web-dev-qa-db-ja.com

Android O-通知チャネルとNotificationCompat

私はこの気持ちを変えることはできません:繰り返しますが、Android開発者は何か新しいものを思いつき、その機能がどのように使われるかについて誰もが暗闇の中に残します。

Android O.

長年、互換性サポートライブラリを使用して、特定のプラットフォームの詳細に対処することを避けてきました。つまり:NotificationCompat

さて、Builderには通知チャンネルIDを指定する必要があります。これはNiceですが、そのようなチャンネルを作成することは完全に私に任せています。チャネルを作成するための互換性のサポートが見つかりません。また、適切な時点でそれらを作成する合理的な方法を見つけることもできません。

ドキュメントは単に「どこかで」行うべきであり、「おそらく通知を発行するときではない」と述べています。しかし、私は正確に何をすべきでしょうか?単純なタスクのためにバージョン固有のものを書くのは嫌いです。そのため、compatライブラリを使用します。

誰がそれを処理する方法についての提案を持っていますか?通知を表示したいときに毎回作成するのは「高価」ですか?

20
Zordid

これは、Android Oで通知を生成し、後方互換性を維持するための私のソリューションです。

        String idChannel = "my_channel_01";
        Intent mainIntent;

        mainIntent = new Intent(context, LauncherActivity.class);

        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, mainIntent, 0);

        NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

        NotificationChannel mChannel = null;
        // The id of the channel.

        int importance = NotificationManager.IMPORTANCE_HIGH;

        NotificationCompat.Builder builder = new NotificationCompat.Builder(context, null);
        builder.setContentTitle(context.getString(R.string.app_name))
                .setSmallIcon(getNotificationIcon())
                .setContentIntent(pendingIntent)
                .setContentText(context.getString(R.string.alarm_notification) + ManagementDate.getIstance().hourFormat.format(getAlarm(context, 0)));

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            mChannel = new NotificationChannel(idChannel, context.getString(R.string.app_name), importance);
            // Configure the notification channel.
            mChannel.setDescription(context.getString(R.string.alarm_notification));
            mChannel.enableLights(true);
            mChannel.setLightColor(Color.RED);
            mChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
            mNotificationManager.createNotificationChannel(mChannel);
        } else {
            builder.setContentTitle(context.getString(R.string.app_name))
                    .setPriority(NotificationCompat.PRIORITY_HIGH)
                    .setColor(ContextCompat.getColor(context, R.color.transparent))
                    .setVibrate(new long[]{100, 250})
                    .setLights(Color.YELLOW, 500, 5000)
                    .setAutoCancel(true);
        }
        mNotificationManager.notify(1, builder.build());
12
AlexPad

reflectionを使用して通知チャネルを作成し、26よりも小さいcompileSdkVersionを設定できる代替ソリューションを次に示します。

_   private void createNotificationChannel(NotificationManager notificationManager) {
        // Channel details
        String channelId = "myChannelId";
        String channelName = "Notifications";

        // Channel importance (3 means default importance)
        int channelImportance = 3;

        try {
            // Get NotificationChannel class via reflection (only available on devices running Android O or newer)
            Class notificationChannelClass = Class.forName("Android.app.NotificationChannel");

            // Get NotificationChannel constructor
            Constructor<?> notificationChannelConstructor = notificationChannelClass.getDeclaredConstructor(String.class, CharSequence.class, int.class);

            // Instantiate new notification channel
            Object notificationChannel = notificationChannelConstructor.newInstance(channelId, channelName, channelImportance);

            // Get notification channel creation method via reflection
            Method createNotificationChannelMethod =  notificationManager.getClass().getDeclaredMethod("createNotificationChannel", notificationChannelClass);

            // Invoke method on NotificationManager, passing in the channel object
            createNotificationChannelMethod.invoke(notificationManager, notificationChannel);

            // Log success to console
            Log.d("MyApp", "Notification channel created successfully");
        }
        catch (Exception exc) {
            // Log exception to console
            Log.e("MyApp", "Creating notification channel failed", exc);
        }
    }
_

次に、通知を作成するときに、単に_NotificationCompat.Builder_の.setChannelId()メソッドを呼び出します。

_builder.setChannelId("myChannelId");
_

