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
    
    
        

     

  • 自定义通知栏布局文件activity_notification.xml


    
        
        
    
    

生活不只是敲代码,如果你或你身边的人喜欢电影,可以关注下我的公众号~ 

Android O(8.0)通知栏解决方案_第1张图片

 

 

你可能感兴趣的:(Android开发技巧)