Android設定裡面預設儲存空間選項(default write disk)的實現,androidwrite

來源:互聯網
上載者:User

Android設定裡面預設儲存空間選項(default write disk)的實現,androidwrite

    原生的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_SWAP) {»       »       »       »          //               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 list 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。








聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.