11

Recently I use notification channel to support android O. But the problem is I cannot change the sound Uri dynamically. Our app have notification sound setting which user can change app notification sound as they want. But as you know, Android now do not allow developer to update notification channel before user reinstall app. There I consider several possible solutions which is not looks good.

  1. User ringtone manager to play ringtone instead of setSound. But when user disable notification in app setting, still ringtone will not stop playing. (This will be bad user experience)

  2. Delete notification channel and create new one when user change ringtone sound. But this also looks bad because in app setting google shows the history of deleted channel info.(Actually not necessary)

Is there any good solution?

Jonas
  • 121,568
  • 97
  • 310
  • 388
Wooram Jung
  • 228
  • 2
  • 10
  • 1
    Note that #2 does not work if you reuse the notification channel name: it just restores the channel exactly as it was before you deleted it. – ianhanniballake Apr 02 '18 at 05:16

2 Answers2

12

On Android O+ devices, you should remove any notification specific settings within your app and offer a link within your settings screen to open the system's notification channel settings, where the user can adjust the sound of the notification channel directly.

ianhanniballake
  • 191,609
  • 30
  • 470
  • 443
  • 2
    But we want to use custom sound for our app not ringtone provided by google device. And as I said, user can select their favorite ringtone sound from list. (These sounds was recorded by our user voice before). I know why google introduce notification channel but cannot understand why they do not allow modify setSound dynamically. – Wooram Jung Apr 02 '18 at 05:34
  • 4
    Any ringtone you add to [the ringtone directory](https://developer.android.com/reference/android/os/Environment.html#DIRECTORY_RINGTONES) will be automatically made available to pick from. The Channel's settings are owned by the user after creation - they are the ones who choose the importance level (i.e., does your notification make sound at all) as well as the sound, directly in the single centralized system UI. – ianhanniballake Apr 02 '18 at 14:23
  • Thanks, I think you are right. I will talk with my team member to remove app's own notification setting and use google's one. :) – Wooram Jung Apr 02 '18 at 22:36
  • 1
    For behavior "open the system's notification channel settings", should this only be specified to Android O and above? Pre Android O, still able to modify custom notification sound, within app itself right? – Cheok Yan Cheng Jul 30 '18 at 20:36
  • 3
    Some users complain that on their phone the system notification settings lacks option to change sound. I received snapshots from a Samsung A5, Huawei Honor View 10, Huawei Honor 9 demonstrating this using GMail notification settings button. Has anybody faced this? – mdicosimo Sep 11 '18 at 04:10
  • 2
    @mdicosimo Yes, I tried Huawei nova, Xiaomi PAD 4, users can only turn on/off the sound, can not choose different ringtones. – Chandler Oct 06 '18 at 01:27
  • @Chandler It seems quite a common problem. I tried to ask a specific question but no help until now: [link](https://stackoverflow.com/questions/51983074/android-o-some-phones-seem-to-lack-the-option-to-change-sound-type-for-notific) – mdicosimo Oct 07 '18 at 04:58
  • 5
    What is the best practice if, let's say I have 20 sounds that the user can pick? Should I copy everything in Ringtone folder, messing with other apps and the user SDCard? I would like these sounds to stay internal to my app. – Waza_Be Feb 10 '19 at 07:30
  • 2
    I also have a situation where I have ~20 sounds to use as the notifications. Using the phones picker is not an option because this app is a government app that must pick from one of these 20 sounds only. My current option is to pre-create 20 notification channels... I think Google needs to touch this notification channel thing up a bit. If I delete and reuse a notification channel ID they should just let me change the settings to it. – Ryan Oct 04 '19 at 04:07
1

@RequiresApi(api = Build.VERSION_CODES.O) private void createChannels() {

    Nmanager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);

    AudioAttributes attributes = new AudioAttributes.Builder()
            .setUsage(AudioAttributes.USAGE_NOTIFICATION)
            .build();

    ArrayList arrayList = new ArrayList<String>();
    Field[] fields = R.raw.class.getFields();
    for (int i = 1; i < fields.length - 1; i++) {
        arrayList.add(fields[i].getName());
    }


    DBRingtone RDB = new DBRingtone(this);
    Cursor cursor = RDB.getringtone();

    if (cursor.getCount() > 0) {

        int ring = parseInt(cursor.getString(0));

         resID = getResources().getIdentifier((String) arrayList.get(ring), "raw", getPackageName());

        i=i+resID;

        uri = Uri.parse("android.resource://" + getPackageName() + "/" + resID);
    } else
        {
            i=i+10;
        uri = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.default_sound);
    }

    CHANNEL_ID = CHANNEL_ID+i;

    notificationChannel = new NotificationChannel(CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_HIGH);
    notificationChannel.enableLights(true);
    notificationChannel.enableVibration(true);
    notificationChannel.setDescription("Your message");
    notificationChannel.setLightColor(Color.RED);
    notificationChannel.setSound(uri, attributes);
    notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
    Nmanager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    Nmanager.createNotificationChannel(notificationChannel);

}

Hello all, I have solved this problem using the above code and it's working. You can also assign CHANNEL_ID = CHANNEL_ID+resID directly to. For the purpose i have assigned using variable i. I have stored the user preferred Notification sounds resID is SQLite database and In the createchannels class i have retrieved that resID using cursor to create the uri's path.Hope this will help you Thank you...