Как использовать разные звуки на одном канале уведомлений для службы Android Foreground - PullRequest
0 голосов
/ 03 августа 2020

У меня есть служба переднего плана, в которой я настроил канал уведомлений, как требуется для Android API 26 и выше, но я не могу динамически устанавливать звук для этого уведомления. Позвольте мне объяснить:

Когда служба запускается, она создает начальное уведомление с помощью startForeground в соответствии с требованиями службы переднего плана. Я пытаюсь выполнить sh, так это повторно использовать это постоянное уведомление, которое уже находится в панели уведомлений, обновляя сообщение, чтобы обеспечить визуальное обновление статуса. Этого я уже могу достичь. В одном конкретном случае я хотел бы также обновить либо канал уведомления, либо канал уведомления, чтобы обеспечить новый звук уведомления и отобразить уведомление для пользователя. Уведомление всегда использует тот же звук, который был изначально установлен при первом запуске службы, и никогда не становится сразу видимым для пользователя, если не сдвинуть панель уведомлений вниз от верхней части экрана.

Кажется, что работает что я создаю отдельный канал уведомлений для этого случая, но тогда у меня есть два разных элемента уведомлений в трее. Другой способ, который, похоже, работает, показан на YouTube @ https://www.youtube.com/watch?v=3Je9ZEAAjfA, где автор использует NotificationManager.deleteNotificationChannel для удаления, затем NotificationManager.createNotificationChannel, однако они сказали, что ОС в конечном итоге удалит мое приложение, если я продолжу повторять создание канала уведомлений для предотвращения спама.

Есть ли способ повторно использовать исходный канал уведомлений, чтобы динамически изменить звук и сделать его видимым?

Я go на конечности и покажите решение, которое я выбрал. Метод createNotificationChannels вызывается во время onCreate, затем createNotification вызывается один раз в onStartCommand, чтобы удовлетворить 5-секундный предел для вызова startForeground. Затем при необходимости я вызываю createNotification, чтобы выбрать, какой из 3 различных каналов отображать, и установить содержимое заголовка / тела. Я бы предпочел динамически настраивать звук.

private int CHANNEL_NOTIFICATION_ID = 666;
public static final String TARGET_MESSAGING_GROUP_ID = "TargetMessagingGroupID";
public static final String TARGET_MESSAGING_GROUP_NAME = "Target Messaging Group";
public static final String WAITING_NEW_TARGET_CHANNEL_ID = "WaitingNewTargetChannelID";
public static final String WAITING_NEW_TARGET_CHANNEL_NAME = "Waiting for New Target Channel";
public static final String NAVIGATING_TO_TARGET_CHANNEL_ID = "NavigatingToTargetChannelID";
public static final String NAVIGATING_TO_TARGET_CHANNEL_NAME = "Navigating To Target Channel";
public static final String TARGET_ARRIVAL_CHANNEL_ID = "TargetArrivalChannelID";
public static final String TARGET_ARRIVAL_CHANNEL_NAME = "Target Arrival Channel";
    
// --------------------------------------------------------------------
// Method: createNotificationChannels
//
// Purpose: Called once at startup so we have the notification channels
//          ready to go when we need them
// --------------------------------------------------------------------
protected void createNotificationChannels()
{
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
    {
        // use the same audio attributes for each channel
        AudioAttributes audioAttributes = new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_NOTIFICATION).build();

        // configure the group
        NotificationChannelGroup targetMessagingGroup = new NotificationChannelGroup(TARGET_MESSAGING_GROUP_ID, TARGET_MESSAGING_GROUP_NAME);

        // configure the first channel
        Uri soundUri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + parentContext.getPackageName() + "/" + R.raw.elevatording);
        NotificationChannel waitingNewTargetChannel = new NotificationChannel(WAITING_NEW_TARGET_CHANNEL_ID, WAITING_NEW_TARGET_CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT);
        waitingNewTargetChannel.setDescription(WAITING_NEW_TARGET_CHANNEL_NAME);
        waitingNewTargetChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
        waitingNewTargetChannel.setSound(soundUri, audioAttributes); // This is IMPORTANT
        waitingNewTargetChannel.enableLights(true);
        waitingNewTargetChannel.setLightColor(Color.RED);
        waitingNewTargetChannel.enableVibration(false);
        waitingNewTargetChannel.setGroup(TARGET_MESSAGING_GROUP_ID);

        // configure the second channel
        soundUri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + parentContext.getPackageName() + "/" + R.raw.beep);
        NotificationChannel navigatingToTargetChannel = new NotificationChannel(NAVIGATING_TO_TARGET_CHANNEL_ID, NAVIGATING_TO_TARGET_CHANNEL_NAME, NotificationManager.IMPORTANCE_LOW);
        navigatingToTargetChannel.setDescription(NAVIGATING_TO_TARGET_CHANNEL_NAME);
        navigatingToTargetChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
        navigatingToTargetChannel.setSound(soundUri, audioAttributes);
        navigatingToTargetChannel.enableLights(false);
        navigatingToTargetChannel.setLightColor(Color.RED);
        navigatingToTargetChannel.enableVibration(false);
        navigatingToTargetChannel.setGroup(TARGET_MESSAGING_GROUP_ID);

        // configure the third channel
        soundUri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + parentContext.getPackageName() + "/" + R.raw.purge_siren_loud);
        NotificationChannel targetArrivalChannel = new NotificationChannel(TARGET_ARRIVAL_CHANNEL_ID, TARGET_ARRIVAL_CHANNEL_NAME, NotificationManager.IMPORTANCE_HIGH);
        targetArrivalChannel.setDescription(TARGET_ARRIVAL_CHANNEL_NAME);
        targetArrivalChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
        targetArrivalChannel.setSound(soundUri, audioAttributes); // This is IMPORTANT
        targetArrivalChannel.enableLights(true);
        targetArrivalChannel.setLightColor(Color.RED);
        targetArrivalChannel.enableVibration(true);
        targetArrivalChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
        targetArrivalChannel.setGroup(TARGET_MESSAGING_GROUP_ID);

        // finally, register the group and associated channels with the OS
        NotificationManager notificationManager = (NotificationManager) getSystemService(NotificationManager.class);
        notificationManager.createNotificationChannelGroup(targetMessagingGroup);
        notificationManager.createNotificationChannel(waitingNewTargetChannel);
        notificationManager.createNotificationChannel(navigatingToTargetChannel);
        notificationManager.createNotificationChannel(targetArrivalChannel);
    }
}

