Android开发之获取当前展示的activity的包名,类名

在进行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 ComponentName topActivity: 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 component.ComponentName的方法,返回当前组件的包名
getClassName() Return the class name of this component.ComponentName的方法,返回当前组件的类名。
所需权限同时要注意的是,谷歌在API 21之后就收紧了getRunningTasks()的权限,所以想使用该方法还需在manifest里声明权限:

准备工作已经完成,接下来我们来做一个可以获取当前展示在屏幕上的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() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(MainActivity.this,MyService.class);
                startService(intent);
            }
        });

我们将获取当前展示activity包名类名的代码写到service里面
在service的startcommand方法里:

@Override
    public 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);//打印到logcat
            System.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学习之路)