最近プロジェクトに取り組んでいたときに、プラスとマイナスのボタンと番号で通知を送信するという要件が発生しました。ボタンをクリックした後、それに応じて通知の番号を変更する必要があります。
シンプルに聞こえますが、2つのボタンにクリックイベントを追加するだけで十分ではないでしょうか。ただし、通知はアプリプロセスに属していませんが、Androidシステムによって維持されているプロセスです。通知のカスタムレイアウトは、を介してRemoteViews
実装する必要があります。
RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.layout_number);
NotificationCompat.Builder.setContent(remoteViews);
RemoteViews
プロセス間表示のレイアウトスキームを処理するために使用されます。通常、通知やデスクトップウィジェットに使用されます。プロセスが異なるためRemoteViews
、適用されたレイアウトはfindViewById()
、コントロールを見つけるために直接使用することはできません。更新するいくつかのメソッドをカプセル化します。UI
次に例を示します。
void setTextViewText(int viewId, CharSequence text);
void setViewVisibility(int viewId, int visibility);
void setProgressBar(int viewId, int max, int progress, boolean indeterminate);
void setImageViewResource(int viewId, int srcId);
その他のメソッドについては、公式APIドキュメント を参照してください。
クリックイベントをコントロールに直接追加するメソッドは提供されていません。それで私はジレンマに出会いました。
それでは、通知全体のレイアウトをカスタムコントロールとして直接記述し、カスタムコントロールのボタンのクリックを実現できますか?残念ながら、それは不可能です通知を送信すると、次のエラーが直接報告されます:
android.app.RemoteServiceException: Bad notification posted from package
com.example.xujiafeng.notificationrefresh
クリックイベントをこのように簡単RemoteViews
に設定できてしまうと、コントロールにクリックイベントを設定する方法がわからなくなります。
それで、他に何がありますか?
RemoteViews
コントロールのクリックイベントを直接設定するメソッドはありませんが、次のメソッドが提供されています。
void setOnClickPendingIntent (int viewId, PendingIntent pendingIntent)
この方法の公式文書の説明は、次のとおりです。呼び出しに相当
setOnClickListener(android.view.View.OnClickListener)
提供を開始しますPendingIntent
。
そしてPendingIntent
遅延されIntent
、それが内部に含まれているIntent
、一定の条件が満たされたとき、彼は起動しませんIntent
、それは、オブジェクトを取得するための4つの方法があります。
getActivity(Context, int, Intent, int);
getActivities(Context, int, Intent[], int);
getBroadcast(Context, int, Intent, int);
getService(Context, int, Intent, int);
メソッド名が理解できるからで、Intent
時間が開始され、それが開始されますActivity
、ブロードキャストを送信するサービスを開始します。
したがってRemoteViews
、ボタンをクリックして後で開始するように実装する場合Activity
、コードは次のようになります。
Intent intent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 21, intent, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.iv_add, pendingIntent);
では、前の質問に戻り、ボタンをクリックして通知の番号の変更を実現するにはどうすればよいでしょうか。
この方法では、ボタンを制御してブロードキャストを送信します。その後、アプリはブロードキャストを監視し、ブロードキャストを受信した後で同じid
通知を再送信します。新しい通知によって番号が変更されます。これは特定のアイデアであり、以下は特定のコード実装です。
通知を送信するコード:
private void sendNotification()
{
RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.layout_number);
Intent addIntent = new Intent();
addIntent.setAction("com.example.xujiafeng.notificationrefresh.add");
remoteViews.setOnClickPendingIntent(R.id.iv_add, PendingIntent.getBroadcast(MainActivity.this, 10, addIntent, PendingIntent.FLAG_UPDATE_CURRENT));
Intent minusIntent = new Intent();
addIntent.setAction("com.example.xujiafeng.notificationrefresh.minus");
remoteViews.setOnClickPendingIntent(R.id.iv_add, PendingIntent.getBroadcast(MainActivity.this, 10, minusIntent, PendingIntent.FLAG_UPDATE_CURRENT));
remoteViews.setTextViewText(R.id.tv_value, String.valueOf(value));
notification = new NotificationCompat.Builder(MainActivity.this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("ContentTitle")
.setContentText("ContentText")
.setWhen(System.currentTimeMillis())
.setTicker("Ticker")
.setContent(remoteViews)
.build();
mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(12, notification);
}
放送受信機:
public class NotificationReceiver extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent)
{
String action = intent.getAction();
switch (action)
{
case "com.example.xujiafeng.notificationrefresh.add":
value++;
sendNotification();
break;
case "com.example.xujiafeng.notificationrefresh.minus":
value--;
sendNotification();
break;
}
}
}
ブロードキャストに登録:
IntentFilter filter = new IntentFilter();
filter.addAction(ADD_ACTION);
filter.addAction(MINUS_ACTION);
mReceiver = new NotificationReceiver();
registerReceiver(mReceiver, filter);
これが完了すると、実行効果は次のようになります。