繁体   English   中英

如何检测特定的 Android 应用程序何时进入后台?

[英]How to detect when a specific Android app goes to the background?

我正在尝试编写一个应用程序,当另一个特定应用程序进入后台时,该应用程序将启动,或显示通知或弹出窗口。 例如:

  • 用户启动应用程序 A
  • 用户使用应用程序 A
  • 用户通过按下主页按钮或后退按钮或启动另一个应用程序将应用程序 A 置于后台
  • 我的应用程序检测到并自行启动或显示弹出窗口或其他任何内容

有没有办法做到这一点,如果有的话,而不会杀死电池?

在您的应用程序A 中,将以下代码放在一个类中:

public class Foreground implements Application.ActivityLifecycleCallbacks {

public static final long CHECK_DELAY = 500;
public static final String TAG = Foreground.class.getName();

public interface Listener {

    public void onBecameForeground();

    public void onBecameBackground();

}

private static Foreground instance;

private boolean foreground = false, paused = true;
private Handler handler = new Handler();
private List<Listener> listeners = new CopyOnWriteArrayList<Listener>();
private Runnable check;

/**
 * Its not strictly necessary to use this method - _usually_ invoking
 * get with a Context gives us a path to retrieve the Application and
 * initialise, but sometimes (e.g. in test harness) the ApplicationContext
 * is != the Application, and the docs make no guarantees.
 *
 * @param application
 * @return an initialised Foreground instance
 */
public static Foreground init(Application application) {
    if (instance == null) {
        instance = new Foreground();
        application.registerActivityLifecycleCallbacks(instance);
    }
    return instance;
}

public static Foreground get(Application application) {
    if (instance == null) {
        init(application);
    }
    return instance;
}

public static Foreground get(Context ctx) {
    if (instance == null) {
        Context appCtx = ctx.getApplicationContext();
        if (appCtx instanceof Application) {
            init((Application) appCtx);
        }
        throw new IllegalStateException(
                "Foreground is not initialised and " +
                        "cannot obtain the Application object");
    }
    return instance;
}

public static Foreground get() {
    if (instance == null) {
        throw new IllegalStateException(
                "Foreground is not initialised - invoke " +
                        "at least once with parameterised init/get");
    }
    return instance;
}

public boolean isForeground() {
    return foreground;
}

public boolean isBackground() {
    return !foreground;
}

public void addListener(Listener listener) {
    listeners.add(listener);
}

public void removeListener(Listener listener) {
    listeners.remove(listener);
}

@Override
public void onActivityResumed(Activity activity) {
    paused = false;
    boolean wasBackground = !foreground;
    foreground = true;

    if (check != null)
        handler.removeCallbacks(check);

    if (wasBackground) {
        Log.i(TAG, "went foreground");
        for (Listener l : listeners) {
            try {
                l.onBecameForeground();
            } catch (Exception exc) {
                Log.e(TAG, "Listener threw exception!", exc);
            }
        }
    } else {
        Log.i(TAG, "still foreground");
    }
}

@Override
public void onActivityPaused(Activity activity) {
    paused = true;

    if (check != null)
        handler.removeCallbacks(check);

    handler.postDelayed(check = new Runnable() {
        @Override
        public void run() {
            if (foreground && paused) {
                foreground = false;
                Log.i(TAG, "went background");
                for (Listener l : listeners) {
                    try {
                        l.onBecameBackground();
                        Intent intent = getPackageManager().getLaunchIntentForPackage("com.package.name");
                        if (intent != null) {
                            // We found the activity now start the activity
                            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                            startActivity(intent);
                        } else {
                            // Bring user to the market or let them choose an app?
                            intent = new Intent(Intent.ACTION_VIEW);
                            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                            intent.setData(Uri.parse("market://details?id=" + "com.package.name"));
                            startActivity(intent);
                        }
                    } catch (Exception exc) {
                        Log.e(TAG, "Listener threw exception!", exc);
                    }
                }
            } else {
                Log.i(TAG, "still foreground");
            }
        }
    }, CHECK_DELAY);
}

@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
}

@Override
public void onActivityStarted(Activity activity) {
}

@Override
public void onActivityStopped(Activity activity) {
}

@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}

@Override
public void onActivityDestroyed(Activity activity) {
}

}

现在在 Application.class 的 onCreate 方法中放入代码:

 @Override
public void onCreate() {
    super.onCreate();
    Foreground.init(this);
}

您必须在 onActivityPaused() 方法中设置应用程序的包名称。 谢谢

在onPause中做代码

@Override
protected void onPause() {

    Toast.makeText(getApplicationContext(),"Background",Toast.LENGTH_LONG).show();
    super.onPause();
}

因此,如果应用程序进入后台,您将获得吐司。 希望它有帮助..一切顺利

尝试使用服务。 http://developer.android.com/guide/components/services.html上阅读更多信息

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM