Ionic开发Android应用:如何检测最近运行的前台应用?
检测Android前台运行应用的方法(Ionic/Cordova)
一、使用现成Cordova插件
目前有几个成熟插件可以实现获取前台应用包名的需求:
- cordova-plugin-foreground-app-detector:专门用于检测Android前台运行应用,调用API即可返回当前前台应用的包名。
安装命令:
Ionic Angular使用示例:ionic cordova plugin add cordova-plugin-foreground-app-detector npm install @ionic-native/foreground-app-detectorimport { ForegroundAppDetector } from '@ionic-native/foreground-app-detector/ngx'; constructor(private foregroundAppDetector: ForegroundAppDetector) { } async getForegroundApp() { try { const packageName = await this.foregroundAppDetector.getForegroundApp(); console.log('当前前台应用包名:', packageName); // 这里可添加包名后续处理逻辑 } catch (error) { console.error('获取前台应用失败:', error); } } - cordova-plugin-recent-tasks:可获取最近运行的应用列表,列表首项即为当前前台/最近使用的应用,能直接拿到包名。
安装命令:
使用示例:ionic cordova plugin add cordova-plugin-recent-tasks npm install @ionic-native/recent-tasksimport { RecentTasks } from '@ionic-native/recent-tasks/ngx'; constructor(private recentTasks: RecentTasks) { } async getRecentApps() { try { const tasks = await this.recentTasks.getRecentTasks(); if (tasks.length > 0) { console.log('当前前台/最近应用包名:', tasks[0].packageName); } } catch (error) { console.error('获取最近应用失败:', error); } }
二、自定义原生Android代码(插件不满足需求时)
如果现有插件不符合需求,可以自行封装简单的Cordova插件:
- 编写Android原生逻辑代码:
import android.app.ActivityManager; import android.content.Context; import android.os.Build; import android.app.usage.UsageStats; import android.app.usage.UsageStatsManager; import org.apache.cordova.CallbackContext; import org.apache.cordova.CordovaPlugin; import org.json.JSONArray; import org.json.JSONException; import java.util.List; import java.util.SortedMap; import java.util.TreeMap; public class ForegroundAppPlugin extends CordovaPlugin { @Override public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException { if (action.equals("getForegroundPackage")) { String packageName = getForegroundAppPackage(); if (packageName != null) { callbackContext.success(packageName); } else { callbackContext.error("无法获取前台应用包名"); } return true; } return false; } private String getForegroundAppPackage() { Context context = cordova.getActivity().getApplicationContext(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) { // Android 5.1及以上使用UsageStatsManager UsageStatsManager usageStatsManager = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE); long endTime = System.currentTimeMillis(); long startTime = endTime - 1000 * 60; List<UsageStats> usageStatsList = usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_BEST, startTime, endTime); if (usageStatsList != null && !usageStatsList.isEmpty()) { SortedMap<Long, UsageStats> sortedMap = new TreeMap<>(); for (UsageStats usageStats : usageStatsList) { sortedMap.put(usageStats.getLastTimeUsed(), usageStats); } if (!sortedMap.isEmpty()) { return sortedMap.get(sortedMap.lastKey()).getPackageName(); } } } else { // Android 5.1以下兼容逻辑(已过时) ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); ActivityManager.RunningTaskInfo taskInfo = activityManager.getRunningTasks(1).get(0); return taskInfo.topActivity.getPackageName(); } return null; } } - 在插件
plugin.xml中配置权限与文件:<platform name="android"> <config-file target="AndroidManifest.xml" parent="/manifest"> <uses-permission android:name="android.permission.GET_TASKS" /> <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" tools:ignore="ProtectedPermissions" /> </config-file> <source-file src="src/android/ForegroundAppPlugin.java" target-dir="src/com/yourcompany/foregroundapp" /> </platform> - Ionic项目中调用自定义插件:
declare var cordova: any; async getForegroundPackage() { try { const packageName = await new Promise((resolve, reject) => { cordova.exec(resolve, reject, "ForegroundAppPlugin", "getForegroundPackage", []); }); console.log('前台应用包名:', packageName); } catch (error) { console.error(error); } }
关键注意事项
- 权限要求:Android 10(API 29)及以上版本,必须申请
PACKAGE_USAGE_STATS权限,该权限无法通过代码主动请求,需要引导用户到系统设置的「应用使用权限」页面手动开启。 - 版本兼容:不同Android版本的API存在差异,高版本系统对后台获取应用信息的限制更严格,建议优先使用
UsageStatsManager实现更稳定的检测逻辑。
内容的提问来源于stack exchange,提问作者Carlo A
相关产品推荐
相关产品推荐

