我有一个Android应用程序,我需要一个功能或任何广播接收器,可以检查应用程序是否关闭..我不需要在每个活动中调用destroy(应用程序中有大约20个活动) 我试图在应用程序类
中添加此功能public class ApplicationLifeCycleManager implements ActivityLifecycleCallbacks {
/** Manages the state of opened vs closed activities, should be 0 or 1.
* It will be 2 if this value is checked between activity B onStart() and
* activity A onStop().
* It could be greater if the top activities are not fullscreen or have
* transparent backgrounds.
*/
private static int visibleActivityCount = 0;
/** Manages the state of opened vs closed activities, should be 0 or 1
* because only one can be in foreground at a time. It will be 2 if this
* value is checked between activity B onResume() and activity A onPause().
*/
private static int foregroundActivityCount = 0;
/** Returns true if app has foreground */
public static boolean isAppInForeground(){
return foregroundActivityCount > 0;
}
/** Returns true if any activity of app is visible (or device is sleep when
* an activity was visible) */
public static boolean isAppVisible(){
return visibleActivityCount > 0;
}
public void onActivityCreated(Activity activity, Bundle bundle) {
}
public void onActivityDestroyed(Activity activity) {
Log.wtf("destroyed","app closed!!");
}
public void onActivityResumed(Activity activity) {
foregroundActivityCount ++;
}
public void onActivityPaused(Activity activity) {
foregroundActivityCount --;
}
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
public void onActivityStarted(Activity activity) {
visibleActivityCount ++;
}
public void onActivityStopped(Activity activity) {
visibleActivityCount --;
}
}
此外,我已在应用程序类
中创建了@Override
public void onCreate() {
super.onCreate();
registerActivityLifecycleCallbacks(new ApplicationLifeCycleManager());
}
但是当我在activity之间切换时会调用onPaused和onResumed以及onDestroyed函数:因为它检测是否有任何活动被关闭或被破坏甚至恢复
所以检查应用程序是否在一个函数中关闭的任何解决方案??
答案 0 :(得分:5)
此答案使用ProcessLifecycleOwner来检测应用程序可见性。
是Android Architecture Component的一部分。
implementation "android.arch.lifecycle:extensions:1.1.1"
public class AppController extends Application implements LifecycleObserver {
///////////////////////////////////////////////
@OnLifecycleEvent(Lifecycle.Event.ON_START)
public void onEnterForeground() {
Log.d("AppController", "Foreground");
isAppInBackground(false);
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
public void onEnterBackground() {
Log.d("AppController", "Background");
isAppInBackground(true);
}
///////////////////////////////////////////////
// Adding some callbacks for test and log
public interface ValueChangeListener {
void onChanged(Boolean value);
}
private ValueChangeListener visibilityChangeListener;
public void setOnVisibilityChangeListener(ValueChangeListener listener) {
this.visibilityChangeListener = listener;
}
private void isAppInBackground(Boolean isBackground) {
if (null != visibilityChangeListener) {
visibilityChangeListener.onChanged(isBackground);
}
}
private static AppController mInstance;
public static AppController getInstance() {
return mInstance;
}
@Override
public void onCreate() {
super.onCreate();
mInstance = this;
// addObserver
ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
}
}
并像这样使用它:
AppController.getInstance().setOnVisibilityChangeListener(new ValueChangeListener() {
@Override
public void onChanged(Boolean value) {
Log.d("isAppInBackground", String.valueOf(value));
}
});
不要忘记将应用程序name
添加到您的manifest
<application
android:name="myPackageName.AppController"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"">
完成。
(Kotlin示例)
答案 1 :(得分:2)
您可以使用此功能确定应用是否已关闭(不在后台或前台)。
private boolean isAppRunning() {
ActivityManager m = (ActivityManager) this.getSystemService( ACTIVITY_SERVICE );
List<ActivityManager.RunningTaskInfo> runningTaskInfoList = m.getRunningTasks(10);
Iterator<ActivityManager.RunningTaskInfo> itr = runningTaskInfoList.iterator();
int n=0;
while(itr.hasNext()){
n++;
itr.next();
}
if(n==1){ // App is killed
return false;
}
return true; // App is in background or foreground
}
您还可以使用此功能检查应用是否在前台: https://stackoverflow.com/a/8490088/9005188
答案 2 :(得分:1)
基本上查看您的问题,您希望跟踪应用中的状态更改。
要正确处理所有用例可能非常困难。但是有一个令人惊叹的库,它非常好用,非常容易使用 - RxAppState。
我已经使用这个库很长一段时间了,它在所有情况下都能很好地工作。 我强烈建议您试试这个。
答案 3 :(得分:0)
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (isAppForground(context)) {
// App is in Foreground
} else {
// App is in Background
}
}
private boolean isAppOnForeground(Context context,String appPackageName) {
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
if (appProcesses == null) {
//App is closed
return false;
}
final String packageName = appPackageName;
for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND && appProcess.processName.equals(packageName)) {
// Log.e("app",appPackageName);
return true;
}else{
//App is closed
}
}
return false;
}
}
添加此权限
<uses-permission android:name="android.permission.GET_TASKS" />
试试希望它有所帮助
答案 4 :(得分:0)
就像@ S.R答案一样,您也可以在自定义应用程序中使用接口“ Application.ActivityLifecycleCallbacks”,然后在“ onActivityStopped”中使用“ isAppOnForeground(Context)”方法。
public class MyApplication extends Application import Application.ActivityLifecycleCallbacks{
[ Code of ur app class...]
/* START Override ActivityLifecycleCallbacks Methods */
@Override
public void onActivityCreated(Activity activity, Bundle bundle) {
mActivitiesBackStack.add(activity.getClass());
}
@Override
public void onActivityStarted(Activity activity) {
}
@Override
public void onActivityResumed(Activity activity) {
}
@Override
public void onActivityPaused(Activity activity) {
}
@Override
public void onActivityStopped(Activity activity) {
if(!AppUtils.isAppOnForeground(this)){
[Code when app in background...]
}
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
}
@Override
public void onActivityDestroyed(Activity activity) {
if(mActivitiesBackStack.contains(activity.getClass())){
mActivitiesBackStack.remove(activity.getClass());
}
}
/* END Override ActivityLifecycleCallbacks Methods */
[ Code of ur app class...]
应用每次在后台运行时都会调用,而不是在关闭时调用。 如果将“ isAppOnForeground”放入“ onActivityDestroyed”中,则它将与上面的“ isAppOnForeground”代码不兼容,因为它找不到进程(我认为),也许更改了上面的代码或使用了其他实现,它将起作用。 关闭应用程序时将调用“ onActivityDestroyed”,因此,如果您可以在调用时检查该应用程序是否在后台(因此该应用程序已关闭),则可以精确地关闭该应用程序的那一刻。 / p>
“ isAppOnForeground”的代码(我在Utils静态类中使用它):
public static boolean isAppOnForeground(Context context) {
boolean ret = false;
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
if(appProcesses != null){
String packageName = context.getPackageName();
for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND && appProcess.processName.equals(packageName)) {
ret = true;
}
}
}
return ret;
}
希望这会有所帮助,再见,祝您编程愉快! :D
答案 5 :(得分:-1)
使用一项从Application类开始的服务。
public class AppService extends Service {
@Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
//here you will get call when app close.
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
从Application类启动此服务。
@Override
public void onCreate() {
super.onCreate();
Intent intent = new Intent(getApplicationContext(), AppService.class);
startService(intent);
}