获取正在前台运行的apk 包名

简介: 获取正在前台运行的apk 包名

1.ActivityManager的getRunningTasks方法


public String getTopActivity(String path) {
        ActivityManager activityManager = (ActivityManager)getContext().getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
        ComponentName runningTopActivity = activityManager.getRunningTasks(1).get(0).topActivity;
        return runningTopActivity.getPackageName();
    }
需要申请权限
<uses-permission android:name="android.permission.GET_TASKS" />

2.通过UsageStatsManager获取前台应用


public String getTopActivity(String path) {
//        ActivityManager activityManager = (ActivityManager)getContext().getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
//        ComponentName runningTopActivity = activityManager.getRunningTasks(1).get(0).topActivity;
        UsageStatsManager mUsageStatsManager = (UsageStatsManager)getContext().getApplicationContext().getSystemService(Context.USAGE_STATS_SERVICE);
        long time = System.currentTimeMillis();
        List<UsageStats> stats ;
        int TWENTYSECOND = 20*60*1000;
        int THIRTYSECOND = 30*60*1000;
//        if (isFirst){
            stats = mUsageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, time - TWENTYSECOND, time);
//        }else {
//            stats = mUsageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, time - THIRTYSECOND, time);
//        }
// Sort the stats by the last time used
        ComponentName runningTopActivity = null;
        if(stats != null) {
            TreeMap<Long,UsageStats> mySortedMap = new TreeMap<>();
            long start=System.currentTimeMillis();
            for (UsageStats usageStats : stats) {
                mySortedMap.put(usageStats.getLastTimeUsed(),usageStats);
            }
            Log.e("TAG",",mySortedMap cost:"+ (System.currentTimeMillis()-start));
            if(mySortedMap != null && !mySortedMap.isEmpty()) {
                return mySortedMap.get(mySortedMap.lastKey()).getPackageName();
            }
        }
        return null;
    }

代码的功能是通过UsageStatsManager 来获取用户使用的程序的列表,然后按照最近使用时间排序,就得到了当前的前台应用,这种方式只能拿到包名,无法精确了Activity了。

使用这种方发之前,首先要引导用户开启使用量功能:

Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);

startActivity(intent);

还要申明权限:

<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />


3、通过辅助服务获取前台应用


辅助服务(AccessibilityService)有很多神奇的妙用,比如辅助点击,比如页面抓取,还有就是获取前台应用。

这里简单介绍一下如何使用辅助服务,首先要在AndroidManifest.xml中声明:

<service
    android:name=".service.AccessibilityMonitorService"
    android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
    >
    <intent-filter>
        <action android:name="android.accessibilityservice.AccessibilityService" />
    </intent-filter>
    <meta-data
        android:name="android.accessibilityservice"
        android:resource="@xml/accessibility" />
</service>

然后在res/xml/文件夹下新建文件accessibility.xml,内容如下:

<?xml version="1.0" encoding="utf-8"?>
<accessibility-service
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:accessibilityEventTypes="typeViewClicked|typeViewLongClicked|typeWindowStateChanged"
    android:accessibilityFeedbackType="feedbackGeneric"
    android:accessibilityFlags="flagRetrieveInteractiveWindows"
    android:canRetrieveWindowContent="true"
    android:canRequestFilterKeyEvents ="true"
    android:notificationTimeout="10"
    android:packageNames="@null"
    android:description="@string/accessibility_des"
    android:settingsActivity="com.pl.recent.MainActivity"
/>

至于其中每一项的内容,还是去看API文档吧,我这里一一解释的话,文章就太长了。关键是typeWindowStateChanged。

新建AccessibilityMonitorService,主要内容如下:

public class AccessibilityMonitorService extends AccessibilityService {
    private CharSequence mWindowClassName;
    private String mCurrentPackage;
    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
        int type=event.getEventType();
        switch (type){
            case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:
                mWindowClassName = event.getClassName();
                mCurrentPackage = event.getPackageName()==null?"":event.getPackageName().toString();                
                break;
            case TYPE_VIEW_CLICKED:
            case TYPE_VIEW_LONG_CLICKED:
                break;
        }
    }
}

就这么简单,就可以获取当前前台应用的包名和Activity名了。

但是需要注意的是,辅助服务在一些手机(小米、魅族、华为等国产手机)上,一旦程序被清理后台,就会被关闭。。。

4种获取前台应用的方法(肯定有你不知道的) - 简书 (jianshu.com)


目录
相关文章
|
安全 Dubbo 算法
APK/ABB 包加固
APK/ABB 包加固
943 0
|
存储 Shell Android开发
【Android 逆向】获取安装在手机中的应用的 APK 包 ( 进入 adb shell | 获取 root 权限 | 进入 /data/app/ 目录 | 拷贝 base.apk 到外置存储 )
【Android 逆向】获取安装在手机中的应用的 APK 包 ( 进入 adb shell | 获取 root 权限 | 进入 /data/app/ 目录 | 拷贝 base.apk 到外置存储 )
531 0
【Android 逆向】获取安装在手机中的应用的 APK 包 ( 进入 adb shell | 获取 root 权限 | 进入 /data/app/ 目录 | 拷贝 base.apk 到外置存储 )
|
资源调度 JavaScript Android开发
webapp打包为Android的apk包的一种方法
webapp打包为Android的apk包的一种方法
|
安全 Android开发 虚拟化
【Android 插件化】使用 PluginKiller 帮助应用开发者规避发布的 APK 安装包被作为插件的风险 ( 验证应用是否运行在插件化引擎中 )
【Android 插件化】使用 PluginKiller 帮助应用开发者规避发布的 APK 安装包被作为插件的风险 ( 验证应用是否运行在插件化引擎中 )
213 0
|
Shell 测试技术 Android开发
Python Python实现批量安装android apk包
Python Python实现批量安装android apk包
386 0
|
Java Android开发
安卓apk包反编译
拿到安卓的apk包如何,如何反编译呢。流程如下
474 0
安卓apk包反编译
|
Java
APK解包修改后,重新打包
APK解包修改后,重新打包
695 0
|
Android开发
【Android 逆向】GDA 逆向工具安装 ( GDA 下载 | GDA 简介 | 运行 GDA 分析 APK 文件 )
【Android 逆向】GDA 逆向工具安装 ( GDA 下载 | GDA 简介 | 运行 GDA 分析 APK 文件 )
1035 0
【Android 逆向】GDA 逆向工具安装 ( GDA 下载 | GDA 简介 | 运行 GDA 分析 APK 文件 )
|
开发工具 Android开发 Python
【Android 逆向】逆向修改游戏应用 ( APK 解析工具 | 解包 -> 分析 -> 重打包 -> 签名 流程 )
【Android 逆向】逆向修改游戏应用 ( APK 解析工具 | 解包 -> 分析 -> 重打包 -> 签名 流程 )
746 0
【Android 逆向】逆向修改游戏应用 ( APK 解析工具 | 解包 -> 分析 -> 重打包 -> 签名 流程 )
|
Android开发
【Android 插件化】Hook 插件化框架 ( 创建插件应用 | 拷贝插件 APK | 初始化插件包 | 测试插件 DEX 字节码 )
【Android 插件化】Hook 插件化框架 ( 创建插件应用 | 拷贝插件 APK | 初始化插件包 | 测试插件 DEX 字节码 )
212 0
【Android 插件化】Hook 插件化框架 ( 创建插件应用 | 拷贝插件 APK | 初始化插件包 | 测试插件 DEX 字节码 )