마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

notification 터치로 지우기

0 추천

알림이 왔을 때 그 알림을 터지하면 지우는 것을 하고 싶습니다

setAutoCancel(true)를 하면 터치 했을때 지워진다고 들었는데 지워지지 않습니다.

어떻게 해야하나요..?

private void show1() {
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "default");
        builder.setSmallIcon(R.drawable.push1);
        builder.setContentTitle("배달통에 음식이 도착했어요");
        builder.setContentText("확인하기");

        Uri ringtoneUri = RingtoneManager.getActualDefaultRingtoneUri(this,
                RingtoneManager.TYPE_NOTIFICATION);

        builder.setSound(ringtoneUri);

        long[] vibrate = {0, 100, 200, 300};
        builder.setVibrate(vibrate);
        builder.setAutoCancel(true);

        NotificationManager manager = (NotificationManager) getSystemService((NOTIFICATION_SERVICE));
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            manager.createNotificationChannel(new NotificationChannel("default", "기본채널",
                    NotificationManager.IMPORTANCE_DEFAULT));
        }
        manager.notify(2, builder.build());

        photo1.clear();
        photo1.put("current","0");
        db.collection("photo").document("picture")
                .set(photo1)
                .addOnSuccessListener(new OnSuccessListener<Void>() {
                    @Override
                    public void onSuccess(Void unused) {
                    }
                })
                .addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                    }
                });
    }

 

 

 

개미1 (1,260 포인트) 님이 2021년 11월 27일 질문

1개의 답변

0 추천

원인은 PendingIntent가 설정이 안되었기 때문인데요. 하시려고 하는 게 PendingIntent 없이도 Notification 을 탭하면 Notification이 없어지는거니까, 두가지를 만족하기 위해서 빈껍데기 뿐인 PendingIntent를 하나 만들어 줍니다.

Notification처리를 할 수 있는 간단한 유틸리티 클래스들을 만들어 봤습니다. 님이 원하는 자동 취소가 기본으로 들어가 있습니다.

import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

import androidx.core.app.TaskStackBuilder;

public class NoOpBroadcastReceiver extends BroadcastReceiver {

    public static PendingIntent getPendingIntent(Context context) {
        TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
        stackBuilder.addNextIntent(new Intent(context, NoOpBroadcastReceiver.class));
        return stackBuilder.getPendingIntent(
                0,
                PendingIntent.FLAG_UPDATE_CURRENT
        );
    }

    @Override
    public void onReceive(Context context, Intent intent) {
    }
}

NoOpBroadCastReceiver는 아무 것도 안하는 빈껍데기만 있는 클래스입니다.  Notification이 PendingIntent가 있어야 눌렀을 때 사라질 수 있기 때문에 필요합니다.

 

import static android.content.Context.NOTIFICATION_SERVICE;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build;

import androidx.core.app.NotificationCompat;


public class NotificationBuilder {

    private static final String CHANNEL_ID = "default";
    private static final String CHANNEL_NAME = "기본채널";
    private static final long[] DEFAULT_VIBRATE = {0, 100, 200, 300};
    private static final int NOTIFICATION_ID = 2;

    private String channelId = CHANNEL_ID;
    private String channelName = CHANNEL_NAME;
    private int notificationId = NOTIFICATION_ID;
    private Uri ringtoneUri;
    private long[] vibrationPattern = DEFAULT_VIBRATE;
    private PendingIntent pendingIntent;
    private String title;
    private String message;
    private boolean autoCancel = true; // 자동 취소를 기본 설정으로 함.

    private final Context context;

    public NotificationBuilder(Context context) {
        this.context = context;
        this.ringtoneUri = getDefaultRingtoneUri();
        this.pendingIntent = NoOpBroadcastReceiver.getPendingIntent(context);
        this.title = context.getString(R.string.app_name); // 기본값은 님이 원하는대로 설정
        this.message = context.getString(R.string.app_name); // 기본값은 님이 원하는대로 설정
    } 

    public NotificationBuilder setChannelId(String channelId) {
        this.channelId = channelId;
        return this;
    }

    public NotificationBuilder setChannelName(String channelName) {
        this.channelName = channelName;
        return this;
    }

    public NotificationBuilder setRingtoneUri(Uri ringtoneUri) {
        this.ringtoneUri = ringtoneUri;
        return this;
    }

    public NotificationBuilder setVibrationPattern(long[] vibrationPattern) {
        this.vibrationPattern = vibrationPattern;
        return this;
    }

    public NotificationBuilder setPendingIntent(PendingIntent pendingIntent) {
        this.pendingIntent = pendingIntent;
        return this;
    }

    public NotificationBuilder setTitle(String title) {
        this.title = title;
        return this;
    }

    public NotificationBuilder setMessage(String message) {
        this.message = message;
        return this;
    }

    public NotificationBuilder setNotificationId(int notificationId) {
        this.notificationId = notificationId;
        return this;
    }

    public NotificationBuilder setAutoCancel(boolean autoCancel) {
        this.autoCancel = autoCancel;
        return this;
    }

    public Notification build() {
        final NotificationCompat.Builder builder = new NotificationCompat.Builder(context, channelId);
        builder.setSmallIcon(R.drawable.ic_notifications_black_24dp)
                .setContentTitle(title)
                .setContentText(message)
                .setContentIntent(pendingIntent)
                .setSound(ringtoneUri)
                .setVibrate(vibrationPattern)
                .setAutoCancel(autoCancel);

        NotificationManager manager = getNotificationManager();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            manager.createNotificationChannel(new NotificationChannel(channelId, channelName,
                    NotificationManager.IMPORTANCE_DEFAULT));
        }

        Notification notification = builder.build();
        manager.notify(notificationId, notification);

        return notification;
    }

    private NotificationManager getNotificationManager() {
        return (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
    }

    private Uri getDefaultRingtoneUri() {
        return RingtoneManager.getActualDefaultRingtoneUri(context, RingtoneManager.TYPE_NOTIFICATION);
    }
}

NotificationBuilder는 NotficationCompat.Builder를 사용하기 편하게 감싼 클래스입니다. NotficationCompat.Builder를 액티비티에서 직접 사용하게 되면 불필요한 boiler plate코드를 작성하게 되므로 이것을 피하기 위해 만들었습니다.

import android.content.Context;

public class NotificationHelper {
    private final Context context;

    public NotificationHelper(Context context) {
        this.context = context;
    }

    public void notifyDeliveryArrival() {
        NotificationBuilder builder = new NotificationBuilder(context);
        builder.setTitle(context.getString(R.string.delivery_arrival_notification_title))
                .setMessage(context.getString(R.string.delivery_arrival_notification_message))
                .build();
    }
}

 

액비티티에서  위에서 만든 NotificationBuilder클래스를 사용한다고 해도 여전히 boiler plate코드가 생기기 때문에 용도에 맞는 Notification을 관리하는 클래스를 두는 게 좋습니다.

액티비티에서는 NotificationHelper클래스만 사용하면 됩니다.

public class MainActivity extends AppCompatActivity {

    private NotificationHelper notificationHelper;    

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

        notificationHelper = new NotificationHelper(this); //초기화
    }

   private void notifyDeliveryArrival() {
         notificationHelper.notifyDeliveryArrival();
   }
}

도움이 되시길...

spark (227,530 포인트) 님이 2021년 11월 28일 답변
spark님이 2021년 11월 28일 수정
...