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的工程里面的.....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:找到对应需要添加该功能的工程,我们需要添加的是Camrea2,蓝牙,下载器,录音这几个Apk,找到这几个源码存储数据的地方,将存储位置改为StorageManagerEx.getDefaultPath()

tip:SystemProperties写入数据时候需要权限。在Manifests.xml文件加上android:sharedUserId="android.uid.system",在Android.mk中,將LOCAL_CERTIFICATE := XXX修改成LOCAL_CERTIFICATE :=platform。
--------------------- 
作者:无心_细语 
来源:CSDN 
原文:https://blog.csdn.net/liu8497/article/details/41961383 
版权声明:本文为博主原创文章,转载请附上博文链接!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值