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);                  }               }          }      } 

搞定收工,事实经过验证!

请转载注明出处。

}

0 0
原创粉丝点击