android开发关于和使用本机内存,内置存储卡和外置存储卡大揭秘

2021年7月25日 33点热度 0条评论 来源: fth826595345


android开发关于和使用本机内存,内置存储卡和外置存储卡


---------------------------------------------------------------------------------------------------------------------------------------------------------------------------

关于android存储器简介:


                 android开发常常需要涉及数据缓存,这就需要我们了解手机当前使用的内存状况,是否存在外置存储卡,如果有怎么办,没有是否使用内置存储卡。



首先手机本机存储器,有Rom,Ram。


   Rom  :在android中Rom相当于系统盘,当C盘用 ,很多时候要使用需要获取root权限。

              一般可以分为机身内存和内置存储(三星的多是叫:USB存储器);

             机身内存包括system、data和cache等分区目录,软件默认都是安装机身内存或者内置存储卡里的 。

            data(就是手机储存总量)+system(手机系统占用)

           

                具体看是什么手机;


   Ram:在相当于电脑的运行内存,运存  。不多做解释,就是随机运行时内存,断电数据全部消失。


        外置存储器有:手机存储器 (TF卡), 相当于D,E ,F 等硬盘。



---------------------------------------------------------------------------------------------------------------------------------------------------------------------------




android开发中读取手机存储器和外置存储器。

Android读取手机内存之机身内存

