編輯:關於Android編程
原生的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的文件裡面添加
......然後在PreferenceCategory裡面添加RadioButtonPreference (此處省略)......
在Memroy.java文件裡面添加
private void initDefaultWriteDisk(){
» mDefaultWriteCategory = (PreferenceCategory)findPreference(DEFAULT_WRITE_CATEGORY_KEY);
List defaultWritePreference = new ArrayList();
StorageVolume[] volumes = mStorageManager.getVolumeList();
List 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 initVolumeList(StorageVolume[] volumes){
» List storageVolumes = new ArrayList();
» /*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;
} initDefaultWriteDisk()這個方法,這個方法放在Memory.java的onCreate(...)方法裡面,另外,StorageManagerEx.setDefaultPath(),這個方法只可以在settings這個apk裡面使用,即只有settings這個apk可以寫入。
3:找到對應需要添加該功能的工程,我們需要添加的是Camrea2,藍牙,下載器,錄音這幾個Apk,找到這幾個源碼存儲數據的地方,將存儲位置改為StorageManagerEx.getDefaultPath()
Android逆向實例筆記—續力破解三個Android程序
這個首先感謝魚C論壇的cbs大神,我是看了他的視頻。自己再動手破解他給出這三個小程序。真心這樣無私把技術分享給大家的人真的不多。再次感謝他。這裡我就我自己破解的三個小程序
如何快速確定手機型號信息
平時我們使用手機想要了解更多信息或者相關教程的時候,如果想要更快更准確地查找到相關的內容,我們就需要知道它的機型信息以便於查找,鑒於很多手機用戶不知道如何查
Android Developer:Heap Viewer演示
這個演示展示了Heap Viewer工具的基本用法。Heap Viewer實時報告你的應用程序已經分配了什麼類型的對象,多少個,和它們在堆內存中的大小。它的優勢:獲取你的
安卓實戰開發之JNI從小白到偽老白深入了解JNI動態注冊native方法及JNI數據使用
前言或許你知道了jni的簡單調用,其實不算什麼百度谷歌一大把,雖然這些jni絕大多數情況下都不會讓我們安卓工程師來弄,畢竟還是有點難,但是我們還是得打破砂鍋知道為什麼這樣