android源码使用U盘激活Launcher
来源:互联网 发布:java math.ceil 编辑:程序博客网 时间:2024/05/29 09:46
因为广电发文,各种限制android系统的自由度,种种缘由,项目需要做个“掩人耳目”的动作。那就是在android系统平台中需要预制两个Launcher,一个"干净"的,没有任何定制特色的原生launcher,另一个则是“多元”的定制的launcher。在出厂时,系统为干净launcher,出厂后,用户自己可以采用U盘激活“多元”定制Launcher。
根据思路,目前要实现的模块是:
1.U盘中存放一个激活KEY。
2.出厂时,开机Launcher中本身需预装两个Launcher,并且按home键,不可以弹出选择启动项框。出厂时使用干净Launcher。
3.当插入U盘后检测到有激活KEY值时,开机启动定制Launcher,并设置为默认值。
第一步,U盘放激活KEY,这个当然是越简单越好,所以直接定一个文件夹,文件夹中放一个txt格式的文件,里面写上字串,自编。目前我建的路径是:“\LauncherKey\key.txt”文本里写的是:“123456789”。(字串和路径一定要考虑好,代码中是直接做完全匹配验证的)预先准备好测试的U盘。
第二步, 准备两个可以正常运行的Launcher,注意加上Launcher的
<intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.MONKEY" /> <category android:name="android.intent.category.FIRSTHOME" /><!--这个是自定义的Launcher,很多资料都有讲解怎么设置自定义Launcher--> <category android:name="android.intent.category.DEFAULT" /> </intent-filter>
第三步,在检测U盘的应用中,例如,FileBrower.apk源码中,加上:
package com.fb.FileBrower;import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.UnsupportedEncodingException;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.content.SharedPreferences;import android.os.SystemClock;import android.util.Log;import android.widget.Toast;/** * Created by liuwenchang on 14-2-13. */public class MountReceiver extends BroadcastReceiver { private static final String TAG = "MountReceiver"; private static final String ACTION_BOOT_COMPLETED = "android.intent.action.BOOT_COMPLETED"; private static final String ACTION_MEDIA_MOUNTED = "android.intent.action.MEDIA_MOUNTED"; private static boolean life = false; private Context mContext; private SharedPreferences sharedPreferences; private SharedPreferences.Editor editor; @Override public void onReceive(Context context, Intent intent) { mContext = context; String action = intent.getAction().toString(); if ( action == null ) { return; } Log.d(TAG, "==== onReceive() action: " + action); if ((!intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) || ((!intent.getAction().equals("android.intent.action.MEDIA_MOUNTED")) || (intent.getDataString().contains("/mnt/sdcard")))) ; if ( !isAlive() || (SystemClock.uptimeMillis() <= 35000L) ) { Intent localIntent; String pathData = intent.getDataString(); if ( pathData == null ) { Log.d(TAG, "==== pathData is empty!!"); return; } if ( pathData.contains("/mnt/flash") || pathData.contains("/storage/emulated")) { return; } String path = pathData.substring("file://".length()); if ( path == null ) { return; } //add by yangqiuling.begin. String keyPath = path+"/LauncherKey/key.txt"; String targetPath = "/sdcard/LauncherKey/"; File key = new File(keyPath); if(key.exists()){ //store key.txt to local storage ,post tip "reboot machine to use new Launcher".add by yangqiuling. Log.d(TAG, "======================= Get Launcher Key! start new Launcher!======================= "); storeLauncherKey(keyPath,targetPath); } //add by yangqiuling. end. localIntent = new Intent(Intent.ACTION_RUN); localIntent.setClass(context, ScanDialogActivity.class); localIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); localIntent.putExtra("path", path); Log.d(TAG, "get MEDIA_MOUNTED !!! "); context.startActivity(localIntent); } } /** * @function: isAlive() * @description: 判断文件管理器是否打开 * @auth: liuwch * @date: 2014-02-17 * */ public static boolean isAlive() { return life; } /** * @function: setAlive() * @description: 供文件管理器其他Activity调用并设置 * @auth: liuwch * @date: 2014-02-17 * */ public static void setAlive(boolean b) { life = b; } private void storeLauncherKey(String fromFile,String toFile) {File f = null;f = new File(fromFile);// 这是对应文件名InputStream in = null;try {in = new BufferedInputStream(new FileInputStream(f));} catch (FileNotFoundException e3) {// TODO Auto-generated catch blocke3.printStackTrace();}BufferedReader br = null;try {br = new BufferedReader(new InputStreamReader(in, "utf8"));//default:"gb2312"} catch (UnsupportedEncodingException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}String tmp;try {while ((tmp = br.readLine()) != null) {// 在这对tmp操作if(tmp.equals("123456789")){storeKey();Toast.makeText(mContext,"激活新桌面成功,重启生效!",80000).show();}}br.close();in.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}private void storeKey(){sharedPreferences = mContext.getSharedPreferences("LauncherKey",mContext.MODE_WORLD_READABLE); editor = sharedPreferences.edit(); editor.putBoolean("key", true); // 一定要提交 editor.commit(); }}
此处是检测U盘内的KEY值,然后保存到激活状态数据(开始我是使用的File文件方法,保存在内置SD卡中,后来发现,系统framework不可以直接访问SD卡,这是android源码中做的处理,为了防止数据损坏而导致系统应用不可使用。所以后来采用的是SharedPreferences保存数据,权限为全局可读。)
第三步,参考博客http://blog.csdn.net/jia4525036/article/details/18036765中设置默认launcher的方法。我在ActivityManagerService.java (frameworks\base\services\java\com\android\server\am)638872 2014-7-8
boolean startHomeActivityLocked(int userId) { ... setDefaultLauncher(); ...}
中是这样加的一个判断:
//set default launcher is ott_launcher.when exist USB-key . add by yangqiuling. try { // 获取其他应用程序的Context otherContext = mContext.createPackageContext("com.fb.FileBrower", mContext.CONTEXT_IGNORE_SECURITY); Slog.d(TAG, "===YQL========= otherContext =" +otherContext); } catch (NameNotFoundException e) { e.printStackTrace(); } // 获取其他应用程序的SharedPreferences SharedPreferences preferences = otherContext .getSharedPreferences("LauncherKey", mContext.MODE_WORLD_READABLE); Slog.d(TAG, "===YQL========= preferences =" +preferences); boolean key = preferences.getBoolean("key", false); Slog.d(TAG, "===YQL========= key =" +key); if(key){ Slog.d(TAG, "===YQL========= Launcher Key is exist ============" ); setDefaultLauncher(true); }else{ Slog.d(TAG, "===YQL=========Use amlogic Launcher =============== " ); setDefaultLauncher(false); }下面这个设置注意,我没有和上述参考的博文一样,只执行开机第一次,我这个是每次必执行。因为我得保证出厂时的launcher随时准备待激活,激活后能重启生效。关键语句是if(true).
/* *add by yangqiuling. */ private void setDefaultLauncher(boolean isKey) { // get default component String packageName =null; String className= null; if(isKey){ packageName = "com.ott_pro.launcher";//默认launcher包名 className = "com.ott_pro.launcher.MainActivity";////默认launcher入口 }else{ packageName = "com.amlogic.mediaboxlauncher";//默认launcher包名 className = "com.amlogic.mediaboxlauncher.Launcher";////默认launcher入口 } Slog.i(TAG, "=========defautl packageName = " + packageName + ", default className = " + className); if ((packageName != null && packageName.trim().length() > 1) && (className != null && className.trim().length() > 0)) {if(true){ IPackageManager pm = ActivityThread.getPackageManager(); //清除当前默认launcher ArrayList<IntentFilter> intentList = new ArrayList<IntentFilter>(); ArrayList<ComponentName> cnList = new ArrayList<ComponentName>(); mContext.getPackageManager().getPreferredActivities(intentList, cnList, null); IntentFilter dhIF; for(int i = 0; i < cnList.size(); i++) { dhIF = intentList.get(i); if(dhIF.hasAction(Intent.ACTION_MAIN) && dhIF.hasCategory(Intent.CATEGORY_HOME)) { mContext.getPackageManager().clearPackagePreferredActivities(cnList.get(i).getPackageName()); } } //获取所有launcher activity Intent intent = new Intent(Intent.ACTION_MAIN); intent.addCategory(Intent.CATEGORY_HOME); List<ResolveInfo> list = new ArrayList<ResolveInfo>(); try { list = pm.queryIntentActivities(intent, intent.resolveTypeIfNeeded(mContext.getContentResolver()), PackageManager.MATCH_DEFAULT_ONLY,UserHandle.getCallingUserId()); }catch (RemoteException e) { throw new RuntimeException("Package manager has died", e); } // get all components and the best match IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_MAIN); filter.addCategory(Intent.CATEGORY_HOME); filter.addCategory(Intent.CATEGORY_DEFAULT); final int N = list.size(); Slog.d(TAG, "===YQL=========N = " + N); ComponentName[] set = new ComponentName[N]; int bestMatch = 0; for (int i = 0; i < N; i++) { ResolveInfo r = list.get(i); set[i] = new ComponentName(r.activityInfo.packageName, r.activityInfo.name); Slog.d(TAG, "r.activityInfo.packageName============YQL== = " + r.activityInfo.packageName); Slog.d(TAG, "r.activityInfo.name==============YQL== = " + r.activityInfo.name); if (r.match > bestMatch) bestMatch = r.match; } //设置默认launcher ComponentName launcher = new ComponentName(packageName, className); try { pm.addPreferredActivity(filter, bestMatch, set, launcher,UserHandle.getCallingUserId()); } catch (RemoteException e) { throw new RuntimeException("Package manager has died", e); } } } }
搞定收工,事实经过验证!
请转载注明出处。
}
- android源码使用U盘激活Launcher
- 使用U3D 实现 Android Launcher(提供源码)
- android launcher源码分析
- android launcher源码分析 .
- android launcher源码分析
- android launcher源码分析
- android launcher源码分析
- Android launcher -- 调试运行launcher源码 1
- Android launcher -- 调试运行launcher源码 2
- Android launcher -- launcher源码修改 1
- Android launcher -- launcher源码修改 2
- Android Launcher源码分析-网址
- Android Launcher 之源码下载
- Android Launcher研究一(编译Android4.0 launcher 源码 上)
- Android Launcher研究二(编译Android4.0 launcher 源码 下)
- 【Launcher】获取最新Launcher源码,并且导入到Android Studio
- android源码 launcher之android:clearTaskOnLaunch属性
- 使用Eclipse调试Android Launcher
- 士兵杀敌(二)
- JVM(java 虚拟机)内存设置
- LeetCode OJ算法题(三):Longest Substring Without Repeating Characters
- 1014. 福尔摩斯的约会 (20)
- NYOJ 网络的可靠性(换个思路想超简单的一道题)
- android源码使用U盘激活Launcher
- android OTA 升级包含增量升级
- android打包混淆-proguard配置详解
- android ueventd 本地native部分源码分析
- OFBiz entity engine 关于数据库自增序列生成算法的源码解读
- float (**def)[10]这个是什么?
- Android中通过xml资源文件定义数组
- 黑马程序员-点语法,成员变量作用域,@property,@synthsize和 id
- 两个Fragment之间的跳转,和数据的传递