注: _appcompat-v7_ライブラリを_26.x.x_のバージョン_build.gradle_に更新する必要があります。

_compile 'com.Android.support:appcompat-v7:26.1.0'
_
2
Elad Nava

あなたが思うほど高価ではありません!必要なことは、通知チャネルを作成して通知にバインドすることだけです。

これは2つの方法で解決できますが、どちらの場合も、特定のチャンネルIDで通知チャンネルを作成する必要があります。

NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
String id = "my_channel_01";
int importance = NotificationManager.IMPORTANCE_LOW;
NotificationChannel mChannel = new NotificationChannel(id, name,importance);
mChannel.enableLights(true);
mNotificationManager.createNotificationChannel(mChannel);

最初の方法は、コンストラクターで通知用のチャネルを設定することです。

Notification notification = new Notification.Builder(MainActivity.this , id).setContentTitle("Title");
mNotificationManager.notify("your_notification_id", notification);

2番目の方法は、Notificiation.Builder.setChannelId()によってチャネルを設定することです

Notification notification = new Notification.Builder(MainActivity.this).setContentTitle("Title").
setChannelId(id);
mNotificationManager.notify("your_notification_id", notification);

お役に立てれば

2
Milad Moosavi

通知コードが同じ場合構造毎回静的メソッドを作成し、パス必要なものをすべてチェックし、チェックするコードを配置する必要がある場合APIレベルこのメソッド内。

0
Khalid Ali

以前のバージョンのAndroid(<Oreo)をサポートする場合。NotificationManagerをラップして、Notification.Builder次のようなNotificationHelperのインスタンス:

/**
 * Helper class to manage notification channels, and create notifications.
 * <p>
 * Created by teocci.
 *
 * @author [email protected] on 2018-Oct-02
 */
public class NotificationHelper extends ContextWrapper
{
    public static final String NOTIFICATION_CHANNEL_PRIMARY = "notification_channel_primary";
    public static final int NOTIFICATION_ID_PRIMARY = 1100;

    private NotificationManager manager;

    /**
     * Registers notification channels, which can be used later by individual notifications.
     *
     * @param ctx The application context
     */
    public NotificationHelper(Context ctx)
    {
        super(ctx);

        // For API 26+ create notification channels
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL_PRIMARY,
                    getString(R.string.channel_name),
                    NotificationManager.IMPORTANCE_DEFAULT
            );
            channel.setLightColor(Color.BLUE);
            channel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
            channel.setDescription(getString(R.string.channel_description));
            getManager().createNotificationChannel(channel);
        }
    }
    /**
     * Cancel a previously shown notification.  If it's transient, the view
     * will be hidden.  If it's persistent, it will be removed from the status
     * bar.
     *
     * @param id    The ID of the notification
     */
    public void remove(int id){
        manager.cancel(id);
    }

    /**
     * Get a notification of type 1
     * <p>
     * Provide the builder rather than the notification it's self as useful for making notification
     * changes.
     *
     * @return the builder as it keeps a reference to the notification (since API 24)
     */
    public Notification getNotification()
    {
        return getNotification(getTitle(), getBody()).build();
    }

    /**
     * Get a notification of type 1
     * <p>
     * Provide the builder rather than the notification it's self as useful for making notification
     * changes.
     *
     * @param title the title of the notification
     * @param body  the body text for the notification
     * @return the builder as it keeps a reference to the notification (since API 24)
     */
    public Notification.Builder getNotification(String title, String body)
    {
        Notification.Builder builder = new Notification.Builder(getApplicationContext())
                .setOngoing(true)  // Persistent notification!
                .setAutoCancel(true)
                .setTicker(title)
                .setContentTitle(title)
                .setContentText(body)
                .setSmallIcon(getSmallIcon());

        // Set the Channel ID for Android O.
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            builder.setChannelId(NOTIFICATION_CHANNEL_PRIMARY); // Channel ID
        }

        return builder;
    }

    /**
     * Send a notification.
     *
     * @param id           The ID of the notification
     * @param notification The notification object
     */
    public void notify(int id, Notification.Builder notification)
    {
        getManager().notify(id, notification.build());
    }

    /**
     * Get the notification manager.
     * <p>
     * Utility method as this helper works with it a lot.
     *
     * @return The system service NotificationManager
     */
    private NotificationManager getManager()
    {
        if (manager == null) {
            manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        }

        return manager;
    }

    /**
     * Get the small icon for this app
     *
     * @return The small icon resource id
     */
    private int getSmallIcon()
    {
        return R.drawable.ic_smart_audio_noti_icon;
    }

    /**
     * Get the notification title for this app
     *
     * @return The notification title as string
     */
    private String getTitle()
    {
        return getString(R.string.notification_title);
    }

    /**
     * Get the notification content for this app
     *
     * @return The notification content as string
     */
    private String getBody()
    {
        return getString(R.string.notification_content);
    }
}

