'2018/08/24'에 해당되는 글 1건

728x90

안드로이드 Notification Helper 자료를 검색하고 내용을 보강하고 적어둔다.

안드로이드 8.0 이상(targetSdkVersion 26 이상)에서도 동작되는 코드다.

Noti 메시지를 띄우는createNotification(String title, String message) 과 클릭하면 cancelNotification(Context ctx, int notifyId) 되는 걸 테스트했다.

핵심은 NotificationHelper Class 만드는 것이고 나머지는 간단하게 사용해본 것이다.


 public class NotificationHelper {
    private Context mContext;
    private NotificationManager notificationManager;
    public static final String NOTIFICATION_CHANNEL_ID = "10001";

    public NotificationHelper(Context context) {
        mContext = context;
    }

    /**
     * Create and push the notification
     */
    public void createNotification(String title, String message) {
        Intent resultIntent = new Intent(mContext , ShowNotification.class);
        resultIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);

        PendingIntent resultPendingIntent = PendingIntent.getActivity(mContext,
                0 /* Request code */, resultIntent,
                PendingIntent.FLAG_UPDATE_CURRENT);

        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(mContext,NOTIFICATION_CHANNEL_ID);
        mBuilder.setSmallIcon(R.mipmap.ic_launcher);
        mBuilder.setContentTitle(title)
                .setContentText(message)
                .setAutoCancel(false) //클릭하게 되면 사라지도록...
                .setSound(Settings.System.DEFAULT_NOTIFICATION_URI)
                .setVibrate(new long[] { 1000, 1000, 1000 }) //노티가 등록될 때 진동 패턴
                .setContentIntent(resultPendingIntent);

        notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);

        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O){ // 8.0 이상
            int importance = NotificationManager.IMPORTANCE_HIGH;
            String channelName = "NOTIFICATION_CHANNEL_NAME";
            NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, importance);
            notificationChannel.enableLights(true);
            notificationChannel.setLightColor(Color.RED);
            notificationChannel.enableVibration(true);
            notificationChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
            assert notificationManager != null;
            mBuilder.setChannelId(NOTIFICATION_CHANNEL_ID);
            notificationManager.createNotificationChannel(notificationChannel);
        }
        assert notificationManager != null;
        notificationManager.notify(0 /* Request Code */, mBuilder.build());
    }

    public void callSettingNotification(){
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
            Intent intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS);
            intent.putExtra(Settings.EXTRA_APP_PACKAGE,mContext.getPackageName());
            intent.putExtra(Settings.EXTRA_CHANNEL_ID,NOTIFICATION_CHANNEL_ID);
            mContext.startActivity(intent);
        }
    }

    public void cancelNotification(Context ctx, int notifyId) {
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O){
            NotificationManager mNotificationManager =
                    (NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE);
            mNotificationManager.deleteNotificationChannel(NOTIFICATION_CHANNEL_ID);
        } else {
            NotificationManager notificationManager = (NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE);
            notificationManager.cancel(notifyId);
        }
    }
}


테스트에 사용한 파일을 첨부

notificationmanager.zip


PendingIntent

PendingIntent는 Intent를 포함하는 인텐트로, 목적은 본인 앱이 아닌 외부 앱(Notification, Alarm 등)에게 권한을 줘서 본인 앱을 실행할 수 있도록 허락하는 것이다.


A PendingIntent is a token that you give to a foreign application (e.g. NotificationManager, AlarmManager, Home Screen AppWidgetManager, or other 3rd party applications), which allows the foreign application to use your application's permissions to execute a predefined piece of code.


pending : 미결의, ~를 기다리는 동안


Intent의 기본 개념은 특정 컴포넌트(Activity, Service, Broadcast Receiver, Content Provider)를 실행시키는 메시지라는 것이다.

Intent intent = new Intent(MainActivity.this, NewActivity.class);

startActivity(intent);

그런데 PendingIntent는 생성자가 없고 다음 세 개의 메소드들에 의해서 객체가 생성된다.
ㆍgetActivity(Context, int, Intent, int)
ㆍgetBroadcast(Context, int, Intent, int)
ㆍgetService(Context, int, Intent, int)

- 액티비티를 시작할 인텐트를 생성하기 위해선 PendingIntent.getActivity()를 사용한다.
- 서비스를 시작할 인텐트를 생성하기 위해서는 PendingIntent.getService()를 사용한다.
- BroadcastReceiver를 시작할 인텐트를 생성하기 위해서는 PendingIntent.getBroadcast()를 사용한다.


Intent intent = new Intent(context, MainActivity.class);
PendingIntent pendIntent = PendingIntent.getActivity(context, 0 , intent, PendingIntent.FLAG_UPDATE_CURRENT);

- 정상적인 Activity lifecycle을 태우기 위해선, PendingIntent 생성시 requestCode를 반드시 넣어야한다.(대부분 default값으로 0을 넣는다)

- FLAG_CANCEL_CURRENT : 이전에 생성한 PendingIntent는 취소하고 새로 만든다.
- FLAG_IMMUTABLE : 생성된 PendingIntent 는 수정 불가능하도록 한다.
- FLAG_NO_CREATE : 생성된 PendingIntent 를 반환한다.(재사용 가능), 이미 생성된 PendingIntent가 없다면 null를 return 한다.
- FLAG_ONE_SHOT : 해당 Flag로 생성한 PendingIntent 는 일회성이다.
- FLAG_UPDATE_CURRENT : 이미 생성된 PendingIntent가 존재하면 해당 Intent의 Extra Data만 변경한다.


알람 확인 및 취소 게시글 : https://migom.tistory.com/10





참고사이트

https://medium.com/cr8resume/notification-in-android-8-0-oreo-implementing-notification-channels-d65b0f81ca50


https://www.androidauthority.com/android-8-0-oreo-app-implementing-notification-channels-801097/


http://gun0912.tistory.com/77

블로그 이미지

Link2Me

,