Android - 从通知的操作按钮调用服务时遇到问题

时间:2014-10-25 14:12:44

标签: android android-notifications google-cloud-messaging intentservice

我希望能够有一个按钮,将文本从通知复制到剪贴板。该通知是通过Google的GCM服务发送的。

当我按下"复制"第一次收到通知时按钮一切正常,文本通过按钮发送意图的服务进入剪贴板。当我按下"复制"第二次使用不同文本的通知到达时按钮第一个通知的内容进入剪贴板而不是新的。当我调试代码时,似乎调用该服务的意图具有新内容,但是将其放入剪贴板的服务使用旧通知的参数运行,就像服务的同一会话一样用旧的意图唤醒。

有什么理由发生这种情况?

// Called by the GCM notification handler

private void sendNotification(String msg) {
    mNotificationManager = (NotificationManager)
            this.getSystemService(Context.NOTIFICATION_SERVICE);
    PendingIntent contentIntent = PendingIntent.getActivity(this, 0,new Intent(this, MainActivity.class), 0);
    Intent notificationIntent = new Intent(this, clipboardService.class);
    notificationIntent.putExtra("tool",msg);
    PendingIntent serviceIntent = PendingIntent.getService(this, 0, notificationIntent, 0);

    NotificationCompat.Builder mBuilder =
            new NotificationCompat.Builder(this)
                    .setSmallIcon(R.drawable.ic_stat_gcm)
                    .setContentTitle("Here's your text!")
                    .setStyle(new NotificationCompat.BigTextStyle()
                            .bigText(msg))
                    .setContentText(msg)
                    .addAction(R.drawable.ic_stat_gcm, "Copy", serviceIntent); // <--- The intent will have the right (new) value on the second run
    mBuilder.setContentIntent(contentIntent);
    mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
}

这是通知操作调用的服务:

public class clipboardService extends IntentService {
public clipboardService() {
    super("clipboardService");
}

@Override
protected void onHandleIntent(Intent intent) { //This intent will have the values of the first intent to fire, instead of the updated one.
    String msg = (String) intent.getExtras().get("tool");
    ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
    ClipData clip = ClipData.newPlainText("2android",msg);
    clipboard.setPrimaryClip(clip);
}

1 个答案:

答案 0 :(得分:0)

虽然现在回答你的问题已经很晚了,但最近我遇到了同样的问题,谷歌也向我提出了这个悬而未决的问题。所以这是我的理解,如果将来有人挖掘它。

这是因为PendingIntent使用来自之前的intent实例的缓存intent extra,除非你明确告诉它不要。有两种方法可以做到这一点......

  1. 在构建FLAG_CANCEL_CURRENT时,使用FLAG_UPDATE_CURRENTPendingIntent(在您的情况下最好)作为标记。第一个标志将自动关闭先前的PendingIntent并创建一个全新的标志,第二个标志将仅更新PendingIntent的额外内容,并节省创建全新标记的开销。

    PendingIntent.getService(this, 0, notificationIntent, 
                             FLAG_CANCEL_CURRENT |  FLAG_UPDATE_CURRENT);
    
  2. 每次都将唯一的requestCode传递给PendingIntent构造函数。这将为每次生成唯一的待处理意图,以便您以后可以访问与特定意图关联的额外内容。我相信在你的情况下这不是必需的。

    PendingIntent.getService(this, UNIQUE_ID, pi, 0);