その後、次のように簡単に使用できます。

@Override
public void onCreate()
{
    ...
    notificationHelper = new NotificationHelper(this);
    notificationHelper.notify(NotificationHelper.NOTIFICATION_ID_PRIMARY, "App is running");
    ...
}

@Override
public void onDestroy()
{
    notificationHelper.remove(NotificationHelper.NOTIFICATION_ID_PRIMARY)
}
0
Teocci

以下のコードは私の側でうまく機能しています。それがあなたの助けになることを願っています

private void sendNotification(Context ctx, String title, int notificationNumber, String message, String subtext, Intent intent) {
        try {

            PendingIntent pendingIntent = PendingIntent.getActivity(ctx, notificationNumber, intent,
                    PendingIntent.FLAG_UPDATE_CURRENT);
            Uri url = your sound file from raw;
            NotificationCompat.Builder notificationBuilder = null;
            try {
                if (Build.VERSION.SDK_INT >= 26) {

                    try{
                        NotificationManager notificationManager = (NotificationManager)getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
                        notificationManager.deleteNotificationChannel(CHANNEL_ID_1);
                        notificationManager.deleteNotificationChannel(CHANNEL_ID_2);

                        if(!intent.getStringExtra("type").equalsIgnoreCase(""+TYPE_RIDE_REQUEST)){
                            NotificationChannel breaking = new NotificationChannel(CHANNEL_ID_1, CHANNEL_ID_1_NAME, NotificationManager.IMPORTANCE_HIGH);
                            breaking.setShowBadge(false);
                            breaking.enableLights(true);
                            breaking.enableVibration(true);
                            breaking.setLightColor(Color.WHITE);
                            breaking.setVibrationPattern(new long[]{100, 200, 100, 200, 100, 200, 100});
                            breaking.setSound(url,new AudioAttributes.Builder().build());

                            notificationBuilder = new NotificationCompat.Builder(this,CHANNEL_ID_1)
                                    .setSmallIcon(R.mipmap.ic_launcher);
                            notificationManager.createNotificationChannel(breaking);

                        }else{

                            NotificationChannel politics = new NotificationChannel(CHANNEL_ID_2,CHANNEL_ID_2_NAME, NotificationManager.IMPORTANCE_DEFAULT);
                            politics.setShowBadge(false);
                            politics.enableLights(true);
                            politics.enableVibration(true);
                            politics.setLightColor(Color.BLUE);
                            politics.setVibrationPattern(new long[]{100, 200, 100, 200, 100});
                            politics.setSound(url,new AudioAttributes.Builder().build());

                            notificationBuilder = new NotificationCompat.Builder(this,CHANNEL_ID_2)
                                    .setSmallIcon(R.mipmap.ic_launcher);
                            notificationManager.createNotificationChannel(politics);
                        }
                    }catch (Exception e){
                        e.printStackTrace();
                    }

                } else {
                    notificationBuilder = new NotificationCompat.Builder(ctx)
                            .setSmallIcon(R.mipmap.ic_launcher);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

            if (notificationBuilder == null) {
                notificationBuilder = new NotificationCompat.Builder(ctx)
                        .setSmallIcon(R.mipmap.ic_launcher);
            }


            notificationBuilder.setContentTitle(title);
            notificationBuilder.setSubText(subtext);
            notificationBuilder.setAutoCancel(true);

            notificationBuilder.setContentIntent(pendingIntent);
            notificationBuilder.setNumber(notificationNumber);
            NotificationManager notificationManager =
                    (NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE);

            notificationManager.notify(notificationNumber, notificationBuilder.build());

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
0
user4042384