web-dev-qa-db-ja.com

Android Notification Actionsは通知ドロワーを閉じません

NotificationCompatライブラリを使用してシステムバーに通知を追加しています。この通知には2つのアクションボタンがあります。また、通知のAutoCancel()プロパティはtrueに設定されます。

アクションボタンをクリックすると、システムは、NotificationManager.cancel(NOTIFICATION_ID)を呼び出すIntentServiceを起動し、新しいタスクでアクティビティを起動するように構成されます。
問題は、この呼び出しがトレイから通知を削除しても、引き出しが折りたたまれないことです。呼び出されたアクティビティが引き出しの後ろに描画されます。

通知をキャンセルする以外に、ドローを閉じるために必要な特別なコードを誰かが明らかにしてください。

46
Aster

アクションがブロードキャストまたはサービスの形式であるが、通知ドロワーを折りたたむ場合は、ブロードキャストする必要があります Android.intent.action.CLOSE_SYSTEM_DIALOGS onReceiveから。これにより、引き出しが手動で閉じられます。

44
Andro Id

拡張された通知でアクションボタンを使用する場合、余分なコードを記述する必要があり、より制約を受けることがわかりました。

拡張通知を使用する前は、ファイルダウンロード通知のデフォルトのアクションは、ファイルでVIEWアクティビティを開始することでした。 VIEWインテントはChooserインテントによってラップされました。ファイルタイプを表示するアクティビティがない場合、セレクタはクラッシュするため、通知から直接セレクタのインテントに保留中のインテントを使用できませんでした。だから、Chooseインテントを開始するBroadcastReceiverがありました。

通知が拡張されたため、ファイルのダウンロード通知を変更して、デフォルトのアクションがファイルの詳細アクティビティを表示し、表示と送信のアクションボタンを表示するようにしました。 user2536953で述べたように、通知からブロードキャストレシーバーを開始しても、通知ドロワーは閉じられません。アクティビティによってドロワーが閉じられるという彼の情報に基づいて、UIなしでブロードキャストレシーバーをNotificationActivityに変更しました。

この投稿で示されているように、 アクションがクリックされた後の通知を閉じる方法Android通知 )、別の問題は、ユーザーがアクションボタンをクリックしたときに手動で通知をキャンセルする必要があることです通知はデフォルトのアクションに対してのみ自動的にキャンセルされますが、これを処理するためにNotificationActivityにコードも追加しました。

表示ボタンと送信ボタンを使用した拡張通知の作成:

    NotificationCompat.Builder builder = new NotificationCompat.Builder(m_context).setAutoCancel(true);

    final PendingIntent contentIntent = DownloadedFileIntentUtils.buildPendingItemDetailIntent(m_context, item);
        builder.setContentIntent(contentIntent);

    PendingIntent viewIntent = DownloadedFileIntentUtils.buildNotificationActionIntent(m_context, Intent.ACTION_VIEW,
                m_context.getString(R.string.action_open), uri, MimeTypeUtil.getMimeType(item), id);
    builder.addAction(R.drawable.actionbar_open_with, m_context.getString(R.string.action_open), viewIntent);

    PendingIntent sendIntent = DownloadedFileIntentUtils.buildNotificationActionIntent(m_context, Intent.ACTION_SEND,
                m_context.getString(R.string.action_send), uri, MimeTypeUtil.getMimeType(item), id);
    builder.addAction(R.drawable.actionbar_share, m_context.getString(R.string.action_send), sendIntent);

    builder.setTicker(title)
    .setContentTitle(title)
    .setContentText(text)
    .setSmallIcon(R.drawable.notification_download);
    .setStyle(new NotificationCompat.BigTextStyle().bigText(text));

    getNotificationManager().notify(id, builder.build());

通知アクションボタンからアクティビティを開始する意図の構築:

    public static PendingIntent buildNotificationActionIntent(Context context, String action, String actionTitle, Uri uri,
        String mimeType, int notificationId) {
    // Build the file action intent (e.g. VIEW or SEND) that we eventually want to start.
    final Intent fileIntent = buildFileActionIntent(action, actionTitle, uri, mimeType);

    // Build the intent to start the NotificationActivity.
    final Intent notificationIntent = new Intent(context, NotificationActivity.class);
    // This flag must be set on activities started from a notification.
    notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    // Pass the file action and notification id to the NotificationActivity.
    notificationIntent.putExtra(Intent.EXTRA_INTENT, fileIntent);
    notificationIntent.putExtra(IIntentCode.INTENT_EXTRA_NOTIFICATION_ID, notificationId);

    // Return a pending intent to pass to the notification manager.
    return PendingIntent.getActivity(context, s_intentCode.getAndIncrement(), notificationIntent, PendingIntent.FLAG_ONE_SHOT);
}

