如何让应用在后台保持活动状态直到用户关闭或结束应用?

3
我能在用户没有杀掉或关闭应用的情况下,将Android活动保持在后台。我想要检测特定硬件按钮点击事件,但是由于服务中不可用的KeyDown方法,所以需要将我的活动保持在后台,直到用户关闭应用程序。 Android允许此类行为吗?
更新:
我能使用以下方法解决这个问题:
1]使用前台服务, 参考: https://developer.android.com/guide/components/services.html#Foreground 2]在Android 21+之后使用以下方法处理媒体按钮单击(在前台服务的onCreate()中使用此代码):
mediaSession = new MediaSessionCompat(this, TAG);
        mediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS);
        mediaSession.setCallback(new MediaSessionCompat.Callback() {
            @Override
            public boolean onMediaButtonEvent(Intent mediaButtonEvent) {
                if (mediaButtonEvent.getAction().equals(Intent.ACTION_MEDIA_BUTTON)) {
                    KeyEvent event = (KeyEvent) mediaButtonEvent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
                    if (KeyEvent.KEYCODE_HEADSETHOOK == event.getKeyCode() && event.getAction() == KeyEvent.ACTION_DOWN) {
                        Log.e(TAG, "Media Button clicked");
                        handleHeadphoneClick();
                    }
                }
                return false;
            }
        });
        mediaSession.setActive(true);

参考文献:https://developer.android.com/guide/topics/media-apps/mediabuttons.html

这篇文章介绍了如何在 Android 应用程序中实现媒体按钮。Android 系统通常具有媒体按钮,例如播放、暂停和跳过按钮。开发人员可以轻松地将这些按钮集成到其应用程序中,以控制音频或视频播放。此外,该文章还提供了一些示例代码和有关如何添加自定义行为的指南。

只要你在谷歌上搜索“如何在关闭应用程序后保持我的服务”,你就会找到解决方案。 - Basil Battikhi
保持服务的活动状态不是问题,但在服务中检测硬件按钮点击是不被允许的,即使我们尝试使用一些广播捕获,这样的硬件广播在较高版本的Android中也无法工作。 - Prashant
你可以在服务中使用onKeyDown和onKeyUp点击事件。@pcj - Nikhil
1
你不应该这样做,而且Activity没有办法。你可以并且应该使用Service来完成。 - Vladyslav Matviienko
嘿 @pcj,检查下面的答案,它适用于你。 - Nikhil
显示剩余2条评论
3个回答

0

来自developer.android.com的内容:

服务是在后台运行以执行长时间操作或为远程进程执行工作的组件。服务不提供用户界面。例如,服务可以在用户使用不同应用程序时在后台播放音乐,或者可以在不阻止与活动交互的情况下通过网络获取数据。另一个组件(如活动)可以启动服务并让其运行,或者绑定到它以与之交互。服务是Service类的子类实现的,您可以在Services开发人员指南中了解更多信息。

因此,只要创建了服务,用户退出应用程序后它仍将运行。就像上面的例子一样。

这应该为您提供所需的所有信息: 访问此链接


保持服务的运行不是问题,但在服务中检测硬件按钮的点击是不允许的。即使我们尝试使用一些广播来捕获,这样的硬件广播在较高版本的Android系统中也无法正常工作。 - Prashant
1
他在询问如何保持活动状态而不是服务。 - Avinash Roy

0

简单来说,只需创建一个新的服务类。在这里,使用此类,您可以在日志中查看硬件按钮点击事件。在这里我使用音量键作为onKeyEvent

public class Xtra extends Service {


@Override
public void onCreate() {
    // TODO Auto-generated method stub
    super.onCreate();

    final BroadcastReceiver vReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
            boolean isScreenOn = powerManager.isScreenOn();


            if (!isScreenOn) {

                PowerManager pm = (PowerManager) getApplicationContext().getSystemService(Context.POWER_SERVICE);
                PowerManager.WakeLock mWakeLock = pm.newWakeLock((PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP), "YourService");
                mWakeLock.acquire();
                // The screen has been locked
                // do stuff...
                Log.e("Do what you want to do from this service...", "Here screen is off..which do not show or work anything due to screen is off");
Toast.makeText(getActivity(), "Here screen is off..which do not show or work anything due to screen is off", Toast.LENGTH_SHORT).show();

} else {
                Log.e("Do what you want to do from this service...", "Here screen is on, works...");
Toast.makeText(getActivity(), "Here screen is on, works...", Toast.LENGTH_SHORT).show();

            }
        }

    };
    registerReceiver(vReceiver, new IntentFilter("android.media.VOLUME_CHANGED_ACTION"));
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    // TODO Auto-generated method stub
    return super.onStartCommand(intent, flags, startId);
    //43200000 schedules notification on every 12 hours
}


@Override
public void onDestroy() {
    // TODO Auto-generated method stub
    Log.e("BgService", "::>> Service Stopped...");
    super.onDestroy();
}

@Override
public IBinder onBind(Intent intent) {
    // TODO Auto-generated method stub
    return null;
}
}

在您的活动中创建一个按钮点击事件来启动服务。它将在后台启动您的服务。
Button btnSave;
btnSave.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
      //From here service starts when you click on a button.
           startService(new Intent(activity, Xtra.class));
        }
    });

别忘了将这个服务添加到你的清单文件中。

<service android:name=".Xtra">
        <intent-filter>
            <action android:name="android.intent.action.MEDIA_BUTTON" />
        </intent-filter>
    </service>

当您点击btnSave时,它将启动您的服务。现在只需转到主屏幕并单击音量键,您肯定会得到结果,因为对我来说它运行良好。


嘿,感谢你在这里给了我一些提示。你的答案类似于这个链接:https://developer.android.com/reference/android/support/v4/media/session/MediaButtonReceiver.html 我会在我的服务中尝试这种方法。 - Prashant
1
没有问题。我随时准备好帮助你。 - Nikhil
请注意,此解决方案/操作虽然可行,但并非SDK的“官方”部分。请参见此处:https://dev59.com/AV_Va4cB1Zd3GeqPUpbW#8974510 - Venryx
此外,只有在我将android.media.VOLUME_CHANGED_ACTION添加到清单中并/或将android.intent.action.MEDIA_BUTTON作为接收器的触发器时,它才对我起作用。(不确定哪个更改修复了它) - Venryx

0

更新:

我能够使用以下方法解决这个问题:

1] 使用前台服务, 参考:https://developer.android.com/guide/components/services.html#Foreground

2] 在 Android 21+ 版本中,处理媒体按钮点击的方法如下(将此代码放在前台服务的 onCreate() 方法中):

mediaSession = new MediaSessionCompat(this, TAG);
        mediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS);
        mediaSession.setCallback(new MediaSessionCompat.Callback() {
            @Override
            public boolean onMediaButtonEvent(Intent mediaButtonEvent) {
                if (mediaButtonEvent.getAction().equals(Intent.ACTION_MEDIA_BUTTON)) {
                    KeyEvent event = (KeyEvent) mediaButtonEvent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
                    if (KeyEvent.KEYCODE_HEADSETHOOK == event.getKeyCode() && event.getAction() == KeyEvent.ACTION_DOWN) {
                        Log.e(TAG, "Media Button clicked");
                        handleHeadphoneClick();
                    }
                }
                return false;
            }
        });
        mediaSession.setActive(true);

参考:https://developer.android.com/guide/topics/media-apps/mediabuttons.html


这个答案中的特定代码在我的设备上(Android 9)无法工作。我找到了这个可行的替代版本:https://dev59.com/o2kw5IYBdhLWcg3wE2dA#43304591 - Venryx

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接