zoukankan      html  css  js  c++  java
  • Android设置里面默认存储器选项(default write disk)的实现

        原生的Android设置里面没有默认存储器的选项,可是MTK偏偏加上了这个功能,可能MTK认为这个比較实用吧,所以,他们在原生的基础上面做了改动。加上了这个功能。可是高通平台没有这个功能。相对MTK来说。高通比較严谨一点,不会随随便便加上一些功能。可是MTK平台优化了非常多东西(有有点也有缺点),开发人员这可能是非常多山寨手机选择MTK平台的原因吧。

         我给“默认存储器”做了一个简单的定义:一些内置应用的数据存放位置。当然。假设其它应用知道这个接口(不是标准接口。所以仅仅有开发人员本人知道,或者MTK的人),也能够使用该功能。

        之前接到一个在高通平台上的手机里面加上默认存储器的选项,即假设选择本地内存,一些内置应用的数据将存储到本地内存里面,假设选择SD卡存储。则这些应用的数据将会存储到SD卡里面。借鉴MTK平台的实现方法。整理其思路是:通过SystemProperties接口往系统内存里面写入存储路径(set),然后在一些指定应用里面存储数据的时候推断当前默认存储器,使用get方法读取这个属性。为什么使用SystemProperties,由于其设置的值全局都能够使用,即不同应用都能够通过共享内存取出其值,攻克了进程间通信的问题。

        1:我们先在framework层加上一些自己定义的接口文件。我加的位置是 ....../frameworks/base/core/java/android/os/storage/。加入的文件名称StorageManagerEx.java,内容例如以下:

    package android.os.storage;	
    import android.util.Log;	
    import com.android.internal.R;	
    import android.os.SystemProperties;	
    import java.io.File;	
    import android.os.Environment;	
    
    
    public class StorageManagerEx {	
    »       private static final String TAG ="StorageManagerEx";	
    »       private static final String PROP_SD_DEFAULT_PATH = "persist.sys.sd.defaultpath";	
    »       	
    »       private static final String STORAGE_PATH_SD1 ="/storage/sdcard0";	
    »       private static final String STORAGE_PATH_SD2 ="/storage/sdcard1";	
    »       private static final String STORAGE_PATH_SD1_ICS = "/mnt/sdcard";	
    »       private static final String STORAGE_PATH_SD2_ICS = "/mnt/sdcard2";	
    »       	
    »       private static final String STORAGE_PATH_SHARE_SD = "/storage/emulated/0";	
    »       	
    »       /**	
    »        * Return default path for writing.	
    »        * @return default path.	
    »        * @hide	
    »        * @internal	
    »        */	
       public static String getDefaultPath(){
    »          String path = STORAGE_PATH_SD1;	
    »          try {	
    »       »          path = SystemProperties.get(PROP_SD_DEFAULT_PATH);	
    »       »          Log.i(TAG,"default path = "+path);	
    »          } catch (IllegalArgumentException e) {	
    »       »          Log.e(TAG,"IllegalArgumentException when get default path:"+e);	
    »          }	
    »          //Property will be empty when first boot should set to default 	
    »          if(path.equals("")){	
    »       »          Log.i(TAG,"getDefaultPath empty! set to default");	
    »       »          //Here may be some problems.refer to MTK:only share sd and no swap,internal path 
    is 	
    »       »          //"/storage/emulated/0",i don't know "share" and "no swap",so i skip. 	
    »       »          //           if (FeatureOption.MTK_SHARED_SDCARD && !FeatureOption.MTK_2SDCARD_SW
    AP) {»       »       
    »       »          //               setDefaultPath(STORAGE_PATH_SHARE_SD); 	
    »       »          //               path = STORAGE_PATH_SHARE_SD; 	
    »       »          //           } else { 	
    »       »          //               setDefaultPath(STORAGE_PATH_SD1); 	
    »       »          //               path = STORAGE_PATH_SD1; 	
    »       »          //           } 	
    »       »          setDefaultPath(STORAGE_PATH_SD1);	
    »       »          path = STORAGE_PATH_SD1;	
    »          }	
    »          	
    »          //Here we don't care multi user which will be used by google,ignore and go on. 	
    »          	
    »          //MOTA upgrade from ICS to JB,update defaultPath to JB. 	
    »          if(path.equals(STORAGE_PATH_SD1_ICS)){	
    »       »          path = STORAGE_PATH_SD1;	
    »       »          setDefaultPath(path);	
    »          }else if(path.equals(STORAGE_PATH_SD2_ICS)){	
    »       »          path = STORAGE_PATH_SD2;	
    »       »          setDefaultPath(path);	
    »          }	
    »          	
    »          Log.i(TAG,"getDefaultPath path="+path);	
    »          return path;	
       }	
       	
       /**	
        * set default path for Appto storage data	
        * this only can used by settings.	
        * 	
        * @param path	
        * @hide	
        * @internal	
        */	
       public static void setDefaultPath(String path){	
    »          Log.i(TAG,"setDefaultPath path = " + path);	
    »          if (path == null) {	
    »       »          Log.e(TAG,"setDefaultPath error! path = null");	
    »       »          return;	
    »          }	
    »          	
    »          try {	
    »       »          SystemProperties.set(PROP_SD_DEFAULT_PATH,path);	
    »          } catch (IllegalArgumentException e) {	
    »       »          Log.e(TAG,"IllegalArgumentException when setDefaultPath:" + e);	
    »          }	
       }	
       	
       /**	
        * Returns external SD card path.»       /sdcard2	
        * @hide	
        * @internal	
        */	
    //   public static String getExternalStoragePath(){»       //method 1: 	
    //»          String sdCardDir = null; 	
    //       android.os.storage.StorageManager storageManager = 	
    //               (android.os.storage.StorageManager) context 	
    //                       .getSystemService(Context.STORAGE_SERVICE); 	
    //       StorageVolume[] volumes = storageManager.getVolumeList(); 	
    //       for (int i = 0; i < volumes.length; i++) { 	
    //           if (volumes[i].isRemovable() && volumes[i].allowMassStorage()) { 	
    //               sdCardDir = volumes[i].getPath(); 	
    //               break; 	
    //           } 	
    //       } 	
    //       return sdCardDir; 	
    //   } 
       	
     public static String getExternalStoragePath(){»       //method 2: 	
       String sdCardDir = null;	
       String state = Environment.getStorageState(new File(STORAGE_PATH_SD2));	
       	
       if(state.equals(Environment.MEDIA_MOUNTED)){	
    »          sdCardDir = STORAGE_PATH_SD2;	
       }else if(state.equals(Environment.MEDIA_UNMOUNTED)){	
    »          sdCardDir = Environment.MEDIA_UNMOUNTED;	
       }else{	
    »          sdCardDir = STORAGE_PATH_SD2;	
       }	
       return sdCardDir;  	
    }	
       	
       	
       /**	
        * Returns internal storage path.	
        * @return	
        * @hide	
        * @internal	
        */	
       public static String getInternalStoragePath(){	
    »          String sdCardDir = null;	
    »          String state = Environment.getStorageState(new File(STORAGE_PATH_SHARE_SD));	
    »          	
    »          if(state.equals(Environment.MEDIA_MOUNTED)){	
    »       »          sdCardDir = STORAGE_PATH_SD1;	
    »          }else if(state.equals(Environment.MEDIA_UNMOUNTED)){	
    »       »          sdCardDir = Environment.MEDIA_UNMOUNTED;	
    »          }else{	
    »       »          sdCardDir = STORAGE_PATH_SD1;	
    »          }	
    »          return sdCardDir;  	
       }	1
       	
    } 

        定义的主要作用是往系统内存的属性里面加入属性presist.sys.sd.default.我们能够进入adb里面查看和改动一些属性1:adb shell 2:getprop + 键(或不加) tip:我们也能够setprop + 键 +值


         2:在设置里面加入默认存储器的选项:


    在Settings的project里面的.....res/xml/device_info_memory.xml的文件中面加入

    ......<span style="white-space:pre">	</span><PreferenceCategory 	
            android:key="memory_select"	
            android:title="@string/select_memory" />     ......
    然后在PreferenceCategory里面加入RadioButtonPreference  (此处省略)

    在Memroy.java文件中面加入


    private void initDefaultWriteDisk(){	
        »       mDefaultWriteCategory = (PreferenceCategory)findPreference(DEFAULT_WRITE_CATEGORY_KEY);	
            List<RadioButtonPreference> defaultWritePreference = new ArrayList<RadioButtonPreference>();	
            StorageVolume[] volumes = mStorageManager.getVolumeList();	
            List<StorageVolume> storageVolumesEx = initVolumeList(volumes);	
            for (int i = 0; i < storageVolumesEx.size(); i++) {	
            »       StorageVolume volumn = storageVolumesEx.get(i);	
            »       RadioButtonPreference avalibileDisk = new RadioButtonPreference(getActivity());	
            »       String path = volumn.getPath();»       //volumn path 	
            »       android.util.Log.i("haiyong.liu","volumn.path="+path);	
            »       String state = Environment.getStorageState(new File(path));	
            »       	
            »       avalibileDisk.setKey(path);	
            »       avalibileDisk.setTitle(volumn.getDescription(getActivity()));	
            »       avalibileDisk.setPath(path);	
            »       avalibileDisk.setOnPreferenceChangeListener(this);	
            »       defaultWritePreference.add(avalibileDisk);	
            »       android.util.Log.e("haiyong.liu","Environment="+state);	
            »       if(state.equals(Environment.MEDIA_UNMOUNTED)||state.equals(Environment.MEDIA_REMOVED
    )){	
            »       »       	
            »       }else {	
            »       »       mDefaultWriteCategory.addPreference(avalibileDisk);	
            »       »       if(path.equals(StorageManagerEx.getDefaultPath())){	
            »       »       »       avalibileDisk.setChecked(true);	
            »       »       »       mDeafultWritePathPref = avalibileDisk;	
            »       »       }else{	
            »       »       »       avalibileDisk.setChecked(false);	
            »       »       }	
            »       }	
    »       »       }	
        }	
        	
        private List<StorageVolume> initVolumeList(StorageVolume[] volumes){	
        »       List<StorageVolume> storageVolumes = new ArrayList<StorageVolume>();	
        »       /*if(UserManager.supportsMultipleUsers()){»       //return the current user's volumn lis
    t if supported,otherwise ignore.	
        »       »       StorageVolume[] sv = mStorageManager.getVolumeListAsUser();	
        »       »       for (int i = 0; i < sv.length; i++) {	
                    if (!"not_present".equals(mStorageManager.getVolumeState(volumes[i].getPath()))) {	
                        storageVolumes.add(volumes[i]);	
                    }	
                }	
        »       »       return storageVolumes;	
        »       }*/	
        »       	
            for (int i = 0; i < volumes.length; i++) {	
                if (!"not_present".equals(mStorageManager.getVolumeState(volumes[i].getPath()))) {	
                    storageVolumes.add(volumes[i]);	
                }	
            }	
            	
            return storageVolumes;	
        }	
        	
        @Override	
        public boolean onPreferenceChange(Preference preference, Object newValue) {	
    
            if (preference != null && preference instanceof RadioButtonPreference) {	
                if (mDeafultWritePathPref != null) {	
                    mDeafultWritePathPref.setChecked(false);	
                }	
                StorageManagerEx.setDefaultPath(preference.getKey());	
                mDeafultWritePathPref = (RadioButtonPreference) preference;	
                return true;	
            }	
            return false;	
        }

    然后在oncreate方法里面调用
    initDefaultWriteDisk()
    这种方法,这种方法放在Memory.java的onCreate(...)方法里面,另外,StorageManagerEx.setDefaultPath(),这种方法仅仅能够在settings这个apk里面使用,即仅仅有settings这个apk能够写入。

        3:找到相应须要加入该功能的project,我们须要加入的是Camrea2。蓝牙,下载器,录音这几个Apk。找到这几个源代码存储数据的地方,将存储位置改为StorageManagerEx.getDefaultPath()

    tip:SystemProperties写入数据时候须要权限。在Manifests.xml文件加上android:sharedUserId="android.uid.system",在Android.mk中。將LOCAL_CERTIFICATE := XXX改动成LOCAL_CERTIFICATE :=platform。








  • 相关阅读:
    自写 jQuery 大幅弹窗广告插件(不喜勿拍)
    反省:一个失败的产品
    javascript变量:全局?还是局部?这个得注意!
    前端工作常常会用到的一些经验技巧(三)
    Jquery伪选择器学习笔记
    前端工作常常会用到的一些经验技巧(二)
    (总结)工作中常用的js自定义函数——日期时间类
    js 数组引用 发现的问题
    一位资深程序员大牛给予Java初学者的学习路线建议(转)
    正则表达式
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/5258625.html
Copyright © 2011-2022 走看看