public static Intent buildFileActionIntent(String action, String actionTitle, 
        Uri uri, String mimeType) {
    Intent intent = new Intent(action);
    intent.addCategory(Intent.CATEGORY_DEFAULT);

    if (action.equals(Intent.ACTION_SEND)) {
        intent.putExtra(Intent.EXTRA_STREAM, uri);
        intent.setType(mimeType);
    } else {
        intent.setDataAndType(uri, mimeType);
    }

    intent.putExtra(Intent.EXTRA_TITLE, actionTitle);

    // Grant read permission on the file to other apps without declared permission.
    int flags = Intent.FLAG_GRANT_READ_URI_PERMISSION;
    intent.setFlags(flags);

    return intent;
}

UIなしの通知アクティビティ:

public class NotificationActivity extends Activity {
private final static Logger s_logger = LogUtil.getLogger(NotificationActivity.class);

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    Intent intent = getIntent();

    // Cancel the notification that initiated this activity.
    // This is required when using the action buttons in expanded notifications.
    // While the default action automatically closes the notification, the
    // actions initiated by buttons do not.
    int notificationId = intent.getIntExtra(IIntentCode.INTENT_EXTRA_NOTIFICATION_ID, -1);
    if (notificationId != -1) {
        NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        manager.cancel(notificationId);
    }

    // If there is an activity to handle the action, start the file action.
    if (DownloadedFileIntentUtils.verifyActivityIsAvailable(this, fileActionIntent, false)) {
            fileActionIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            DownloadedFileIntentUtils.startFileActionActivity(this, fileActionIntent);
    }

    // Finish activity.
    finish();
}

public static void startFileActionActivity(Context context, Intent fileActionIntent) {
    // Start chooser intent.
    Intent chooser = Intent.createChooser(fileActionIntent, fileActionIntent.getStringExtra(Intent.EXTRA_TITLE));

    // Copy the flags from fileActionIntent to chooser intent.
    // FileActionExecutor must set FLAG_ACTIVITY_NEW_TASK on the intent passed to startActivity
    // because the flag is required when starting an activity from a context that is not an activity.
    chooser.addFlags(fileActionIntent.getFlags());

    context.startActivity(chooser);
}

NotificationActivityをAndroidManifest.xmlに追加することを忘れないでください。

9
Vicki

Soumyajyotiの答えは正しいはずであることに完全に感謝していますが、実際はそうではありません...

私は使っている

Intent CR = new Intent(CRCODE); 
PendingIntent.getBroadcast(getApplicationContext(), MY_ID, CR, 0);

継続的な通知のためのリモートビューレイアウトで...

引き出しを閉じず、意図を起動し、開いた引き出しの背後にアクティビティを描画し、受信機に割り当てた他のタスクを実行することを保証できます...

私はgetActivityとgetServiceの両方をテストしました(どちらも私の環境では機能せず、Recieveで複数のインテントを起動する必要があります)。両方ともドロワーを適切に閉じます...

私はこれが答えではないことを知っていますが、それを見つけた場合は編集して報告します...

クレイジーな考え...コンテンツビューのないアクティビティは、必要に応じて他のクラスまたはアプリに適切なインテントを送信するブロードキャストレシーバーとして呼び出される可能性があります...

上記のクレイジーな考えは機能します... PendingIntent.getActivityでアクティビティを開始し、それを使用してブロードキャストまたは他のインテントを中継し、それ自体を終了します...効果は直接ではなく、エンドユーザーには認識されません

1
me_

これを試して:

    NotificationManager notificationManager = (NotificationManager) getApplicationContext().getSystemService(getApplicationContext().NOTIFICATION_SERVICE);
    Intent notificationIntent = new Intent(this.getBaseContext(), MainActivity.class);
    notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    NotificationCompat.Builder mNotifyBuilder = (NotificationCompat.Builder) new NotificationCompat.Builder(
            getApplicationContext())
            .setTicker(getApplicationContext().getText(R.string.app_name))
            .setContentTitle(getApplicationContext().getText(R.string.app_name))
            .setContentText(getApplicationContext().getText(R.string.text))
            .setSmallIcon(R.drawable.smallicon)
            .setLargeIcon(BitmapFactory.decodeResource(getApplicationContext().getResources(), R.mipmap.ic_launcher))
            .setContentIntent(pendingIntent)
            .setAutoCancel(true)
            .setVibrate(new long[]{150, 300});
    mNotifyBuilder.build().flags |= Notification.FLAG_AUTO_CANCEL;
    notificationManager.notify(1, mNotifyBuilder.build());
0

Androidシステムは、通知をクリックしてアクティビティまたはブロードキャストを起動するたびに、通知ドロワーを折りたたみます。コードによって通知ドロワーを閉じるプログラム的な方法はないと思います。通知ビルダーに渡すインテントを確認し、正しい参照インテントが与えられていることを確認することをお勧めします。Android通知マネージャーは、インテントによってブロックされていると思いますこれまでのところ、通知からアクションがトリガーされた後、通知ドロワーが開いたままになっているのを見たことはありません。ターゲットアクティビティに、前のアクティビティが表示される半透明の領域があるかどうかを知りたい場合は、背景は完全に不透明です(透明/半透明の領域はありません)。これはAndroidホームランチャーが停止シーケンスを完了するのを妨げているため、ランチャーが通知ドロワーを閉じないようにしている可能性があります。 。お役に立てば幸いです。ではごきげんよう。

0