Android에서 포 그라운드 서비스의 알림 텍스트를 어떻게 업데이트합니까? @Override

Android에서 포 그라운드 서비스 설정이 있습니다. 알림 텍스트를 업데이트하고 싶습니다. 아래와 같이 서비스를 만들고 있습니다.

이 포 그라운드 서비스 내에 설정된 알림 텍스트를 어떻게 업데이트합니까? 알림을 업데이트하는 가장 좋은 방법은 무엇입니까? 모든 샘플 코드를 주시면 감사하겠습니다.

public class NotificationService extends Service {

    private static final int ONGOING_NOTIFICATION = 1;

    private Notification notification;

    @Override
    public void onCreate() {
        super.onCreate();

        this.notification = new Notification(R.drawable.statusbar, getText(R.string.app_name), System.currentTimeMillis());
        Intent notificationIntent = new Intent(this, AbList.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
        this.notification.setLatestEventInfo(this, getText(R.string.app_name), "Update This Text", pendingIntent);

        startForeground(ONGOING_NOTIFICATION, this.notification);

    }

아래와 같이 주요 활동에서 서비스를 만들고 있습니다.

    // Start Notification Service
    Intent serviceIntent = new Intent(this, NotificationService.class);
    startService(serviceIntent);


답변

이 시나리오를 시도하지는 않았지만 startForeground()동일한 고유 ID와 Notification새 정보를 사용하여 다시 호출하면 효과가 있다고 생각합니다 .

업데이트 : 주석에 따라 NotifcationManager를 사용하여 알림을 업데이트해야하며 서비스는 계속 포 그라운드 모드로 유지됩니다. 아래 답변을보십시오.


답변

startForeground ()로 설정된 알림을 업데이트하려면 새 알림을 작성한 다음 NotificationManager를 사용하여 알림을 보내십시오.

핵심은 동일한 알림 ID를 사용하는 것입니다.

알림을 업데이트하기 위해 startForeground ()를 반복적으로 호출하는 시나리오를 테스트하지는 않았지만 NotificationManager.notify를 사용하는 것이 더 좋을 것이라고 생각합니다.

알림을 업데이트해도 포 그라운드 상태에서 서비스가 제거되지는 않습니다 (stopForground 호출로만 수행 할 수 있음).

예:

private static final int NOTIF_ID=1;

@Override
public void onCreate (){
    this.startForeground();
}

private void startForeground() {
    startForeground(NOTIF_ID, getMyActivityNotification(""));
}

private Notification getMyActivityNotification(String text){
    // The PendingIntent to launch our activity if the user selects
    // this notification
    CharSequence title = getText(R.string.title_activity);
    PendingIntent contentIntent = PendingIntent.getActivity(this,
            0, new Intent(this, MyActivity.class), 0);

    return new Notification.Builder(this)
            .setContentTitle(title)
            .setContentText(text)
            .setSmallIcon(R.drawable.ic_launcher_b3)
            .setContentIntent(contentIntent).getNotification();
}

/**
 * This is the method that can be called to update the Notification
 */
private void updateNotification() {
    String text = "Some text that will update the notification";

    Notification notification = getMyActivityNotification(text);

    NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    mNotificationManager.notify(NOTIF_ID, notification);
}

문서의 상태

업데이트 할 수 있도록 알림을 설정하려면을 호출하여 알림 ID로 알림을 발행하십시오 NotificationManager.notify(). 이 알림을 발행 한 후 업데이트하려면, NotificationCompat.Builder오브젝트를 업데이트 또는 작성하고,
오브젝트를 빌드하고 Notification, Notification이전에 사용한 것과 동일한 ID로 발행하십시오 . 이전 알림이 여전히 표시되면 시스템은 Notification객체 의 내용에서 알림을 업데이트 합니다. 이전 알림이 해제 된 경우 대신 새 알림이 작성됩니다.


답변

알림을 업데이트 할 때 안드로이드 8.0 이상에서 Luca Manzo 답변을 개선하면 소리가 나고 헤드 업으로 표시됩니다.
추가해야하는 것을 방지하기 위해setOnlyAlertOnce(true)

코드는 다음과 같습니다.

private static final int NOTIF_ID=1;

@Override
public void onCreate(){
        this.startForeground();
}

private void startForeground(){
        startForeground(NOTIF_ID,getMyActivityNotification(""));
}

private Notification getMyActivityNotification(String text){
        if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){
        ((NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE)).createNotificationChannel(
        NotificationChannel("timer_notification","Timer Notification",NotificationManager.IMPORTANCE_HIGH))
}

        // The PendingIntent to launch our activity if the user selects
        // this notification
        PendingIntent contentIntent=PendingIntent.getActivity(this,
        0,new Intent(this,MyActivity.class),0);

        return new NotificationCompat.Builder(this,"my_channel_01")
        .setContentTitle("some title")
        .setContentText(text)
        .setOnlyAlertOnce(true) // so when data is updated don't make sound and alert in android 8.0+
        .setOngoing(true)
        .setSmallIcon(R.drawable.ic_launcher_b3)
        .setContentIntent(contentIntent)
        .build();
}

/**
 * This is the method that can be called to update the Notification
 */
private void updateNotification(){
        String text="Some text that will update the notification";

        Notification notification=getMyActivityNotification(text);

        NotificationManager mNotificationManager=(NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
        mNotificationManager.notify(NOTIF_ID,notification);
}

답변

서비스에서 수행하는 코드 는 다음과 같습니다 . 새 알림을 작성하지만 startForeground에서 사용한 것과 동일한 알림 ID를 알림 관리자에게 요청하십시오.

Notification notify = createNotification();
final NotificationManager notificationManager = (NotificationManager) getApplicationContext()
    .getSystemService(getApplicationContext().NOTIFICATION_SERVICE);

notificationManager.notify(ONGOING_NOTIFICATION, notify);

전체 샘플 코드는 여기에서 확인할 수 있습니다.

https://github.com/plateaukao/AutoScreenOnOff/blob/master/src/com/danielkao/autoscreenonoff/SensorMonitorService.java


답변

기존 답변 중 전체 사례를 처리하는 방법을 보여주지 않는 것 같습니다. 첫 번째 통화 인 경우 startForeground를 시작하고 후속 통화에 대한 알림을 업데이트하십시오.

다음 패턴을 사용하여 올바른 사례를 감지 할 수 있습니다.

private void notify(@NonNull String action) {
    boolean isForegroundNotificationVisible = false;
    NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    StatusBarNotification[] notifications = notificationManager.getActiveNotifications();
    for (StatusBarNotification notification : notifications) {
        if (notification.getId() == FOREGROUND_NOTE_ID) {
            isForegroundNotificationVisible = true;
            break;
        }
    }
    Log.v(getClass().getSimpleName(), "Is foreground visible: " + isForegroundNotificationVisible);
    if (isForegroundNotificationVisible){
        notificationManager.notify(FOREGROUND_NOTE_ID, buildForegroundNotification(action));
    } else {
        startForeground(FOREGROUND_NOTE_ID, buildForegroundNotification(action));
    }
}

또한 다른 답변과 같이 알림 및 채널을 작성해야합니다.

private Notification buildForegroundNotification(@NonNull String action) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        createNotificationChannel();
    }
    //Do any customization you want here
    String title;
    if (ACTION_STOP.equals(action)) {
        title = getString(R.string.fg_notitifcation_title_stopping);
    } else {
        title = getString(R.string.fg_notitifcation_title_starting);
    }
    //then build the notification
    return new NotificationCompat.Builder(this, CHANNEL_ID)
            .setSmallIcon(R.mipmap.ic_launcher)
            .setContentTitle(title)
            .setOngoing(true)
            .build();
}

@RequiresApi(Build.VERSION_CODES.O)
private void createNotificationChannel(){
    NotificationChannel chan = new NotificationChannel(CHANNEL_ID, getString(R.string.fg_notification_channel), NotificationManager.IMPORTANCE_DEFAULT);
    chan.setLightColor(Color.RED);
    chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
    NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    assert manager != null;
    manager.createNotificationChannel(chan);
}