Android进阶——启动内置APK和动态发送接收自定义广播

引言

最近在工作中恰好遇到一个这样的需求,需要在手机启动时引导界面的时候,提供一个接口启动内置的APK,思考再三最后决定更改Framework利用广播机制去实现,恰好使用了两个知识点,为了记忆和积累,在以后的开发中遇到类似的直接重用这些代码片段,积累到一定程度之后再封装成工具类,以后还会继续收集和积累有用的代码片段。

一、代码动态自主启动内置APK

我们都知道Android系统为我们提供了很多服务管理类,PackageManager主要是管理应用程序包,通过它就可以获取应用程序信息并构建Intent,启动对应的应用。除此之外Android还未我们提供了一些对应的类来管理相关的xml文件,比如说可以通过PackageInfo来获取AndroidManifest.xml文件的信息PackageItemInfo——AndroidManifest.xml文件中所有节点的基类,提供了这些节点的基本信息比如label、icon、 meta-data。但它并不直接使用,而是由子类继承然后调用相应方法;ApplicationInfo继承自 PackageItemInfo用于获取一个特定程序中节点的信息,比如常见的字段:flags字段: **FLAG_SYSTEM 系统应用程序FLAG_EXTERNAL_STORAGE 表示该应用安装在sdcard中ActivityInfo也继承自 PackageItemInfo用于获得应用程序中或者 节点的信息 。我们可以通过它来获取我们设置的任何属性比如:theme 、launchMode、launchmode等,还有ServiceInfo与ActivityInfo类似,只不过是用于获取节点的信息;最后一个ResolveInfo是基于节点来获取其上一层目录的信息,比如说、、节点信息。

Android进阶——启动内置APK和动态发送接收自定义广播_第1张图片

1、PackageManager简介

PackageManager主要用于管理应用程序包,获取程序中所安装的应用程序包的相关信息,而且是一个抽象类,但是我们可以通过getPackageManager()方法来获取PackageManager对象

抽象公共方法(部分) 说明
PackageManager getPackageManager() 获取PackageManager对象
boolean addPermission(PermissionInfo info) 动态添加权限
int checkPermission(String permName, String pkgName) 检查是否具有特定的权限
Drawable getActivityIcon(Intent intent) 取得与一个Intent关联的图标
List getAllPermissionGroups(int flags) 获取所有的权限列表
ApplicationInfo getApplicationInfo(String packageName, int flags) 获取application的信息
List getInstalledPackages(int flags) 获取已安装的app包名列表
PackageInfo getPackageInfo(String packageName, int flags) 获取指定包名的信息
List queryIntentActivities(Intent intent, int flags) 返回所有可以被指定意图来执行的活动

2、代码实现

包名和mainActivity未知时:

    /* ** @param packageName 将要去启动第三方app的package */
    private void runAppByPackage(@NonNull String packageName) {
        PackageInfo packageInfo = null;
        PackageManager packageManager=getPackageManager();//获取PackageManager对象
        try {
            packageInfo = packageManager.getPackageInfo(packageName, 0);//通过包名获取PackInfo
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }

        Intent resolveIntent = new Intent(Intent.ACTION_MAIN, null);
        resolveIntent.addCategory(Intent.CATEGORY_LAUNCHER);
        resolveIntent.setPackage(packageInfo.packageName);

        List<ResolveInfo> apps = packageManager.queryIntentActivities(resolveIntent, 0);

        ResolveInfo resolveInfo = apps.iterator().next();
        if (resolveInfo != null ) {
            String pkgeName = resolveInfo.activityInfo.packageName;
            String className = resolveInfo.activityInfo.name;

            Intent intent = new Intent(Intent.ACTION_MAIN);
            intent.addCategory(Intent.CATEGORY_LAUNCHER);

            ComponentName cn = new ComponentName(pkgeName, className);

            intent.setComponent(cn);
            startActivity(intent);
        }
    }

包名和mainActivity已知时:

private void startLenovePlan(){
       ComponentName componetName = new ComponentName(  
             "com.lenovo.ue.service",
"com.lenovo.ue.service.LenovoUEServiceActivity");  
         try {  
             Intent intent = new Intent();  
             intent.setComponent(componetName);  
             startActivity(intent);  
         } catch (Exception e) {  

         }  
 }

二、动态发送和接收广播

1、发送自定义广播

Intent intent = new Intent("android.intent.action.CART_BROADCAST_SILENT");
    mContext.sendBroadcast(intent);

2、定义广播接收器并处理

private static String BROADCAST_FILTER="android.intent.action.CART_BROADCAST_SILENT";
    private AudioManager mAudioManager=(AudioManager) (getActivity().getApplicationContext().getSystemService(Context.AUDIO_SERVICE));
    private BroadcastReceiver zenmodeReceiver = new BroadcastReceiver() {
        //定义接收广播接收器
        @Override
        public void onReceive(Context contex, Intent intent) {
            String action = intent.getAction();
            PreferenceScreen sound = (PreferenceScreen) findPreference("hq_ringtone_volume_settings");
            if (action.equals(BROADCAST_FILTER)) {
                int ringMode = mAudioManager.getRingerMode();
                if (ringMode == AudioManager.RINGER_MODE_SILENT) {
                    if (findPreference(KEY_RING_VOLUME) != null && findPreference(KEY_NOTIFICATION_VOLUME) != null) {
                        ((VolumeSeekBarPreference) findPreference(KEY_RING_VOLUME)).setSeekBarStatus(false, 0);
                    }
                } else {
                    if (findPreference(KEY_RING_VOLUME) != null && findPreference(KEY_NOTIFICATION_VOLUME) != null) {
                        findPreference(KEY_RING_VOLUME).setEnabled(false);
                    }
                }
            }
        }
    };

3、注册广播接收器

@Override
 public void onCreate(Bundle icicle) {
     super.onCreate(icicle);
     addPreferencesFromResource(R.xml.hq_volume_fragment_prefs);
     initVolume(getPreferenceScreen());
     IntentFilter intent = new IntentFilter();
     intent.addAction(BROADCAST_FILTER);
     getActivity().getApplicationContext().registerReceiver(zenmodeReceiver,intent);//注册广播接收器
 }

4、使用完毕之后记得释放掉广播,否则会有OOM的隐患

unregisterReceiver(receiver);

你可能感兴趣的:(Broadcast,动态广播,PackageInf,PackageMgr,启动内置APK)