web-dev-qa-db-ja.com

Android O-通知チャンネル-振動パターンまたは音の種類を変更する

Android Oを使用すると、「Notification Channels」が取得されます。

私が理解する限り、それはユーザー設定できない通知音または他の関連する通知設定APP内もう.

ユーザーは「Notification Channels Setting」に移動して、toneまたはvibrationなどを変更する必要があります。hereすべてのメソッド from NotificationBuilder like setSoundは無視されます。

[〜#〜] no [〜#〜]を変更する方法トーンをサイレントにする via code
またはコードを介して振動パターンを変更するには?

たとえば、ユーザーは私のアプリで振動パターンを設定することができます。
または通知タイプではなく、アラームタイプからトーンを選択できます。

これはすべて不可能になりましたか?
これは正しいですか、これを行う方法はありますか?

21
chrisonline

アプリでサウンドとバイブレーションのカスタマイズを引き続き提供できますが、別のアプローチが必要です。要するに、通知チャンネルを使用する代わりにAndroid Oで手動で音と振動を再生することです(見た目よりも簡単です)。

これは私がそれをやった方法です:

_NotificationCompat.Builder builder = new NotificationCompat.Builder(context, channelId);

// builder.setSmallIcon(...)
// builder.setContentTitle(...)
// builder.setContentText(...)

if (Android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

    // play vibration
    vibrator = (Vibrator)context.getSystemService(Context.VIBRATOR_SERVICE);
    vibrator.vibrate(VibrationEffect.createWaveform(vibrationPattern, -1));

    // play sound
    Intent serviceIntent = new Intent(context, SoundService.class);
    serviceIntent.setAction("ACTION_START_PLAYBACK");
    serviceIntent.putExtra("SOUND_URI", soundUri.toString());
    context.startForegroundService(serviceIntent);

    // the delete intent will stop the sound when the notification is cleared
    Intent deleteIntent = new Intent(context, SoundService.class);
    deleteIntent.setAction("ACTION_STOP_PLAYBACK");
    PendingIntent pendingDeleteIntent =
            PendingIntent.getService(context, 0, deleteIntent, 0);
    builder.setDeleteIntent(pendingDeleteIntent);

} else {

    builder.setVibrate(vibrationPattern);
    builder.setSound(soundUri);

}

notificationManager.notify(notificationId, builder.build());
_

SoundService.classは、MediaPlayerでサウンドを再生する場所です。

_public class SoundService extends Service {

    MediaPlayer mMediaPlayer;

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    public int onStartCommand(Intent intent, int flags, int startId) {

        // foreground notification
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationCompat.Builder builder =
                new NotificationCompat.Builder(this, otherChannelId);
            builder.setSmallIcon(...)
                    .setContentTitle(...)
                    .setContentText(...)
                    .setAutoCancel(true);
            startForeground(foregroundNotificationId, builder.build());
        }

        // check action
        String action = intent.getAction();
        switch (action) {
            case "ACTION_START_PLAYBACK":
                startSound(intent.getStringExtra("SOUND_URI"));
                break;
            case "ACTION_STOP_PLAYBACK":
                stopSound();
                break;
        }

        // service will not be recreated if abnormally terminated
        return START_NOT_STICKY;
    }

    private void startSound(String uriString) {

        // parse sound
        Uri soundUri;
        try {
            soundUri = Uri.parse(uriString);
        } catch (Exception e) {
            cleanup();
            return;
        }

        // play sound
        if (mMediaPlayer == null) {
            mMediaPlayer = new MediaPlayer();
            mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                @Override
                public void onPrepared(MediaPlayer mp) {
                    mp.start();
                }
            });
            mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mediaPlayer) {
                    cleanup();
                }
            });
        }
        try {
            mMediaPlayer.setDataSource(this, soundUri);
            mMediaPlayer.prepareAsync();
        } catch (Exception e) {
            cleanup();
        }

    }

    private void stopSound() {
        if (mMediaPlayer != null) {
            mMediaPlayer.stop();
            mMediaPlayer.release();
            mMediaPlayer = null;
        }
        cleanup();
    }

    private void cleanup() {
        stopSelf();
    }

}
_

