1. 程式人生 > >Android O(8.0)通知欄解決方案

Android O(8.0)通知欄解決方案

  • 我一定要適配嗎Android8.0通知欄嗎?
    Google這次對於8.0系統通知渠道的推廣態度還是比較強硬的。如果你將專案中的targetSdkVersion指定到了26或者更高,那麼Android系統就會認為你的App已經做好了8.0系統的適配工作,當然包括了通知欄的適配。這個時候如果還不使用通知渠道的話,那麼你的App的通知將完全無法彈出。因此這裡給大家的建議就是,一定要適配。

通知渠道圖解


 

  • 要要相容Android8.0 NotificationChannel需配置build.gradle(app)的相關版本號
android {
    /*要適配Android8.0 通知欄,編譯版本必須在26或以上,
    否則與渠道(NotificationChannel)的相關方法用不了*/
    compileSdkVersion 26
    buildToolsVersion "25.0.2"
    defaultConfig {
        applicationId "com.lg.www.blog"
        /*適配Android8.0 通知欄也要求最低版本必須在26或以上,
        否則與通知渠道相關的方法比如設定渠道id方法(setChannelId(String channelId))會提示報
        (Call requires API level 26 (current min is 16):android.app.Notification.Builder#Builder)錯誤,
        但是為了相容低版本手機也能安裝APP,我們通過加buildsdk的版本號的判斷
        (當版本號大於26時才使用渠道相關方法)來解決這個錯誤*/
        minSdkVersion 16
        targetSdkVersion 22
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}
  • 主要程式碼
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.graphics.Color;
import android.os.Build;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.RemoteViews;

public class NotificationActivity extends AppCompatActivity implements View.OnClickListener {

    private Button normal_notification;
    private Button progress_notification;
    private Button custom_notification;
    private Button detete_notification;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_notification);
        normal_notification = (Button) findViewById(R.id.normal_notification);
        normal_notification.setOnClickListener(this);
        progress_notification = (Button) findViewById(R.id.progress_notification);
        progress_notification.setOnClickListener(this);
        custom_notification = (Button) findViewById(R.id.custom_notification);
        custom_notification.setOnClickListener(this);
        detete_notification = (Button) findViewById(R.id.detete_notification);
        detete_notification.setOnClickListener(this);
    }

    //發一個普通通知,新增一個通知
    private void sendNormalNotification(){
        Notification notification = getNotificationBuilder().build();
        getNotificationManager().notify(1,notification);
    }

    //模仿一個帶下載進度的通知,對通知的更新
    private void sendProgressNotification(){
        final Notification.Builder builder = getNotificationBuilder();
        //發起Notification後,鈴聲和震動均只執行一次
        builder.setDefaults(Notification.FLAG_ONLY_ALERT_ONCE);
        getNotificationManager().notify(2,builder.build());
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 100; i++) {
                    try {
                        Thread.sleep(1000);
                        builder.setProgress(100,i,false);
                        //雖然加了FLAG_ONLY_ALERT_ONCE,但是每過一秒就發次通知震動一次還是挺煩的,
                        //所以把下面設定震動模式的程式碼註釋掉了
                        builder.setDefaults(Notification.FLAG_ONLY_ALERT_ONCE);
                        getNotificationManager().notify(2,builder.build());
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }

    //發一個自定義通知
    private void sendCustomNotification(){
        //自定義通知也是在Android N之後才出現的,所以要加上版本號判斷
        if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.N){
            Notification.Builder builder = getNotificationBuilder();
            //自定義通知欄檢視初始化
            RemoteViews remoteViews =
                    new RemoteViews(getPackageName(),R.layout.layout_custom_notification);
            remoteViews.setTextViewText(R.id.notification_title,"custom_title");
            remoteViews.setTextViewText(R.id.notification_content,"custom_content");
            //PendingIntent即將要發生的意圖,可以被取消、更新
            Intent intent = new Intent(this,NotificationIntentActivity.class);
            PendingIntent pendingIntent =
                    PendingIntent.getActivity(this,-1,intent,PendingIntent.FLAG_UPDATE_CURRENT);
            remoteViews.setOnClickPendingIntent(R.id.turn_next,pendingIntent);
            //繫結自定義檢視
            builder.setCustomContentView(remoteViews);
            getNotificationManager().notify(3,builder.build());
        }
    }

    //獲取系統服務
    private NotificationManager mNotificationManager;
    private NotificationManager getNotificationManager() {
        if (mNotificationManager == null){
            mNotificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
        }
        return mNotificationManager;
    }

    //相容android8.0以及之前版本獲取Notification.Builder方法
    private Notification.Builder getNotificationBuilder(){
        Notification.Builder builder = new Notification.Builder(this)
                .setAutoCancel(true)//是否自動取消,設定為true,點選通知欄 ,移除通知
                .setContentTitle("通知欄訊息標題")
                .setContentText("通知欄訊息具體內容")
                .setSmallIcon(R.mipmap.ic_launcher)//通知欄訊息小圖示,不設定是不會顯示通知的
                //ledARGB 表示燈光顏色、ledOnMs 亮持續時間、ledOffMs 暗的時間
                .setLights(Color.RED, 3000, 3000)
                //.setVibrate(new long[]{100,100,200})//震動的模式,第一次100ms,第二次100ms,第三次200ms
                //.setStyle(new Notification.BigTextStyle())
                ;
        //沒加版本判斷會報Call requires API level 26 (current min is 16):android.app.Notification.Builder#Builder)錯誤
        //builder.setChannelId("channel_id");
        //通過版本號判斷相容了低版本沒有通知渠道方法的問題,只有當版本號大於26(Build.VERSION_CODES.O)時才使用渠道相關方法
        if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){
            //builder的channelId需和下面channel的保持一致;
            builder.setChannelId("channel_id");
            NotificationChannel channel = new
                    NotificationChannel("channel_id","channel_name",
                    NotificationManager.IMPORTANCE_DEFAULT);
            channel.setBypassDnd(true);//設定可以繞過請勿打擾模式
            channel.canBypassDnd();//可否繞過請勿打擾模式
            //鎖屏顯示通知
            channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
            channel.shouldShowLights();//是否會閃光
            channel.enableLights(true);//閃光
            //指定閃光時的燈光顏色,為了相容低版本在上面builder上通過setLights方法設定了
            //channel.setLightColor(Color.RED);
            channel.canShowBadge();//桌面launcher訊息角標
            channel.enableVibration(true);//是否允許震動
            //震動模式,第一次100ms,第二次100ms,第三次200ms,為了相容低版本在上面builder上設定了
            //channel.setVibrationPattern(new long[]{100,100,200});
            channel.getAudioAttributes();//獲取系統通知響鈴聲音的配置
            channel.getGroup();//獲取通知渠道組
            //繫結通知渠道
            getNotificationManager().createNotificationChannel(channel);
        }
        return builder;
    };

    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.normal_notification:
                sendNormalNotification();
                break;
            case R.id.progress_notification:
                sendProgressNotification();
                break;
            case R.id.custom_notification:
                sendCustomNotification();
                break;
            case R.id.detete_notification:
                getNotificationManager().cancel(1);//通知管理——刪除
                break;
        }
    }
}
  • 主要程式碼所在Activity的佈局檔案activity_notification.xml
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/activity_notification"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context="com.lg.www.blog.NotificationActivity">
        <Button
            android:id="@+id/normal_notification"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="普通通知"/>
        <Button
            android:id="@+id/progress_notification"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="帶進度條的通知"/>
        <Button
            android:id="@+id/custom_notification"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="自定義通知"/>
        <Button
            android:id="@+id/detete_notification"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="刪除通知"/>
    </LinearLayout>
    

     

  • 自定義通知欄佈局檔案activity_notification.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:paddingLeft="16dp"
    android:paddingRight="16dp">
    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:gravity="center_horizontal"
        android:orientation="vertical">
        <TextView
            android:id="@+id/notification_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="@color/colorPrimaryDark"
            android:textSize="16sp"
            android:text="通知欄標題"/>
        <TextView
            android:id="@+id/notification_content"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:textColor="@color/colorAccent"
            android:textSize="13sp"
            android:text="通知欄內容"/>
    </LinearLayout>
    <Button
        android:id="@+id/turn_next"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="跳轉"/>
</LinearLayout>

生活不只是敲程式碼,如果你或你身邊的人喜歡電影,可以關注下我親愛的公眾號~