【问题标题】:How can I detect if my app is swiped from the app switcher?如何检测我的应用是否从应用切换器中滑动?
【发布时间】:2016-06-02 13:22:56
【问题描述】:

我的 Android 音频播放器应用在播放时设置了绑定服务,以确保它不会被系统杀死。该应用程序使用系统媒体播放器。该服务在系统栏中创建一个通知图标。

当我从最近的应用程序列表中滑动应用程序时,应用程序消失了。但是:媒体播放器继续播放,通知留在系统栏中。

当我选择通知或应用程序图标时,它会启动应用程序的新实例,无法访问正在运行的实例。它只能通过在应用程序的系统设置中选择强制停止来停止。如果我不从列表中滑动应用程序,我总是会回到正在播放的实例。

如果只有我的应用程序能够检测到它何时从列表中滑出,它就可以正确停止一切。但是 onDestroy() 不能保证被调用 - 并且不会例如在 CM12 中。 onStop() 或 onPause() 对我来说不适用,因为当应用程序刚进入后台时音频不应该停止。

那么,如何检测应用何时从列表中滑出?

这就是服务。这里可以做点什么吗?

public class myService extends Service {
...

@Override
public void onCreate() {
    mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
    showNotification();
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    return START_STICKY;
}

@Override
public void onDestroy() {
    mNM.cancel(NOTIFICATION);
    stopForeground(true);
}

@Override
public IBinder onBind(Intent intent) {
    return mBinder;
}
...

private void showNotification() {
    Notification notification = new Notification(R.drawable.icon, "Hello", 0);
    Intent intent = new Intent(this, myActivity.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
    PendingIntent pendIntent = PendingIntent.getActivity(this, 0, intent, 0);
    notification.setLatestEventInfo(this, "AppName", "Hello", pendIntent);
    notification.flags |= Notification.FLAG_NO_CLEAR;
    startForeground(FOREGROUNDID, notification);
    }
}

这是我的服务的绑定方式:

private static ServiceConnection mConnection = new ServiceConnection() {
    public void onServiceConnected(ComponentName className, IBinder service) {
          // Not used
    }

    public void onServiceDisconnected(ComponentName className) {
          // Not used
    }
};

private static void doBindService() {
    context.bindService(
        new Intent(context, myService.class),
        mConnection, Context.BIND_AUTO_CREATE);
}

感谢您的帮助。

【问题讨论】:

  • Android 无法启动同一个应用程序的多个实例,那么“正在运行的实例不可访问”是什么意思?我在服务中没有看到媒体播放器,您是否希望 activity 不会被破坏?
  • 我预计活动、服务和媒体播放器会被销毁。随着媒体播放器的继续并且符号停留在系统栏中,我认为只有活动会被刷卡杀死,而服务不会。所以“运行实例”确实被错误地描述了。媒体播放器是在 Activity 中处理的,该服务仅用于防止应用被系统杀死并显示符号。正如我在某处读到的,这是一个有效的程序。
  • 是的,这是有效的程序。但是在这种情况下,媒体播放器控制器应该在服务中,以便重新启动的活动可以连接到它并控制正在运行的播放。

标签: android service android-mediaplayer


【解决方案1】:

Service 有一个 onTaskRemoved() 方法,该方法在这种情况下被触发。您可以在那里停止服务:

/**
 * This is called if the service is currently running and the user has
 * removed a task that comes from the service's application.  If you have
 * set ServiceInfo#FLAG_STOP_WITH_TASK ServiceInfo.FLAG_STOP_WITH_TASK}
 * then you will not receive this callback; instead, the service will simply
 * be stopped.
 *
 * @param rootIntent The original root Intent that was used to launch
 *                   the task that is being removed.
 */
@Override
public void onTaskRemoved(Intent rootIntent) {
    super.onTaskRemoved(rootIntent);

    stopSelf();
}

记得在onStop() 或onDestroy() 中解除Service 与Activity 的绑定。 (只要符合您的绑定策略即可。)

【讨论】:

  • 这听起来很奇怪,但是没有做任何改变它就可以按预期工作。我尝试按照您的建议添加 onTaskRemoved,但出现 @Override 错误。我还尝试了 Manifest 中服务的“android:stopWithTask”开关,这也不适用于我的 2.2 环境。现在我看不出与之前版本的代码有什么不同,但是滑动会停止媒体播放器和服务。
猜你喜欢
  • 2012-01-15
  • 1970-01-01
  • 2017-06-05
  • 1970-01-01
  • 1970-01-01
  • 2014-09-11
  • 2014-09-02
  • 1970-01-01
  • 2017-07-04
相关资源
最近更新 更多