在进行Android开发学习过程中,有时候我们想实现这种功能:
从自己写的小应用里启动其它APP。
这听起来似乎很简单,使用intent的隐式启动就可以了。
Intent intent = new Intent();
intent.setClassName(包名,类名);
startActivity(intent);
似乎三句代码就解决问题,但是问题的关键在与,你怎么知道你要启动的APP的包名,类名。有人说到manifest文件里就能找到。但如果你想启动手机QQ,想启动微信,怎么找?
腾讯官网的开发者平台也没有类似的文档,所以我们只能自己解决。而且幸运的是Android提供了几个类可以解决这个问题。
需要用到的几个类和方法介绍:
ActivityManager:Interact with the overall activities running in the system.它是android.app包下的一个类,用来与当前系统正在运行的所有activity交互。
getRunningTasks(int maxNum)是ActivityManager的一个方法,返回的是当前正在运行的Task列表,传入的参数值表示需要返回的列表的最大值,当我们传一个1进去时,返回的就是当前正在运行的activity栈。
public ComponentNametopActivity: The activity component at the top of the history stack of the task,This is what the user is currently doing. ActivityManger的一个成员变量,表示栈顶activity。
ComponentName:Identifier for a specific application component (Activity, Service, BroadcastReceiver, or ContentProvider) that is available. Two pieces of information, encapsulated here, are required to identify a component: the package (a String) it exists in, and the class (a String) name inside of that package.识别一个具体的可用的组件,(Android四大组件皆可),里面包含了两个信息,包名和类名。
getPackageName()Return the package name of this ponentName的方法,返回当前组件的包名
getClassName()Return the class name of this ponentName的方法,返回当前组件的类名。
所需权限同时要注意的是,谷歌在API 21之后就收紧了getRunningTasks()的权限,所以想使用该方法还需在manifest里声明权限:
<uses-permission android:name="android.permission.GET_TASKS"/>
准备工作已经完成,接下来我们来做一个可以获取当前展示在屏幕上的activity的包名类名的简单APP。
首先新建一个工程。
在manif文件里声明权限
<uses-permission android:name="android.permission.GET_TASKS"/>
在布局文件中添加一个按钮,button:text内容为:开启服务.
在MainActivity里获取到这个按钮并为它添加监听事件。
同时我们在创建一个service组件,我们用这个按钮来启动service。
btnService = (Button) findViewById(R.id.btn_service); btnService.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {Intent intent = new Intent(MainActivity.this,MyService.class);startService(intent);}});
我们将获取当前展示activity包名类名的代码写到service里面
在service的startcommand方法里:
@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {int count = 0;while (count < 100) {//计数,100秒后服务停止ActivityManager manager = (ActivityManager) this.getSystemService(Activity.ACTIVITY_SERVICE);ComponentName cn = manager.getRunningTasks(1).get(0).topActivity;String pName = cn.getPackageName();//获取包名String className = cn.getClassName();//获取类名System.out.println("pName : " + pName);//打印到logcatSystem.out.println("className : " + className);try {Thread.sleep(1000);//每隔一秒获取一次count++;} catch (InterruptedException e) {e.printStackTrace();}}return super.onStartCommand(intent, flags, startId);}
这样,一个简易的工具app就完成了,接下来我们将APP运行到手机上,然后点击按钮开启服务,注意服务只会运行100秒,当然你也可以修改while里的判断值来增长或缩短时间。
开启服务后,我们退出APP,这里服务会在后台运行。这时我们打开想获取的某APP的某activity,比如QQ的登录界面,在该界面上停顿,此时logcat就会每隔一秒输出QQ登录界面的包名和类名。
PS:不过由于安全问题,许多应用设置了权限,应用内部的一些activity不允许被外部APP启动。
以上。
如果觉得《Android开发之获取当前展示的activity的包名 类名》对你有帮助,请点赞、收藏,并留下你的观点哦!