原生的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。

Android设置里面默认存储器选项(default write disk)的实现的更多相关文章

  1. android设置系统默认开机时间

    1.设置RTC时间,该时间是如果RCT时钟断电以后使用的默认时间 Android L之前: \alps\mediatek\custom\[project]\preloader\ inc\cust_rt ...

  2. Android 设置界面的圆角选项

    请先看一个图: 像这种界面的设计,其实是这样的:整体为一个LinearLayout,一个一个排下去,每一个点击项都是一个RelativeLayout(要为其设置clickable为true),分为左右 ...

  3. 【SecureCRT配置】修改默认卷屏行数当做一个操作,屏幕输出有上百行,当需要将屏幕回翻时,这个设置会有很大帮助,默认为500行,可以改为10000行,不用担心找不到了。 选项 => 全局选项 => Default Session => Edit Default Settings => Terminal => Emulation => Scrollback 修改为32000。

    SecureCRT配置屏幕内容输出到log文件 SecureCRT看不到前几分钟操作的内容,或者想把通过vi命令查看的日志输出到log文件(在懒得下载日志文件的情况下),所以接下来就这样操作: 文件保 ...

  4. MTK Android 设置-选择日期格式 [管理和组织首选项,ListPreference,CheckBoxPreference,EditTextPreference,RingtonePreference]

    ###android.preference.ListPreference的一些特性 android:key  选项的名称或键 android:title  选项的标题 android:summary  ...

  5. I.MX6 android 设置 默认 动态桌面

    /************************************************************************ * I.MX6 android 设置 默认 动态桌面 ...

  6. Mysql 数据库date, datetime类型设置0000-00-00默认值(default)报错问题

    Mysql 数据库date, datetime类型设置0000-00-00默认值报错问题 现象:MySQL5.7版本之后,date, datetime类型设置默认值"0000-00-00&q ...

  7. Android 9.0 默认输入法的设置流程分析

    Android 输入法设置文章 Android 9.0 默认输入法的设置流程分析 Android 9.0 添加预置第三方输入法/设置默认输入法(软键盘) 前言 在上一篇文章  Android 9.0 ...

  8. Android eclipse 运行项目设置程序默认安装到SD卡

    Android eclipse 运行项目设置程序默认安装到SD卡  1.在Android手机启用USB调试功能 2.在Windows系统中打开命令提示符(开始菜单,选择运行,输入cmd回车即可),使用 ...

  9. SQL Server 默认跟踪(Default Trace)

    一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 基础知识(Rudimentary Knowledge) 查看默认跟踪信息(Default Tr ...

随机推荐

  1. 如何删除Windows服务

    删除的办法有两个: 办法一: 用sc.exe这个Windows命令         开始——运行——cmd.exe,然后输入sc就可以看到了.使用办法很简单:         sc delete &q ...

  2. 【转】深入理解Java内存模型(五)——锁

    锁的释放-获取建立的happens before 关系 锁是java并发编程中最重要的同步机制.锁除了让临界区互斥执行外,还可以让释放锁的线程向获取同一个锁的线程发送消息. 下面是锁释放-获取的示例代 ...

  3. 写一个MyORM--利用反射的方法

    本文的目的是为了更加深刻的理解反射. ORM:Object Relational Mapping对象关系映射,是解决了面向对象语言和关系型数据库不匹配的问题. ORM是一种思想,实现这种思想的技术有很 ...

  4. jquery mobile 按钮部件(包含图标的使用)

    参考网址:http://api.jquerymobile.com/1.3/button/ 注:按钮的三种写法 <a href="#" class="ui-btn u ...

  5. IIS 中asp.net的一些配置

    安装了IIS之后, 添加了虚拟目录然后运行页面, 出现了一点儿错误, 好像是不认识aspx文件, 把aspx文件当成是xml文件处理. 无法显示 XML 页. 使用 XSL 样式表无法查看 XML 输 ...

  6. Android Init进程命令的执行和服务的启动

    这里开始分析init进程中配置文件的解析,在配置文件中的命令的执行和服务的启动. 首先init是一个可执行文件,它的对应的Makfile是init/Android.mk. Android.mk定义了i ...

  7. win64安装及配置apache+php+mysql

    Windows是64位Win7,所以Apache.PHP和Mysql都选用的64位版本(最好是统一64位). Apache:httpd-2.4.7-win64.zip PHP:PHP-5.4.6-Wi ...

  8. Mysql权限控制 - 允许用户远程连接(转载)

    Mysql为了安全性,在默认情况下用户只允许在本地登录,可是在有此情况下,还是需要使用用户进行远程连接,因此为了使其可以远程需要进行如下操作: 一.允许root用户在任何地方进行远程登录,并具有所有库 ...

  9. 简单运用 activity 的 button 点击事件

    今天我们要讲的主要是四大组件之一Activity Activity 在英文中是活动的意思.活动就是我们与用户进行交互的一个场所. activity 整个的活动流程是什么呢?我们用一个图来看下 当然今天 ...

  10. build.prop各种优化代码

    1.首先要准备RE管理器以及root权限.2.在根目录里的system文件夹找到build.prop文件.3.打开build.prop文件后找到代码ro.sf.lcd_density=240(这里的2 ...