dha*_*wat 107 android android-service android-background
我希望有一个在后台运行的应用程序,它知道任何内置应用程序(消息,联系人等)何时运行.
所以我的问题是:
我应该如何在后台运行我的应用程序.
我的后台应用程序如何知道前台运行的应用程序是什么.
有经验的人的回应将不胜感激.
Oli*_*ain 103
关于"2.我的后台应用程序如何知道当前在前台运行的应用程序是什么."
不要使用这个getRunningAppProcesses()
方法,因为这会从我的经验中返回各种系统垃圾,你会得到多个结果RunningAppProcessInfo.IMPORTANCE_FOREGROUND
.请getRunningTasks()
改用
这是我在服务中用来识别当前前台应用程序的代码,它非常简单:
ActivityManager am = (ActivityManager) AppService.this.getSystemService(ACTIVITY_SERVICE);
// The first in the list of RunningTasks is always the foreground task.
RunningTaskInfo foregroundTaskInfo = am.getRunningTasks(1).get(0);
Run Code Online (Sandbox Code Playgroud)
多数民众赞成,然后您可以轻松访问前台应用/活动的详细信息:
String foregroundTaskPackageName = foregroundTaskInfo .topActivity.getPackageName();
PackageManager pm = AppService.this.getPackageManager();
PackageInfo foregroundAppPackageInfo = pm.getPackageInfo(foregroundTaskPackageName, 0);
String foregroundTaskAppName = foregroundAppPackageInfo.applicationInfo.loadLabel(pm).toString();
Run Code Online (Sandbox Code Playgroud)
这需要在活动清单中获得额外的许可,并且完美地运行.
<uses-permission android:name="android.permission.GET_TASKS" />
Run Code Online (Sandbox Code Playgroud)
Sve*_*itz 38
我必须以艰难的方式找出正确的解决方案.下面的代码是cyanogenmod7(平板电脑调整)的一部分,并在android 2.3.3/gingerbread上测试.
方法:
希望能在所有方面解决这个问题(:
private RunningAppProcessInfo getForegroundApp() {
RunningAppProcessInfo result=null, info=null;
if(mActivityManager==null)
mActivityManager = (ActivityManager)mContext.getSystemService(Context.ACTIVITY_SERVICE);
List <RunningAppProcessInfo> l = mActivityManager.getRunningAppProcesses();
Iterator <RunningAppProcessInfo> i = l.iterator();
while(i.hasNext()){
info = i.next();
if(info.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND
&& !isRunningService(info.processName)){
result=info;
break;
}
}
return result;
}
private ComponentName getActivityForApp(RunningAppProcessInfo target){
ComponentName result=null;
ActivityManager.RunningTaskInfo info;
if(target==null)
return null;
if(mActivityManager==null)
mActivityManager = (ActivityManager)mContext.getSystemService(Context.ACTIVITY_SERVICE);
List <ActivityManager.RunningTaskInfo> l = mActivityManager.getRunningTasks(9999);
Iterator <ActivityManager.RunningTaskInfo> i = l.iterator();
while(i.hasNext()){
info=i.next();
if(info.baseActivity.getPackageName().equals(target.processName)){
result=info.topActivity;
break;
}
}
return result;
}
private boolean isStillActive(RunningAppProcessInfo process, ComponentName activity)
{
// activity can be null in cases, where one app starts another. for example, astro
// starting rock player when a move file was clicked. we dont have an activity then,
// but the package exits as soon as back is hit. so we can ignore the activity
// in this case
if(process==null)
return false;
RunningAppProcessInfo currentFg=getForegroundApp();
ComponentName currentActivity=getActivityForApp(currentFg);
if(currentFg!=null && currentFg.processName.equals(process.processName) &&
(activity==null || currentActivity.compareTo(activity)==0))
return true;
Slog.i(TAG, "isStillActive returns false - CallerProcess: " + process.processName + " CurrentProcess: "
+ (currentFg==null ? "null" : currentFg.processName) + " CallerActivity:" + (activity==null ? "null" : activity.toString())
+ " CurrentActivity: " + (currentActivity==null ? "null" : currentActivity.toString()));
return false;
}
private boolean isRunningService(String processname){
if(processname==null || processname.isEmpty())
return false;
RunningServiceInfo service;
if(mActivityManager==null)
mActivityManager = (ActivityManager)mContext.getSystemService(Context.ACTIVITY_SERVICE);
List <RunningServiceInfo> l = mActivityManager.getRunningServices(9999);
Iterator <RunningServiceInfo> i = l.iterator();
while(i.hasNext()){
service = i.next();
if(service.process.equals(processname))
return true;
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
小智 35
请尝试以下代码:
ActivityManager activityManager = (ActivityManager) newContext.getSystemService( Context.ACTIVITY_SERVICE );
List<RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
for(RunningAppProcessInfo appProcess : appProcesses){
if(appProcess.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND){
Log.i("Foreground App", appProcess.processName);
}
}
Run Code Online (Sandbox Code Playgroud)
进程名称是在前台运行的应用程序的程序包名称.将其与应用程序的包名称进行比较.如果它是相同的,那么您的应用程序正在前台运行.
我希望这回答了你的问题.
Sum*_*man 24
从棒棒糖开始,这变了.请找到下面的代码,然后用户必须进入设置 - >安全 - >(向下滚动到最后)具有使用权限的应用程序 - >授予我们的应用程序权限
private void printForegroundTask() {
String currentApp = "NULL";
if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
UsageStatsManager usm = (UsageStatsManager) this.getSystemService(Context.USAGE_STATS_SERVICE);
long time = System.currentTimeMillis();
List<UsageStats> appList = usm.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, time - 1000*1000, time);
if (appList != null && appList.size() > 0) {
SortedMap<Long, UsageStats> mySortedMap = new TreeMap<Long, UsageStats>();
for (UsageStats usageStats : appList) {
mySortedMap.put(usageStats.getLastTimeUsed(), usageStats);
}
if (mySortedMap != null && !mySortedMap.isEmpty()) {
currentApp = mySortedMap.get(mySortedMap.lastKey()).getPackageName();
}
}
} else {
ActivityManager am = (ActivityManager)this.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> tasks = am.getRunningAppProcesses();
currentApp = tasks.get(0).processName;
}
Log.e(TAG, "Current App in foreground is: " + currentApp);
}
Run Code Online (Sandbox Code Playgroud)
考虑到已getRunningTasks()
被弃用getRunningAppProcesses()
且不可靠,我决定结合StackOverflow中提到的两种方法:
private boolean isAppInForeground(Context context)
{
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
{
ActivityManager am = (ActivityManager) context.getSystemService(ACTIVITY_SERVICE);
ActivityManager.RunningTaskInfo foregroundTaskInfo = am.getRunningTasks(1).get(0);
String foregroundTaskPackageName = foregroundTaskInfo.topActivity.getPackageName();
return foregroundTaskPackageName.toLowerCase().equals(context.getPackageName().toLowerCase());
}
else
{
ActivityManager.RunningAppProcessInfo appProcessInfo = new ActivityManager.RunningAppProcessInfo();
ActivityManager.getMyMemoryState(appProcessInfo);
if (appProcessInfo.importance == IMPORTANCE_FOREGROUND || appProcessInfo.importance == IMPORTANCE_VISIBLE)
{
return true;
}
KeyguardManager km = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
// App is foreground, but screen is locked, so show notification
return km.inKeyguardRestrictedInputMode();
}
}
Run Code Online (Sandbox Code Playgroud)
为了确定前台应用程序,可以使用来检测前台应用程序,可以使用https://github.com/ricvalerio/foregroundappchecker。根据设备的android版本,它使用不同的方法。
至于服务,存储库还提供了所需的代码。本质上,让android studio为您创建服务,然后onCreate添加使用appChecker的代码段。但是,您将需要请求许可。
对于需要从我们自己的服务/后台线程检查我们的应用程序是否在前台的情况。这是我实施的方式,对我来说很好用:
public class TestApplication extends Application implements Application.ActivityLifecycleCallbacks {
public static WeakReference<Activity> foregroundActivityRef = null;
@Override
public void onActivityStarted(Activity activity) {
foregroundActivityRef = new WeakReference<>(activity);
}
@Override
public void onActivityStopped(Activity activity) {
if (foregroundActivityRef != null && foregroundActivityRef.get() == activity) {
foregroundActivityRef = null;
}
}
// IMPLEMENT OTHER CALLBACK METHODS
}
Run Code Online (Sandbox Code Playgroud)
现在要从其他类中检查应用是否在前台,只需调用:
if(TestApplication.foregroundActivityRef!=null){
// APP IS IN FOREGROUND!
// We can also get the activity that is currently visible!
}
Run Code Online (Sandbox Code Playgroud)
更新(如SHS所指出):
不要忘记在Application类的onCreate
方法中注册回调。
@Override
public void onCreate() {
...
registerActivityLifecycleCallbacks(this);
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
96032 次 |
最近记录: |