推奨事項

  • IMPORTANCE_DEFAULT(ユーザーの場合は「高」)、ヌルサウンド(setSound(null,null))、およびヌルバイブレーション(setVibrationPattern(null))を使用して通知チャンネルを作成し、チャンネルの説明でこれを説明しますアプリ自体のカスタマイズとの競合を避けるために推奨される設定です。
  • すべてをあなたの好意に変えてください:機能を削除する代わりに、ユーザーに新しい機能を提供してください。カスタマイズ機能または通知チャネル機能を使用する機会を彼らに与えることができます(たとえば、現在のチャネルの重要度を確認でき、使用できるレベルに応じて、どちらかを使用できます)。

フォアグラウンド通知

Starting Android O、バックグラウンドから開始されたサービスは、フォアグラウンドサービスとして開始する必要があります。これは、SoundServiceにフォアグラウンド通知が必要であることを意味します。これにはいくつかのオプションがあります。

  • 「再生を停止」というボタンを使用して、ニースのフォアグラウンド通知を作成し、ユーザーが開始した通知を削除せずにサウンドを停止できるようにします。

  • 簡単な通知を作成し、無効なチャンネルに送信します(IMPORTANCE_NONEで作成した場合、無効なチャンネルを作成できます)。これを行うと、デフォルトのシステム「アプリはバックグラウンドで実行されています」通知がフォアグラウンド通知の代わりに表示されますが、ユーザーは必要に応じてステータスバーからこの通知を非表示にできます。

[〜#〜] edit [〜#〜]:in Android 8.1 8.1は、IMPORTANCE_NONEで無効化されたチャネルを作成することは、チャネルが有効化されるため、役に立たないようです。通知を送信すると自動的に送信されます。最初からIMPORTANCE_LOWで作成し、必要に応じてユーザーが重要度を変更できるようにすることをお勧めします。

17
jmart

あなたの場合に役立つかもしれません。通知が1つ表示されている場合は、.setOnlyAlertOnce(true)を設定して、この通知を更新するときにサウンドを無効にできます。このソリューションは、通知を更新する場合にのみ機能します。

5

チャンネルが作成されると、それを変更することはできなくなります。

通知チャネルを作成して通知マネージャーに送信すると、プログラムで通知チャネルの動作を変更することはできません

https://developer.Android.com/preview/features/notification-channels.html

あなたがしなければならないこと チャンネルを削除する そして異なるIDで新しいものを作成する

3
tyczj

私にとってAndroid> = 8.0の正しい方法は、これを使用してサウンド/バイブレーションオプションを非表示にし、ユーザーをアプリ通知設定にリダイレクトすることです。

  Intent intent = new Intent();
                intent.setAction("Android.settings.APP_NOTIFICATION_SETTINGS");
                intent.putExtra("Android.provider.extra.APP_PACKAGE", context.getPackageName());
                context.startActivity(intent);
1
Lluis Felisart

サウンドを手動で再生することはお勧めできません。最適なアプローチは、2つ(またはそれ以上)のチャンネルを使用することです。これは、再生したい各音/振動ごとに1つです。

コードでは、再生するサウンドに応じて、使用するチャネルを決定できます。

クライアントの設定に応じてデフォルトの通知音またはカスタム音を再生するコードを次に示します。コードは、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());
}
0

だから、コードを介してトーンをサイレントに変更する方法は本当にありませんか?

NotificationChannelsetSound()を使用 おそらく、短い無音部分を含むサウンドファイルを指します。

または、コードを介して振動パターンを変更するには?

NotificationChannelsetVibrationPattern()を使用

0
CommonsWare