// --------------------------------------------------------------------
// Method: createNotification
//
// Purpose: Called whenever changing the displayed notification is
//          required.  Must call this with requestedNotificationType
//          of NOTIFY_TYPE_WAITING_FOR_TARGET from onStartCommand
//          in order to call startForeground within the 5 second limit
//          for a foreground service.
// --------------------------------------------------------------------
protected void createNotification(LocationService.LocationNotifyType requestedNotificationType, Bitmap notificationBitmap, Uri soundUri, String title, String message)
{
    Intent notificationIntent = new Intent(parentContext, signalledClass);
    PendingIntent pendingIntent = null;
    Notification notification = null;
    int notification_id = CHANNEL_NOTIFICATION_ID;

    switch (requestedNotificationType)
    {
        default:
        {
            Log.d("LocationHandler", "Unknown LocationNotifyType, NOT changing notification");
            break;
        }
        case NOTIFY_TYPE_WAITING_FOR_TARGET:
        {
            pendingIntent = PendingIntent.getActivity(parentContext, 0, notificationIntent, 0);

            notification = new NotificationCompat.Builder(parentContext, WAITING_NEW_TARGET_CHANNEL_ID)
                    .setContentTitle(title)
                    .setContentText(message)
                    .setSmallIcon(R.mipmap.ic_launcher)
                    .setLargeIcon(notificationBitmap)
                    .setPriority(NotificationCompat.PRIORITY_HIGH) // only affects API 25 and below
                    .setStyle(new NotificationCompat.BigTextStyle().setSummaryText("Waiting").setBigContentTitle(title).bigText(message))
                    .setContentIntent(pendingIntent)
                    .setTicker(getText(R.string.ticker_text))
                    .setAutoCancel(false)
                    .setOnlyAlertOnce(true)
                    .setSound(soundUri)
                    .build();

            if (notification != null)
            {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
                {
                    startForeground(notification_id, notification);
                }
                else
                {
                    NotificationManagerCompat.from(parentContext).notify(notification_id, notification);
                }
            }

            break;
        }
        case NOTIFY_TYPE_NAVIGATING:
        {
            pendingIntent = PendingIntent.getActivity(parentContext, 0, notificationIntent, 0);

            notification = new NotificationCompat.Builder(parentContext, NAVIGATING_TO_TARGET_CHANNEL_ID)
                    .setContentTitle(title)
                    .setContentText(message)
                    .setSmallIcon(R.mipmap.ic_launcher)
                    .setLargeIcon(notificationBitmap)
                    .setPriority(Notification.PRIORITY_HIGH) // only affects API 25 and below
                    .setStyle(new NotificationCompat.BigTextStyle().setSummaryText("Navigating").setBigContentTitle(title).bigText(message))
                    .setContentIntent(pendingIntent)
                    .setTicker(getText(R.string.ticker_text))
                    .setAutoCancel(false)
                    .setOnlyAlertOnce(true)
                    .setSound(soundUri)
                    .build();

            NotificationManagerCompat.from(parentContext).notify(notification_id, notification);
            break;
        }
        case NOTIFY_TYPE_ARRIVAL:
        {
            notificationIntent.setAction("ArrivalNotification");
            notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
            notificationIntent.putExtra(AllConstants.APP_WAKEUP_TYPE, AllConstants.APP_WAKEUP_TARGET_ARRIVAL);
            pendingIntent = PendingIntent.getActivity(parentContext, notification_id, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);

            notification = new NotificationCompat.Builder(parentContext, TARGET_ARRIVAL_CHANNEL_ID)
                    .setContentTitle(title)
                    .setContentText(message)
                    .setSmallIcon(R.mipmap.ic_launcher)
                    .setLargeIcon(notificationBitmap)
                    .setPriority(NotificationCompat.PRIORITY_HIGH) // only affects API 25 and below
                    .setStyle(new NotificationCompat.BigTextStyle().setSummaryText("Arrival").setBigContentTitle(title).bigText(message))
                    .setContentIntent(pendingIntent)
                    .setAutoCancel(false)
                    .setSound(soundUri)
                    .setWhen(System.currentTimeMillis())
                    .build();

            NotificationManagerCompat.from(parentContext).notify(notification_id, notification);
            break;
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...