16

ユーザーからの入力を受け取り、それを通知として設定する非常にシンプルなアプリがあります。ユーザーは、好きなだけ通知を作成できます。ユーザーに通知をクリックして、と呼ばれる新しいアクティビティに移動してもらいたいResultActivity。次に、通知インテントからResultActivityを読み込み、ユーザーに表示します。以下のコードを使用すると、通知が押されるたびに最後に作成された通知putExtrasを受け取ることを除いて、私が望むほとんどすべてのことを実行できます。putExtra

Intent notificationIntent = new Intent(ctx, MainActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(ctx, i,notificationIntent,PendingIntent.FLAG_CANCEL_CURRENT);

NotificationManager nm = (NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE);

Resources res = ctx.getResources();
NotificationCompat.Builder builder = new NotificationCompat.Builder(ctx);
builder.setContentIntent(contentIntent)
    .setSmallIcon(R.drawable.ic_launcher)
    .setLargeIcon(BitmapFactory.decodeResource(res,R.drawable.ic_launcher))
    .setTicker("Remember to " + text.getText())
    .setWhen(System.currentTimeMillis()).setAutoCancel(true)
    .setContentTitle(text.getText());

// Creates an explicit intent for an Activity in your app
Intent resultIntent = new Intent(this, ResultActivity.class);
String pass = text.getText().toString();

resultIntent.putExtra("title", pass);
resultIntent.putExtra("uid", i);

TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
// Adds the back stack for the Intent (but not the Intent itself)
stackBuilder.addParentStack(ResultActivity.class);
// Adds the Intent that starts the Activity to the top of the stack
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0,PendingIntent.FLAG_UPDATE_CURRENT);

new Uri.Builder().scheme("data").appendQueryParameter("text", "my text").build();
builder.setContentIntent(resultPendingIntent);

Notification n = builder.build();
n.flags = Notification.FLAG_NO_CLEAR;
nm.notify(i++, n);
text.setText(null);
  1. アプリケーションを開きます

  2. 「One」と入力します

  3. ヒットOK

  4. 通知が送信されます

  5. アプリケーションを開きます

  6. 「2」と入力します

  7. ヒットOK

  8. 通知が送信されます

これで、2つの通知があります。「1つ」と言うものと「2つ」と言うもの。「Two」という通知をクリックすると、「Two」という画面が表示されます。完全!

通知「One」をクリックすると、「Two」という画面が表示されます。壊れた!

ResultActivity.java

public class ResultActivity extends Activity {
    String title = null;
    TextView text;

    int i=0;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity);
        text = (TextView) findViewById(R.id.textView1);



        title = getIntent().getStringExtra("title");
         i = getIntent().getIntExtra("uid", 0);


        text.setText(title);

    }
4

4 に答える 4

25

これはずっと前のことですが、コードの問題については答えが何も言われていないと感じています。だから問題はほとんどここにあります PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0,PendingIntent.FLAG_UPDATE_CURRENT);

したがって、update_current のフラグを持つスタックビルダーから pendingIntent を作成します。FLAG_UPDATE_CURRENT を見ると、

 /**
 * Flag indicating that if the described PendingIntent already exists,
 * then keep it but replace its extra data with what is in this new
 * Intent. For use with {@link #getActivity}, {@link #getBroadcast}, and
 * {@link #getService}. <p>This can be used if you are creating intents where only the
 * extras change, and don't care that any entities that received your
 * previous PendingIntent will be able to launch it with your new
 * extras even if they are not explicitly given to it.
 */
public static final int FLAG_UPDATE_CURRENT = 1<<27;

したがって、あなたのユース ケースでは、stackbuilder から 2 つの同一の pendingintent を作成し、2 番目の意図が最初の意図をオーバーライドします。実際には、最初のエクストラを更新するだけで、2番目を作成することはありません。

残念ながら、ユースケースに使用できるフラグはありませんが、それを回避するための優れたハックがあります。できることは、resultIntent の setAction を使用して、ランダムな文字列またはアプリにとって意味のある文字列を配置することです。

例えば。resultIntent.setAction("dummy_action_" + notification.id);

これにより、resultIntent が十分に一意になるため、pendingIntent は以前のものを更新するのではなく作成します。

于 2015-05-01T03:49:34.710 に答える
9

混在する複数のインテントを作成します。コードをクリーンアップしました (ただし、テストはしていません)

    NotificationManager nm = (NotificationManager) ctx
            .getSystemService(Context.NOTIFICATION_SERVICE);

    Resources res = ctx.getResources();

    // Creates an explicit intent for an Activity in your app
    Intent resultIntent = new Intent(this, ResultActivity.class);
    String pass = text.getText().toString();
    resultIntent.setData(new Uri.Builder().scheme("data")
            .appendQueryParameter("text", "my text").build());
    resultIntent.putExtra("title", pass);
    resultIntent.putExtra("uid", i);

    TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
    // Adds the back stack for the Intent (but not the Intent itself)
    stackBuilder.addParentStack(ResultActivity.class);
    // Adds the Intent that starts the Activity to the top of the stack
    stackBuilder.addNextIntent(resultIntent);
    PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0,
            PendingIntent.FLAG_UPDATE_CURRENT);

    NotificationCompat.Builder builder = new NotificationCompat.Builder(ctx);
    builder.setSmallIcon(R.drawable.ic_launcher)
            .setLargeIcon(
                    BitmapFactory.decodeResource(res,
                            R.drawable.ic_launcher))
            .setTicker("Remember to " + text.getText())
            .setWhen(System.currentTimeMillis()).setAutoCancel(true)
            .setContentTitle(text.getText())
            .setContentIntent(resultPendingIntent);

    Notification n = builder.build();
    n.flags = Notification.FLAG_NO_CLEAR;
    nm.notify(i++, n);

    text.setText(null);
于 2012-10-19T06:14:31.097 に答える