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是基于节点来获取其上一层目录的信息,比如说、、节点信息。

这里写图片描述

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);
好的,这里是一个简单的示例代码,演示如何在 Android Studio 中创建自定义广播接收器和发送器: 首先是发送广播的代码: ```java Intent intent = new Intent("com.example.myapp.MY_CUSTOM_ACTION"); intent.putExtra("data", "Hello World!"); sendBroadcast(intent); ``` 这里我们创建了一个 Intent 对象,并设置了 action 为 `"com.example.myapp.MY_CUSTOM_ACTION"`,然后使用 `putExtra()` 方法将数据添加到 Intent 中,最后使用 `sendBroadcast()` 方法发送广播。 接下来是接收广播的代码: ```java public class MyBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals("com.example.myapp.MY_CUSTOM_ACTION")) { String data = intent.getStringExtra("data"); Toast.makeText(context, "Received: " + data, Toast.LENGTH_SHORT).show(); } } } ``` 这里我们创建了一个继承自 BroadcastReceiver 的类 MyBroadcastReceiver,并重写了 `onReceive()` 方法。在方法中,我们将收到的 Intent 的 action 与我们发送广播时设置的 action 进行比较,如果一致,则从 Intent 中获取数据,并显示一个 Toast 提示。 最后,我们需要在 AndroidManifest.xml 文件中注册我们的广播接收器: ```xml <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.myapp"> <application ...> <receiver android:name=".MyBroadcastReceiver"> <intent-filter> <action android:name="com.example.myapp.MY_CUSTOM_ACTION" /> </intent-filter> </receiver> </application> </manifest> ``` 在 `<receiver>` 标签中,我们指定了我们的广播接收器类名为 `.MyBroadcastReceiver`,并在 `<intent-filter>` 标签中设置了我们要接收的 action 为 `"com.example.myapp.MY_CUSTOM_ACTION"`。 这样,我们就完成了自定义广播发送接收代码的编写。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CrazyMo_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值