最近公司有一個通知的功能,因而想起以前看過的Notification,當時看的時候看到網上有不少的講解和代碼,就以爲這個功能真的是so easy,然而實際操做的時候才發現網上的代碼坑真多。android
首先說明一下,我是在三款手機上進行的測試,華爲榮耀v10(Android8.0系統),oppo手機(Android7.0系統),魅藍note5(Android6.0系統),還有一個oppo(Android5.0系統)。api
在我寫這個功能的過程當中,遇到了一下幾個問題:bash
1:對於8.0系統,須要使用NotificationChannel,建立Notification的時候須要用這行代碼:Notification.Builder builder =new Notification.Builder(this);
app
而且必須給builder 設置ChannelId,經過setChannelId()這個方法。ide
2:在點擊通知欄上的通知跳轉到新界面後,通知不消失。佈局
這個須要在新界面進行取消操做,在新界面的onCerate()方法中進行如下操做:測試
//關閉通知欄上的通知ui
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
manager.cancel(5); //5表示跳轉過來的通知的ID
複製代碼
3:華爲8.0手機上修改提示音後提示音不變的問題:必須卸載重裝才能生效this
4:oppo手機上通知不顯示問題:須要進行如下設置:spa
設置 ——》其餘設置——》應用程序管理——》找到本身的應用——》點擊後找到通知管理——》將通知管理裏面的都打開
5:震動問題:魅藍手機上須要打開震動按鈕才能震動,oppo和華爲不用
6:v4包和v7包的區別:
Android Support v4:這個包是爲了照顧1.6及更高版本而設計的,這個包是使用最普遍的。
Android Support v7:這個包是爲了考慮照顧2.1及以上版本而設計的,但不包含更低,故若是不考慮1.6,咱們能夠採用再加上這個包,另外注意,v7是要依賴v4這個包的,即,兩個得同時被包含。
Android Support v13:這個包的設計是爲了android 3.2及更高版本的,通常咱們都不經常使用,平板開發中能用到
7:Android3.0以前使用new Notification()建立Notification對象,3.0以後就不用這麼建立對象了
Notification notification = new Notification();
複製代碼
8:呼吸燈問題:setLights()這個方法設置的是屏幕這一側的呼吸燈,不是手機背面的攝像頭的閃光燈,至於不知道什麼是呼吸燈的同窗,能夠百度一下
9:權限問題:只須要在清單文件中聲明震動權限便可,不須要動態獲取權限
下面是代碼(注意:代碼中已經對8.0進行了適配)
package gcg.testproject.activity.notifycation;
import android.Manifest;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.SystemClock;
import android.preference.PreferenceManager;
import android.provider.MediaStore;
import android.provider.Settings;
import android.support.annotation.RequiresApi;
import android.support.v7.app.NotificationCompat;
import android.view.View;
import android.widget.RemoteViews;
import android.widget.TextView;
import com.bumptech.glide.load.model.file_descriptor.FileDescriptorStringLoader;
import butterknife.Bind;
import butterknife.ButterKnife;
import gcg.testproject.R;
import gcg.testproject.base.BaseActivity;
import gcg.testproject.utils.LogUtils;
public class Notifycation2Activityextends BaseActivityimplements View.OnClickListener {
@Bind(R.id.tv_common)
TextViewmTvCommon;
@Bind(R.id.tv_remove)
TextViewmTvRemove;
@Bind(R.id.tv_bigicon)
TextViewmTvBigicon;
@Bind(R.id.tv_progress)
TextViewmTvProgress;
@Bind(R.id.tv_multi)
TextViewmTvMulti;
@Bind(R.id.tv_custom)
TextViewmTvCustom;
private int num_else;
private int num;
private Stringid ="my_channel_01";
private Stringname="我是渠道名字";
private NotificationChannelmChannel;
private NotificationManagermanager;//通知管理器,用於發送通知Notification對象
private boolean isO;//用來判斷是否是8.0系統
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_notifycation2);
ButterKnife.bind(this);
mTvCommon.setOnClickListener(this);
mTvRemove.setOnClickListener(this);
mTvBigicon.setOnClickListener(this);
mTvProgress.setOnClickListener(this);
mTvMulti.setOnClickListener(this);
mTvCustom.setOnClickListener(this);
manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
isO =true;
mChannel =new NotificationChannel(id,name, NotificationManager.IMPORTANCE_DEFAULT);
mChannel.setBypassDnd(true);//設置繞過免打擾模式
mChannel.canBypassDnd();//檢測是否繞過免打擾模式
mChannel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);//設置在鎖屏界面上顯示這條通知
//設置通知出現時的呼吸燈
mChannel.enableLights(true);
mChannel.enableVibration(true);
mChannel.setLightColor(Color.WHITE);
//卸載重裝,讓設置的震動生效 注意:設置震動時不用動態申請震動權限,只在清單文件中聲明便可
mChannel.setVibrationPattern(new long[]{100,200,300,400,500,400,300,200,400});
Uri mUri = Settings.System.DEFAULT_NOTIFICATION_URI;
mChannel.setSound(mUri, Notification.AUDIO_ATTRIBUTES_DEFAULT);
//自定義聲音 注意:要想讓設置的聲音生效,必須卸載重裝
// AudioAttributes.Builder audioAttributesBuilder = new AudioAttributes.Builder();
// audioAttributesBuilder.setLegacyStreamType(AudioManager.STREAM_MUSIC);
// AudioAttributes aa = audioAttributesBuilder.build();
// Uri uri = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.umeng_push_notification_default);
// mChannel.setSound(uri, aa);
manager.createNotificationChannel(mChannel);
}else {
isO =false;
}
}
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.tv_common://發送一個普統統知
LogUtils.i("送一個普統統知");
if (isO)
{
btn_8_common();
}else {
else_common();
}
break;
case R.id.tv_remove://移除通知
LogUtils.i("移除通知");
// manager.cancel(5);
manager.cancelAll();
break;
case R.id.tv_bigicon://設置大圖通知
LogUtils.i("設置大圖通知");
if (isO)
{
btn_8_bigicon();
}else {
else_big();
}
break;
case R.id.tv_progress://發送帶進度條的通知
LogUtils.i("發送帶進度條的通知");
if (isO)
{
btn_8_progress();
}else {
else_progress();
}
break;
case R.id.tv_multi://封裝多行文本樣式
LogUtils.i("封裝多行文本樣式");
if (isO)
{
btn_8_multi();
}else {
else_multi();
}
break;
case R.id.tv_custom://徹底自定義的通知
LogUtils.i("徹底自定義的通知");
if (isO)
{
btn_8_custom();
}else {
else_custom();
}
break;
}
}
複製代碼
// ========================== 如下是8.0如下的通知========================================
private void else_common(){
LogUtils.i("else_common");
// 注意:Android3.0以前使用new Notification()建立Notification對象
// Notification notification = new Notification();
// Android Support v4:這個包是爲了照顧1.6及更高版本而設計的,這個包是使用最普遍的。
// Android Support v7:這個包是爲了考慮照顧2.1及以上版本而設計的,但不包含更低,故若是不考慮1.6,
// 咱們能夠採用再加上這個包,另外注意,v7是要依賴v4這個包的,即,兩個得同時被包含。
// Android Support v13:這個包的設計是爲了android 3.2及更高版本的,通常咱們都不經常使用,平板開發中能用到
//Android3.0以後用
NotificationCompat.Builder builder =new NotificationCompat.Builder(this);
builder.setContentTitle("設置標題" + System.currentTimeMillis());
builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher));//設置大圖標
builder.setContentText("內容文本部分");
builder.setContentInfo("info信息");//設置info信息,即設置顯示在時間右下角的文字
builder.setSmallIcon(R.mipmap.ic_launcher);//必需要設置的小圖標
builder.setWhen(System.currentTimeMillis());//設置通知時間
builder.setTicker("設置滾動提示的文字設置滾動提示的文字設置滾動提示的文字設置滾動提示的文字設置滾動提示的文字");
builder.setOngoing(false);//設置左右滑動時是否會消失
builder.setAutoCancel(true);
builder.setDefaults(Notification.DEFAULT_SOUND);//設置默認鈴聲
//設置自定義鈴聲
// builder.setSound(Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.umeng_push_notification_default)); //調用系統多媒體褲內的鈴聲
//設置震動;部分手機必須打開震動功能才能震動
long[] vibrate =new long[]{0,500,500,500,500};
builder.setVibrate(vibrate);
// builder.setDefaults(Notification.DEFAULT_VIBRATE); //設置默認震動
// builder.setDefaults(Notification.DEFAULT_ALL);
//設置呼吸燈(不是閃光燈);注意:顏色跟設備有關,不是全部的顏色均可以,要看具體設備。
//注意:閃爍時長和熄滅時長也會跟設備有關,不徹底跟設置的同樣
builder.setLights(0xff0000ff,300,0);
num_else++;
manager.notify(num_else, builder.build());//發送通知
}
//部分手機的大圖通知在6.0系統上親測不能顯示大圖,若是要顯示大圖,建議設置自定義view
private void else_big()
{
LogUtils.i("else_big");
NotificationCompat.Builder builder =new NotificationCompat.Builder(this);
builder.setSmallIcon(R.mipmap.t2);
builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.t1));//設置大圖標
builder.setContentTitle("大圖片通知");
builder.setContentText("內容文本部分");
builder.setTicker("大圖通知來了");
builder.setContentInfo("info信息");//設置info信息,即設置顯示在時間右下角的文字
builder.setDefaults(Notification.DEFAULT_SOUND);//設置默認鈴聲
manager.notify(7, builder.build());
}
private void else_progress()
{
LogUtils.i("else_progress");
final NotificationCompat.Builder builder =new NotificationCompat.Builder(this);
builder.setSmallIcon(R.mipmap.ic_launcher);
builder.setContentTitle("帶進度條的通知");
builder.setProgress(100,0,false);
builder.setDefaults(Notification.DEFAULT_SOUND);//設置默認鈴聲
manager.notify(3, builder.build());
new Thread(new Runnable() {
@Override
public void run() {
for (int i =0; i <=100; i++) {
builder.setProgress(100, i,false);
manager.notify(3,builder.build());
SystemClock.sleep(200);
if (i ==100)//當進度條走完後,清除這個通知
{
manager.cancel(3);
}
}
}
}).start();
}
private void else_multi()
{
NotificationCompat.InboxStyle inboxStyle =new NotificationCompat.InboxStyle();
for (int i =0; i <10; i++) {
inboxStyle.addLine("這是第" + i +"行" +"文本");
}
NotificationCompat.Builder builder =new NotificationCompat.Builder(this);
builder.setSmallIcon(R.mipmap.ic_launcher);
builder.setContentTitle("多行文本");
inboxStyle.setBigContentTitle("多行文本標題");
builder.setStyle(inboxStyle);
builder.setDefaults(Notification.DEFAULT_SOUND);//設置默認鈴聲
manager.notify(4, builder.build());
}
private void else_custom()
{
RemoteViews views =new RemoteViews(getPackageName(),R.layout.remote);
NotificationCompat.Builder builder =new NotificationCompat.Builder(this);
builder.setContent(views);
builder.setSmallIcon(R.mipmap.ic_launcher);//設置了setContent屬性後,setSmallIcon就不生效了
builder.setContentTitle("自定義佈局");//設置了setContent屬性後,setContentTitle就不生效了
builder.setContentText("點擊聯繫人行可跳轉");//設置了setContent屬性後,setContentText就不生效了
builder.setAutoCancel(true);//設置點擊通知自動消失,8.0時並無用
builder.setOngoing(false);//true:左右滑動時通知不會消失 false:左右滑動時能夠滑動消失
builder.setDefaults(Notification.DEFAULT_SOUND);//設置默認鈴聲
Notification build = builder.build();
build.flags = Notification.FLAG_AUTO_CANCEL;
PendingIntent pendingIntent = PendingIntent.getActivity(this,1,
new Intent(Notifycation2Activity.this, NotifycationActivity.class),
PendingIntent.FLAG_UPDATE_CURRENT);
//當前設置表明點擊id爲R.id.but_re的按鈕時,要執行跳轉到TwoActivity頁面的操做
views.setOnClickPendingIntent(R.id.item, pendingIntent);
manager.notify(5, build);
}
複製代碼
// ========================== 如下是8.0上的通知==========================================
@RequiresApi(api = Build.VERSION_CODES.O)
private void btn_8_common() {
Notification.Builder builder =new Notification.Builder(this);
builder.setChannelId(id);//8.0必須設置信道
builder.setContentTitle("設置標題" + System.currentTimeMillis());
builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher));//設置大圖標
builder.setContentText("內容文本部分");
builder.setContentInfo("info信息");//設置info信息,即設置顯示在時間右下角的文字
builder.setSmallIcon(R.mipmap.ic_launcher);//必需要設置的小圖標
builder.setWhen(System.currentTimeMillis());//設置通知時間
builder.setTicker("設置滾動提示的文字");
builder.setOngoing(false);
num++;
manager.notify(num, builder.build());//發送通知
}
@RequiresApi(api = Build.VERSION_CODES.O)
private void btn_8_bigicon() {
Notification.Builder builder =new Notification.Builder(this);
builder.setChannelId(id);//8.0必須設置信道
builder.setSmallIcon(R.mipmap.ic_launcher);
builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.t1));//設置大圖標
builder.setContentTitle("大圖片通知");
builder.setContentText("內容文本部分");
builder.setTicker("大圖通知來了");
manager.notify(7, builder.build());
}
@RequiresApi(api = Build.VERSION_CODES.O)
private void btn_8_progress() {
final Notification.Builder builder =new Notification.Builder(this);
builder.setSmallIcon(R.mipmap.ic_launcher);
builder.setContentTitle("帶進度條的通知");
builder.setProgress(100,0,false);
builder.setChannelId(id);//8.0必須設置信道
manager.notify(3, builder.build());
new Thread(new Runnable() {
@Override
public void run() {
for (int i =0; i <=100; i++) {
builder.setProgress(100, i,false);
manager.notify(3,builder.build());
SystemClock.sleep(500);
}
}
}).start();
}
@RequiresApi(api = Build.VERSION_CODES.O)
private void btn_8_multi() {
Notification.InboxStyle inboxStyle =new Notification.InboxStyle();
for (int i =0; i <10; i++) {
inboxStyle.addLine("這是第" + i +"行" +"文本");
}
Notification.Builder builder =new Notification.Builder(this);
builder.setChannelId(id);
builder.setSmallIcon(R.mipmap.ic_launcher);
builder.setContentTitle("多行文本");
inboxStyle.setBigContentTitle("多行文本標題");
builder.setStyle(inboxStyle);
manager.notify(4, builder.build());
}
@RequiresApi(api = Build.VERSION_CODES.O)
private void btn_8_custom() {
RemoteViews views =new RemoteViews(getPackageName(),R.layout.remote);
Notification.Builder builder =new Notification.Builder(this);
builder.setContent(views);
builder.setSmallIcon(R.mipmap.ic_launcher);//設置了setContent屬性後,setSmallIcon就不生效了
builder.setContentTitle("自定義佈局");//設置了setContent屬性後,setContentTitle就不生效了
builder.setContentText("點擊聯繫人行可跳轉");//設置了setContent屬性後,setContentText就不生效了
builder.setChannelId(id);
builder.setAutoCancel(true);//設置點擊通知自動消失,8.0時並無用
builder.setOngoing(false);//true:左右滑動時通知不會消失 false:左右滑動時能夠滑動消失
Notification build = builder.build();
build.flags = Notification.FLAG_AUTO_CANCEL;
PendingIntent pendingIntent = PendingIntent.getActivity(this,1,
new Intent(Notifycation2Activity.this, NotifycationActivity.class),
PendingIntent.FLAG_UPDATE_CURRENT);
//當前設置表明點擊id爲R.id.but_re的按鈕時,要執行跳轉到TwoActivity頁面的操做
views.setOnClickPendingIntent(R.id.item, pendingIntent);
manager.notify(5, build);
}
}
複製代碼
=================================================
package gcg.testproject.activity.notifycation;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.Service;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.support.v7.app.NotificationCompat;
import android.view.View;
import android.widget.TextView;
import butterknife.Bind;
import butterknife.ButterKnife;
import gcg.testproject.R;
import gcg.testproject.base.BaseActivity;
import gcg.testproject.utils.LogUtils;
//參考連接:https://www.jianshu.com/p/f2cf23d6d836
public class NotifycationActivityextends BaseActivity{
@Bind(R.id.tv_send)
TextViewmTvSend;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_notifycation);
ButterKnife.bind(this);
//關閉通知欄上的通知
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
manager.cancel(5);
}
}
複製代碼
======================= 佈局文件 ====================
<TextView
android:id="@+id/tv_common"
android:gravity="center"
android:textColor="#fff"
android:textSize="20sp"
android:text="普統統知"
android:background="#4caf65"
android:layout_width="match_parent"
android:layout_height="50dp"/>
<TextView
android:layout_marginTop="@dimen/dp10"
android:id="@+id/tv_remove"
android:gravity="center"
android:textColor="#fff"
android:textSize="20sp"
android:text="移除通知"
android:background="#4caf65"
android:layout_width="match_parent"
android:layout_height="50dp"/>
<TextView
android:layout_marginTop="@dimen/dp10"
android:id="@+id/tv_bigicon"
android:gravity="center"
android:textColor="#fff"
android:textSize="20sp"
android:text="設置大圖通知"
android:background="#4caf65"
android:layout_width="match_parent"
android:layout_height="50dp"/>
<TextView
android:layout_marginTop="@dimen/dp10"
android:id="@+id/tv_progress"
android:gravity="center"
android:textColor="#fff"
android:textSize="20sp"
android:text="進度條通知"
android:background="#4caf65"
android:layout_width="match_parent"
android:layout_height="50dp"/>
<TextView
android:layout_marginTop="@dimen/dp10"
android:id="@+id/tv_multi"
android:gravity="center"
android:textColor="#fff"
android:textSize="20sp"
android:text="多行文本樣式通知"
android:background="#4caf65"
android:layout_width="match_parent"
android:layout_height="50dp"/>
<TextView
android:layout_marginTop="@dimen/dp10"
android:id="@+id/tv_custom"
android:gravity="center"
android:textColor="#fff"
android:textSize="20sp"
android:text="徹底自定義通知"
android:background="#4caf65"
android:layout_width="match_parent"
android:layout_height="50dp"/>
複製代碼