设置自定义声音以进行通知

时间:2017-08-30 09:39:01

标签: android audio android-notifications

  

我试图为通知设置自定义声音。

详细信息:

我试图通过用户的选择(来自他们的手机存储设置)来设置通知声音。 因为我保存了db的路径,当有通知时,显示通知和设置声音;我从现有的通知ID中获取声音。

从那个我决定哪个声音应该播放用户选择的声音或默认声音....但这不是全部工作...它甚至没有播放默认声音。

如何设置/播放自定义声音以进行通知!?

谷歌研究之后:许多建议从原始文件夹播放声音,但我没有得到ans我将用户选择的声音保存到原始文件夹(当然程序化的盟友)所以我可以从原始文件夹播放声音..

P.S 有许多与此相关的问题,但它们并不符合我的要求

这是我的代码:

 private void showNotification(Context context, Things things) {

    try {
        NotificationManager mNotifyMgr =
                (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);

        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context)
                .setSmallIcon(R.drawable.icon)
                //example for large icon
                .setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.drawable.icon))
                .setContentTitle(things.getTitle())
                .setContentText(things.getThing()).setSubText(things.getNotification())
                .setOngoing(false)
                .setPriority(NotificationCompat.PRIORITY_DEFAULT)
                .setAutoCancel(true);
        Intent i = new Intent(context, HomeActivity.class);
        PendingIntent pendingIntent =
                PendingIntent.getActivity(
                        context,
                        0,
                        i,
                        PendingIntent.FLAG_ONE_SHOT
                );
        // example for blinking LED
        mBuilder.setLights(0xFFb71c1c, 1000, 2000);
        if (things.getRingtone() == null || things.getRingtone().equals("")) {
            mBuilder.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION));

        } else {
           Ringtone r = RingtoneManager.getRingtone(context, Uri.parse(things.getRingtone()));
            r.play();
            Toast.makeText(context, things.getRingtone(), Toast.LENGTH_SHORT).show();
        }
        //mBuilder.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION));
        mBuilder.setContentIntent(pendingIntent);
        mNotifyMgr.notify(12345, mBuilder.build());
    } catch (Exception e) {
        Log.d(getClass().getName(), "catch  " + e.toString());
    }
}

2 个答案:

答案 0 :(得分:1)

从API 26(Oreo)开始,您需要在通知通道上设置声音。创建通道后,除非重新安装应用程序或清除本地数据,否则无法更改其设置(包括声音)。

因此,最好的方法是有两个(或更多)通道-每个要播放的声音/振动一个。

在代码中,您可以根据要播放的声音来决定使用哪个通道。

这是我的代码,在其中根据客户端的设置播放默认的通知声音或自定义声音。该代码还将处理在API 26之前运行Android的设备:

String sound = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).getString("NotificationsSound", getString(R.string.settingsNotificationSiren));
Uri soundUri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://"+ getApplicationContext().getPackageName() + "/" + R.raw.siren);
NotificationManager mNotificationManager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
NotificationChannel mChannel;
String channel_id = Utils.CHANNEL_DEFAULT_ID;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    if (sound.toLowerCase().equals(getString(R.string.settingsNotificationSiren).toLowerCase())) {
        channel_id = Utils.CHANNEL_SIREN_ID;
        mChannel = new NotificationChannel(Utils.CHANNEL_SIREN_ID, Utils.CHANNEL_SIREN_NAME, NotificationManager.IMPORTANCE_HIGH);
        mChannel.setLightColor(Color.GRAY);
        mChannel.enableLights(true);
        mChannel.setDescription(Utils.CHANNEL_SIREN_DESCRIPTION);
        AudioAttributes audioAttributes = new AudioAttributes.Builder()
                .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                .setUsage(AudioAttributes.USAGE_NOTIFICATION)
                .build();
        mChannel.setSound(soundUri, audioAttributes);
    } else {
        mChannel = new NotificationChannel(Utils.CHANNEL_DEFAULT_ID, Utils.CHANNEL_DEFAULT_NAME, NotificationManager.IMPORTANCE_HIGH);
        mChannel.setLightColor(Color.GRAY);
        mChannel.enableLights(true);
        mChannel.setDescription(Utils.CHANNEL_DEFAULT_DESCRIPTION);
    }
    if (mNotificationManager != null) {
        mNotificationManager.createNotificationChannel( mChannel );
    }
}

NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this, channel_id)
        .setSmallIcon(R.drawable.ic_stat_maps_local_library)
        .setLargeIcon(BitmapFactory.decodeResource(getApplicationContext().getResources(), R.mipmap.ic_launcher))
        .setTicker(title)
        .setContentTitle(contentTitle)
        .setContentText(contentText)
        .setAutoCancel(true)
        .setLights(0xff0000ff, 300, 1000) // blue color
        .setWhen(System.currentTimeMillis())
        .setPriority(NotificationCompat.PRIORITY_DEFAULT);

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
    if (sound.toLowerCase().equals(getString(R.string.settingsNotificationSiren).toLowerCase())) {
        mBuilder.setSound(soundUri);
    } else {
        mBuilder.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION));
    }
}

int NOTIFICATION_ID = 1; // Causes to update the same notification over and over again.
if (mNotificationManager != null) {
    mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
}

答案 1 :(得分:0)

我使用了这段代码:

    private Uri getSound(){
    String sound = appPreferences.getString(LocalPreferences.PREFERENCE_NOTIFICATIONS_SOUND, "");
    Uri soundUri = null;
    try {
        soundUri = Uri.parse(sound);
    } catch (Exception ignored) {}

    if (soundUri == null) {
        soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
    }
    return soundUri;
}

要将声音置于首选项中,我使用了此

        @Override
public boolean onPreferenceTreeClick(Preference preference){
    switch (preference.getKey()) {
        case LocalPreferences.PREFERENCE_NOTIFICATIONS_SOUND:
            Intent intent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
            intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_NOTIFICATION);
            intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, true);
            intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, true);
            intent.putExtra(RingtoneManager.EXTRA_RINGTONE_DEFAULT_URI, Settings.System.DEFAULT_NOTIFICATION_URI);

            String existingValue = appPreferences.getString(LocalPreferences.PREFERENCE_NOTIFICATIONS_SOUND, "");
            if (existingValue != null) {
                if (existingValue.length() == 0) {
                    // Select "Silent"
                    intent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, (Uri) null);
                } else {
                    intent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, Uri.parse(existingValue));
                }
            }

            startActivityForResult(intent, REQUEST_CODE_ALERT_RINGTONE);
            return true;
        default:
            return super.onPreferenceTreeClick(preference);
    }
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data){
    if (requestCode == REQUEST_CODE_ALERT_RINGTONE && data != null) {
        Uri ringtone = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
        if (ringtone != null) {
            setRingtonePreferenceValue(ringtone.toString());
        } else {
            // "Silent" was selected
            setRingtonePreferenceValue("");
        }
    } else {
        super.onActivityResult(requestCode, resultCode, data);
    }
}

private void setRingtonePreferenceValue(String ringtonePath){
    appPreferences.edit().putString(LocalPreferences.PREFERENCE_NOTIFICATIONS_SOUND, ringtonePath).apply();
    // For ringtone preferences, look up the correct display value
    // using RingtoneManager.
    if (! TextUtils.isEmpty(ringtonePath)) {
        Ringtone ringtone = RingtoneManager.getRingtone(ringtonePreference.getContext(), Uri.parse(ringtonePath));

        if (ringtone == null) {
            // Clear the summary if there was a lookup error.
            ringtonePreference.setSummary(null);
        } else {
            // Set the summary to reflect the new ringtone display
            // name.
            String name = ringtone.getTitle(ringtonePreference.getContext());
            ringtonePreference.setSummary(name);
        }
    } else {
        ringtonePreference.setSummary("Без звука");
    }
}

第二个区块的来源:https://issuetracker.google.com/issues/37057453#c2

当然,在制作通知时,您应该致电

        builder.setSound(getSound())

检查设备上是否启用了声音。

希望它可以帮到你!