我正在尝试在我的应用中添加通知操作项,这是一个音乐播放器。启动流时,应触发通知,并在通知中显示流的停止按钮。到目前为止通知工作正常,我遇到了停止操作项目的问题。以下是在启动流的服务中声明它的方式:
Intent stopIntent = new Intent(this, MusicPlayerNew.class);
stopIntent.putExtra("STOP", "STOP");
PendingIntent stopPendingIntent = PendingIntent.getActivity(this, 0,
stopIntent, PendingIntent.FLAG_UPDATE_CURRENT, null);
mBuilder.addAction(R.drawable.ic_stat_stop, "Stop", stopPendingIntent);
现在在onResume() - 我的活动方法中,我使用getIntent()。getStringExtra()检查“STOP”额外,但我通过getIntent()检索的意图没有设置额外内容:(
我还试图检查发送广播(我有一个广播接收器工作从服务到活动进行通信)
Intent stopIntent2 = new Intent(MusicPlayerNew.STOP_MEDIAPLAYER);
PendingIntent stopPendingIntent2 = PendingIntent.getBroadcast(this, 0,
stopIntent2, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.addAction(R.drawable.ic_stat_stop, "Stop", stopPendingIntent2);
现在,如果活动当前位于前台,则此功能正常。如果活动在后台,则停止按钮不执行任何操作:(
修改 我将Activity中的BroadcastReceiver作为私有类
private class DataUpdateReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
..
}}
在onResume()中注册我的app接收器:
intentFilter = new IntentFilter(STOP_MEDIAPLAYER);
registerReceiver(dataUpdateReceiver, intentFilter);
的onPause()
unregisterReceiver(dataUpdateReceiver);
现在,如果我从onPause() - 方法中删除取消注册,即使app / activity不在前台,也会收到广播。但这是正确的方法吗?我从网上的教程中得到了这个注册/取消注册的内容我认为..
答案 0 :(得分:10)
我在Google代码https://code.google.com/p/android/issues/detail?id=61850
中的此主题中找到了解决方案要修复此问题,您必须在PendingIntent.FLAG_CANCEL_CURRENT
添加PendingIntent
标记。
PendingIntent stopPendingIntent2 = PendingIntent.getBroadcast(this, 0,
stopIntent2, PendingIntent.FLAG_CANCEL_CURRENT);
答案 1 :(得分:7)
这是非常晚的答案,但它可能对某人有所帮助:
您应该根据要运行的意图选择正确的待处理意图。以下是一些示例:
活动使用以下内容:
Intent i = new Intent(this, YourActivity.class);
PendingIntent pi = PendingIntent.getActivity(this, 0, i, 0);
服务使用以下内容:
Intent i = new Intent(this, YourService.class);
PendingIntent pi = PendingIntent.getService(this, 0, i, 0);
对于广播接收器,请在下面使用:
Intent i = new Intent(this, YourReciver.class);
PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, 0);
您可能需要更改请求代码和Flags(如果需要)
答案 2 :(得分:6)
我今天遇到了这个问题。在我的情况下,由于pendingIntent
构造函数的所有参数都相同,所以它使用了之前的intent实例的缓存intent extras。我找到了两个解决方案...
将唯一的requestCode
传递给pendingIntent
,如下所示
PendingIntent pi = PendingIntent.getService(this, UNIQUE_ID, pi, 0);
在我的情况下,第二种方法解决了问题,因为我需要保持以前的通知存活。可能这会帮助有类似问题的人。
答案 3 :(得分:5)
我今天遇到了这个问题,这是因为活动没有注册或添加到 AndroidManifest.xml 。我以为我在那里有它,但它不是。此外,尝试以其意图调用操作时,未记录任何错误。
我通过创建一个intent然后在不使用通知的情况下调用startAcitivty(intent)来解决这个问题。然后它给了我一个错误,说明清单中可能缺少活动。
如果其他答案都没有解决您的问题,那么希望这样做。通常棘手的问题是简单而愚蠢的结果。
答案 4 :(得分:1)
除了使用广播接收器之外,您还应该使用服务并以这种方式在您的服务中声明一个新动作:
public final String ACTION_STOP = "yourpackagename.ACTION_STOP";
然后创建这样的意图:
Intent stopIntent = new Intent(this, YourService.class).setAction(YourService.ACTION_STOP);
PendingIntent stopPendingIntent = PendingIntent.getService(this, 0, stopIntent, 0);
当然,如果意图的行为等于startCommand
,请停止在服务的功能ACTION_STOP
中播放。
这应该可以解决问题;)
答案 5 :(得分:0)
由于您在onPause中取消注册,因此当它在后台时您不会收到广播。将unregisterReceiver代码移动到onDestroy函数。只有在活动被销毁时才会调用此方法。或者,您可以在预期事件发生后取消注册。
答案 6 :(得分:0)
这里有多个问题:
第1部分:为什么你的意图没有额外收到“停止”?
虽然在您提供的代码中没有看到,但我想确认您是否使用FLAG_ACTIVITY_SINGLE_TOP标志作为通知意图?如果是这样,您在活动中收到的意图将是启动活动的意图,因此“STOP”额外功能将无法使用。在这种情况下(发送新意图的地方),您需要扩展onNewIntent()
。 More info here。
如果您尚未使用FLAG_ACTIVITY_SINGLE_TOP,则表示在点击通知时会创建新活动,在这种情况下,Intent必须具有“STOP”参数。如果您能提供我所有相关的代码,我可以帮助您更好。
第2部分:使用广播接收器 正如您已经发现的那样,这不是直截了当的。您需要在onDestroy中取消注册,如果您的活动被用户关闭,则可能会调用onDestroy,并且您的广播接收器可能在用户点击通知时不活动。如果你根本没有取消注册,它可能似乎正在工作,但这是一个内存泄漏,GC可能会随时清理,这可能会导致程序崩溃,即,你必须取消注册。如果你需要使用广播接收器方法,你需要有一个服务来做到这一点,服务带来自己的陷阱 - >系统重启,电池耗尽等。我强烈建议你采用第一种方法。
答案 7 :(得分:0)
我有一个非常相似的问题,但是一个非常不同的解决方案。如果您在manifest.xml文件中声明了<service android:enabled="false"></service>
,则也不会触发挂起的意图。
从android:enabled="false"
替换为android:enabled="true"
这可能不是问题的直接问题。但是如果你使用默认模板在android studio中创建服务,它会自动将这些属性添加到服务中。
答案 8 :(得分:0)
对我来说,解决方案是设置意图的标志:
resultIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_CLEAR_TASK);
答案 9 :(得分:0)
就我而言,我在 BroadcastReceiver
类中创建了一个动态上下文注册 Service
,用于监听通知操作。
class MyService:Service(){
private val receiver: BroadcastReceiver = NotificationActionReceiver()
...
inner class NotificationActionReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
...
}
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
...
registerReceiver(receiver,IntentFilter("SOME_ACTION"))
return super.onStartCommand(intent, flags, startId)
}
override fun onDestroy() {
...
unregisterReceiver(receiver)
super.onDestroy()
}
PendingIntent
带有显式 Intent
val nextIntent = Intent(this, NotificationActionReceiver::class.java) //Explicit Intent
val nextPendingIntent: PendingIntent= PendingIntent.getBroadcast(this,0x11,nextIntent, PendingIntent.FLAG_CANCEL_CURRENT)
但是,通过这种设置,BroadcastReceiver
从未触发。
所以我所做的就是,
val nextIntent = Intent("SOME_ACTION") //Implicit Intent
val nextPendingIntent: PendingIntent= PendingIntent.getBroadcast(this,0x11,nextIntent, PendingIntent.FLAG_CANCEL_CURRENT)
注意:由于 BroadcastReceiver
是动态上下文注册的,因此您不必担心对隐式意图的限制