Android의 알림이 삭제되었음을 감지합니다.

소개



안드로이드 알림을 탭하면 액티비티가 시작된다는 것은 자주 보이지만, 그 반대의 "알림이 지워진 것을 감지하고 어떠한 액션을 한다"는 것은 별로 보이지 않는다고 생각했기 때문에 조사 시도했습니다.

아무래도 NotificationCompat#setDeleteIntent()라는 메소드와 BroadcastReceiver를 사용하면 실현할 수 있을 것이라는 것을 알았기 때문에 정리합니다.

이번에는 샘플로 버튼을 누르면 알림이 표시됩니다.
  • 알림을 탭하면 "알림이 탭되었습니다"라는 Toast가 표시됩니다.
  • 알림을 스 와이프하여 삭제 (또는 모두 지우기)하면 "통지가 삭제되었습니다"라는 Toast가 표시됩니다.

    라는 간단한 앱을 사용하여 설명합니다.

    구현



    구현의 거친 흐름으로서는
  • 통지를 조립할 때 NotificationCompat # setDeleteIntent ()를 호출하고 통지 삭제시의 거동을 설정한다.
  • 삭제시의 거동에 PendingIntent#getBroadcast()를 지정해,BroadcastReceiver가 받을 수 있도록 action를 설정한다.
  • 삭제시에 던져진 PendingIntent를 BroadcastReceiver로 받아, action에 따른 처리를 실시한다.

  • 됩니다.

    아래가 주요 부분의 소스입니다.

    MainActivity.java
    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            findViewById(R.id.buttonBroadcast).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    showNotificationWithBroadcast();
                }
            });
    
        private void showNotificationWithBroadcast() {
            NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
            Notification notification = builder
                    .setWhen(System.currentTimeMillis())
                    .setAutoCancel(true)
                    .setSmallIcon(R.mipmap.ic_launcher)
                    .setContentTitle("Notification Title")
                    .setContentText("Notification Text")
                    .setContentIntent( //通知タップ時のPendingIntent
                            getPendingIntentWithBroadcast(NotificationReceiver.CLICK_NOTIFICATION)
                    )
                    .setDeleteIntent(  //通知の削除時のPendingIntent
                            getPendingIntentWithBroadcast(NotificationReceiver.DELETE_NOTIFICATION)
                    )
                    .build();
    
            ((NotificationManager) getSystemService(NOTIFICATION_SERVICE)).notify(0, notification);
        }
    
        private PendingIntent getPendingIntentWithBroadcast(String action) {
            return PendingIntent.getBroadcast(getApplicationContext(), 0 , new Intent(action), 0);
        }
    

    이 샘플에서는 action을 switch문으로 분기시키고 있습니다만, 픽업하고 싶은 것이 삭제 이벤트만으로 좋은 경우는 아래와 같이 써도 좋다고 생각합니다.
    String action = intent.getAction();
    if (action.equals(DELETE_NOTIFICATION)) {
        //do something
    }
    
    

    또한 나중에 설명하지만 AndroidManifest.xml에 정의를 추가하는 것을 잊지 않도록하십시오.

    NotificationReceiver.java
    public class NotificationReceiver extends BroadcastReceiver{
    
        //MainActivity側からも参照されるのでpublic
        public static final String CLICK_NOTIFICATION = "click_notification";
        public static final String DELETE_NOTIFICATION = "delete_notification";
    
        @Override
        public void onReceive(Context context, Intent intent) {
    
            String action = intent.getAction();
    
            switch (action) {
                case CLICK_NOTIFICATION:
                    //通知タップ時のイベントを書く
                    Toast.makeText(context, "通知がタップされました", Toast.LENGTH_SHORT).show();
                    break;
    
                case DELETE_NOTIFICATION:
                    //通知削除時のイベントを書く
                    Toast.makeText(context, "通知が削除されました", Toast.LENGTH_SHORT).show();
                    break;
    
                default:
                    break;
            }
        }
    }
    

    receiver를 추기해, intent-filter에 정의한 action을 정의해 두지 않으면 걸어 주지 않습니다.

    AndroidManifest.xml
    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.masaibar.notificationdeleteintentsample">
    
        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
            <activity android:name=".MainActivity">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
            <receiver android:name=".NotificationReceiver">
                <intent-filter>
                    <!--定義したactionを追記する-->
                    <action android:name="click_notification" />
                    <action android:name="delete_notification" />
                </intent-filter>
            </receiver>
        </application>
    
    </manifest>
    

    움직여 보자



    조금 알기 힘들지도 모릅니다만, 통지를 탭했을 때, 통지를 스와이프 해 지웠을 때에 각각 Toast가 표시되고 있습니다.




    Broadcast를 사용하지 않고, 자주 있는 통지 탭시와 같이 Activity의 기동이나 그 외 앱의 호출로 하는 것도 가능합니다.
    아래는 알림을 탭하면 Yahoo! JAPAN이 알림을 삭제하면 Qiita가 각각 브라우저에서 일어나는 알림입니다.
    샘플 앱에 추가 구현을 추가하고 있습니다.

    ※삭제했을 때에도 브라우저가 일어난다고 하는 사양은 어떠한가라고 생각합니다.

    MainActivity.java
        private void showNotificationWithIntent() {
            NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
            Notification notification = builder
                    .setWhen(System.currentTimeMillis())
                    .setContentTitle("Notification Title")
                    .setContentText("Notification Text")
                    .setContentIntent( //通知タップ時のPendingIntent タップされたらYahoo!をブラウザで表示
                            getPendingIntent("http://www.yahoo.co.jp")
                    )
                    .setDeleteIntent(  //通知の削除時のPendingIntent 削除されたらQiitaをブラウザで表示
                            getPendingIntent("http://qiita.com")
                    )
                    .setAutoCancel(true)
                    .setSmallIcon(R.mipmap.ic_launcher)
                    .build();
    
            ((NotificationManager) getSystemService(NOTIFICATION_SERVICE)).notify(0, notification);
        }
    
        private PendingIntent getPendingIntent(String url) {
            Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
            return PendingIntent.getActivity(getApplicationContext(), 0, intent, 0);
        }
    



    결론



    알림 삭제를 트리거로 하고 뭔가를 하고 있는 앱을 별로 모르겠지만, 원래 알림을 삭제하고 있음에도 불구하고 전면에 나오는 것은 이상하다고 생각했습니다. 지분 은행 앱, 너의 일이야.
    반대로, 「통지가 지워졌다」라고 하는 로그를 뒤편에서 송신하는 등 유저에게 인지되지 않는 부분으로 할 수 있는 구현의 가능성은 느꼈습니다.

    이번 소스는 아래와 같습니다.
    htps : // 기주 b. 코 m / 마사이바 r / 노치 후 카치 온테 텐텐 츠 mp ぇ

    참고



    android - How to use Notification.deleteIntent - Stack Overflow

    좋은 웹페이지 즐겨찾기