这个我反复试验过,可以弄入以及读取数据到data目录下,但是需要获取root权限(这里是指使用的目录地址非当前应用在data中的目录地址),这个真有点纠结,难道要使用**软件的人都去root下?嘿嘿,所以这里不推荐,这里就不粘贴代码了 ,要使用手机内存只能使用当前应用对应在data目录的地址了。下面是一个下载图片到手机内存的方法:(当前应用在data下对应的目录)

    

 // 网络图片先下载到本地cache目录保存,以imagUrl的图片文件名保存。如果有同名文件在cache目录就从本地加载
		public static Drawable loadImageFromUrl(Context context, String imageUrl) {
			Drawable drawable = null;  
	        if(imageUrl == null )  
	            return null;  
	        String imagePath = "";  
	        String   fileName   = "";  
	              
	        // 获取url中图片的文件名与后缀  
	        if(imageUrl!=null&&imageUrl.length()!=0){   
	            fileName  = imageUrl.substring(imageUrl.lastIndexOf("/")+1);  
	        }  
	          
	        // 图片在手机本地的存放路径,注意:fileName为空的情况  
	        imagePath = context.getCacheDir() + "/" + fileName;  
	        Log.i(TAG,"context.getCacheDi = " + context.getCacheDir());  
	        Log.i(TAG,"imagePath = " + imagePath);  
	        File file = new File(imagePath);// 保存文件       同:    File file = new File(context.getCacheDir(),fileName);  
	        Log.i(TAG,"file.toString()=" + file.toString());  
	        if(!file.exists()&&!file.isDirectory())  
	        {  
	            try {  
	                // 可以在这里通过文件名来判断,是否本地有此图片  
	                  
	                FileOutputStream   fos=new   FileOutputStream( file );  
	                InputStream is = new URL(imageUrl).openStream();  
	                int   data = is.read();   
	                while(data!=-1){   
	                        fos.write(data);   
	                        data=is.read();;   
	                }   
	                fos.close();  
	                is.close();  
//	              drawable = Drawable.createFromStream(  
//	                      new URL(imageUrl).openStream(), file.toString() ); // (InputStream) new URL(imageUrl).getContent();  
	                drawable = Drawable.createFromPath(file.toString());  
//	                Log.i(TAG, "file.exists()不文件存在,网上下载:" + drawable.toString());  
	            } catch (IOException e) {  
	                Log.e(TAG, e.toString() + "图片下载及保存时出现异常!");  
	            }  
	        }else  
	        {  
	        	try {
					FileInputStream filein=new FileInputStream(file);
					drawable=Drawable.createFromStream(filein, "src");
				} catch (FileNotFoundException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
                 //上面的方法同下;
                //drawable = Drawable.createFromPath(file.toString());  
//	            Log.i("test", "file.exists()文件存在,本地获取");  
	        } 
	        return drawable ;
		}


Android读取手机内存内置存储器实例


下面给出一个小例子来说明如何Android读取手机内存里的文件,这在Android开发中是比较重要的一部分,如何要是掌握不好的话,我们就没法把数据库里保存的数据给读出来,也就是说我们我们每一次玩游戏的时候,我们的数据库都是最原始的数据,这样就会给我们带来很多的麻烦。如果出现这样的事情,那么你的应用就是非常烂的,代码如下:



    
    public static InputStream readInternalFileInputStream(Context context,String fileName){    
      
      
      
    /**   
    * 读取手机内存文件   
    *   
    */    
      
    try{    
    FileInputStream fis = context.openFileInput(fileName);    
      
    return fis;    
    }catch(Exception e){    
    return null;    
    }    
      
    }    
    public static String readInternalFile(Context context,String fileName){    
      
      
    /**   
    * 读取手机内存文件   
    *   
    */    
      
    try{    
    byte[] buffer = new byte[512];    
    int read =0;    
    StringBuffer stringbuffer = new StringBuffer();    
    FileInputStream fis = context.openFileInput(fileName);    
      
      
    do{    
    read = fis.read(buffer);    
    if(read>0)    
    stringbuffer.append(new String(buffer, 0, read, "utf-8"));    
      
    }while(read!=-1);    
      
      
    fis.close();    
    return stringbuffer.toString();    
      
      
    }catch(Exception e){    
    return null;    
    }    
      
    }   

外置内存

android 读取sd卡中的图片

一 读取sd卡中的图片
     1 获取读取sd的权限
        在AndroidMainfest.xml文件中添加

  

         <!-- 在SDCard中创建与删除文件权限 -->
 <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" ></uses-permission>
 <!-- 往SDCard写入数据权限 -->
 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" ></uses-permission>
 <uses-permission android:name="android.permission.RESTART_PACKAGES" ></uses-permission>

    注意:在<application...></application>前添加

    2 找到sd卡的目录(以真机的情况说明)

 

 /**

      *图片文件路径

 *打印Environment.getExternalStorageDirectory()得到:"/mnt/sdcard",即找到了sd卡的根目录

      */

 public String filePath=Environment.getExternalStorageDirectory()+"/client/tile/1_0_0.jpg";

   3 根据路径获取图片    

     File mfile=new File(path);
     if (mfile.exists()) {//若该文件存在
     Bitmap bm = BitmapFactory.decodeFile(path);
     return bm;
     }

二 注意事项

    在读取sd卡中图片的过程中的一些可用判断

     1 Environment.getExternalStorageState()获取路径是否成功

       /*如获取成功,返回值为MEDIA_MOUNTED*/

   if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
    {

         String filePath=Environment.getExternalStorageDirectory().getPath();
    }

   2 获取sd卡的权限成功

     /*fileName=Environment.getExternalStorageDirectory()+"/client" 是个文件夹目录*/

     File f = new File(fileName);
     //可读
     if(f.canRead())
     Log.v("EagleTag","very bad");
     //可写
     if(f.canWrite())
          Log.v("EagleTag","very good");

--------------------------------------------------------------------------------------------------------------


android的data和system以及cache系统目录讲解

 
 
 
/system 存放的是rom的信息;
 
/system/app 存放rom本身附带的软件即系统软件;
 
/system/data 存放/system/app 中核心系统软件的数据文件信息。
 
 /data 存放的是用户的软件信息(非自带rom安装的软件);
 
/data/app 存放用户安装的软件;
 
/data/data 存放所有软件(包括/system/app 和 /data/app 和 /mnt/asec中装的软件)的一些lib和xml文件等数据信息;
 
/data/dalvik-cache 存放程序的缓存文件,这里的文件都是可以删除的。
 


 
/sdcard和/mnt/sdcard一样吗?/mnt/asce是干嘛用的?
 
我来谈谈/mnt/asce目录
1、android升级到2.2以上,出现了这个目录,这个目录是干什么的呢?
2、2.2以上,出现了新的功能,应用可以安装的sd卡上,哪到底安装在哪儿呢?我找遍了整个卡结果发现了所有这些应用安装在.android 的asecure目录下,要把卡放到读卡器上去看才知道。
3、那是如何与系统发生关系的,学过unix的人都知道,mnt是在/下的一个目录,sd卡是通过mount挂接上去的,/mnt叫挂接点,系统就能通过挂接点/mnt访问sd卡了
4、在/mnt下有三个目录如下:asec、secure、sdcard 其中asec就是我们安装在卡上的应用、secure是用于sd卡应用程序安装路径加密的吧自己猜想的、sdcard就是卡上的其他内容。
 
 
/mnt/asce实际上对应的真正物理目录是/mnt/sdcard/.android_secure(记住android_secure前有个点,这是个隐藏目录)
 
 
我们回过来看/sdcard和/mnt/sdcard就容易理解:
 
/sdcard 目录,这是一个软链接(相当于windows的文件夹的快捷方式),链接到/mnt/sdcard 目录,即这个目录的内容就是sdcard的内容。
 
 
   因此,用户程序安装到到sd卡上后,其内容可能分散到:/mnt/asec , /mnt/secure , /data/data 。
 
    要实现app2sd,目前比较流行有两种方案,分别是app2ext 和 data2ext,下面分别介绍下这2种方案。
 
    app2ext的原理是,删除data区中的app文件夹,然后在sd卡的ext分区上创建一个app文件,并通过软链接映射到data区。这样系统会以为,app这个软链接是一个真实的文件夹,会把程序都安装在里面,但实际上,这些程序都安装到卡上了。但由于操作系统并不知道,所以这种情况下,我们依然看到系统显示这个程序是安装在“内置空间”的。
    data2ext则更彻底,它不是用软链接,而是直接用“挂载”功能,Linux下所有的存储设备都必须挂载成一个文件夹才能进行文件操作(如sd卡就挂载在/mnt/sdcard目录下面)。data文件夹本来是对应手机内部Flash中的一个分区(为了保持术语的准确,这里要把内部Flash和内存相区别,内部Flash是ROM,内存是RAM)。而data2ext则是修改了挂载对应关系,使data文件夹挂载的不是内置Flash,而是sd卡的整个ext分区。这样,不仅是app,连存储程序设置的data和缓存dalvik-cache都会存储到sd卡中。
 
    可以看到,dalvik-cache和data这两个文件夹的位置,是这两种方式的一个重大区别。其中dalvik-cache是虚拟机预编译缓存,data(不同于/data,这个是/data/data)是存储程序数据的地方,例如游戏的存档记录,软件的配置信息等。这样有什么区别,区别在于假如你重刷了ROM,app2ext的话,所有的程序都可以保留,但是这些程序的配置信息和游戏的存档都会丢失。而data2ext则可以连同配置和存档都保留,但是dalvik-cache也是一个容易积累垃圾的地方,这些垃圾也会一同保留。
 
 
    data2ext由于是把整个data分区都放在sd卡上,因此,我们刷ROM需要WIPE的时候,这个data分区的内容就可能不会被wipe,这可以保存用户的个人资料,但是也可能造成系统莫名其妙的故障。
 
 


原文:http://www.2cto.com/kf/201212/178288.html


---------------------------------------------------------------------------------------------------------------------------------------------------------------------------

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Android 4.0中关于内外置存储卡读写权限问题

在2.x的版本中,在manifest中配置的权限android.permission.WRITE_EXTERNAL_STORAGE确实是用来使得sd卡获得写的权限。而在4.0开发的源码当中,由于有了内外置sd卡的区,android.permission.WRITE_EXTERNAL_STORAGE的权限用来设置了内置sd卡的写权限,如果在manifest中只是配置了这个权限,那个应用只能在内置sd卡中进行写操作,还是无法在外置sd卡中进行写操作。

需要写外置sd卡的话,需要配置另一个权限android.permission.WRITE_MEDIA_STORAGE,这样就可以在外置sd卡中进行写入操作了。

这两个权限都被定义在android源码目录\frameworks\base\data\etc\platform.xml中:

 

使用到的类主要是framework/base/core/java/android/os/storage/StorageVolume.java及相同目录下的StorageManager.java文件。

StorageManager类可以获得所有的存储媒体列表,及StorageVolume类型的数组,从而可以获得对应存储是否可读写一类的信息。

问题在于 android 4.0的 SDK包中没有增加这个接口
解决的办法 一种是依赖 厂家将这2个权限默认为一个 也就是外部存储SD卡的android.permission.WRITE_EXTERNAL_STORAGE 和android.permission.WRITE_MEDIA_STORAGE等同 —— 这个是目前比较好的做法

第二种是: reflection 这个我具体没有弄过 待验证

第三种是 将你的源代码在 android的source code下编译 ; 或者得到厂家定制的android.jar包。


以上部分可参照原文,地址http://blog.sina.com.cn/s/blog_5da93c8f0101fgy9.html



希望可以帮助遇到相同问题的童鞋。

转载请注明出处:http://blog.csdn.net/fth826595345/article/details/8823392#t8

  

待续.......

    原文作者:fth826595345
    原文地址: https://blog.csdn.net/fth826595345/article/details/8823392
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系管理员进行删除。