這篇要來寫關於android中"通知(Notification)"的用法
最近基於公司需求而開始研究它
就這樣研究了幾天..我覺得我最大的收穫是學會拼Notification這個單字ヾ(´¬`)ノ
沒有啦說笑的โ๏∀๏ใ
其實最近公司的專案有打算加入FCM推播通知
蛤?你問我FCM是什麼?
FCM全名為Firebase Cloud Message,就是你各位手機一天到晚收到的那個煩死人的廣播推播系統
以前端開發者的角度而言這是Google提供的一種推播服務
那今天我們不是要做,FCM那個下次(笑)
這次我們針對在手機前端的通知來做一個介紹
那麼,來看一下今天的範例吧!
以及Github
->https://github.com/thumbb13555/NotificationDemo
1. 檔案結構&介面
如圖
NotificationReceiver.java等一下再創,因為還有別的東西要設定(-‿◦)
我們可以先來弄介面
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <androidx.constraintlayout.widget.Guideline android:id="@+id/guideline" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" app:layout_constraintGuide_percent="0.5" /> <Button android:id="@+id/button_DefaultNotification" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="系統預設通知" app:layout_constraintBottom_toTopOf="@+id/guideline" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <Button android:id="@+id/button_CustomNotification" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="客製化通知" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="@+id/guideline" /> </androidx.constraintlayout.widget.ConstraintLayout>
以及這是給notification的介面
custom_notification.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:padding="10dp"> <TextView android:id="@+id/textView_Title" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Title" android:textAppearance="@style/TextAppearance.AppCompat.Body1" android:textStyle="bold" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <ImageView android:id="@+id/imageView_Icon" android:layout_width="50dp" android:layout_height="50dp" android:padding="5dp" app:srcCompat="@drawable/ic_launcher_background" /> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="end" android:orientation="horizontal"> <Button android:id="@+id/button_Noti_Hi" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="hi!" /> <Button android:id="@+id/button_Noti_Close" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="關閉" /> </LinearLayout> </LinearLayout> </LinearLayout>
備註:用於notification的Layout不能用ConstraintLayout!!
坦白說我也不知道為什麼...(;´д`)ゞ
我實測起來就是真的用了不會顯示(但不會閃退)
圖檔的部分在這,有需要去Github複製一下吧
2. 加入channel
在使用notification時,必須要先加入"channel"
具體的意義就是有點像是告訴系統"我要使用通知功能了喔!我的名在叫做XXX喔!"
這樣的感覺(゜ロ゜)
像是預先報備上級的概念吧( ̄ー ̄;
那在“通報上級”還要看你的公司環境
在Android8以下的手機使用功能是可以不用報備的
那麼具體來說,是這樣寫的(順便連按鈕相關事件也寫一寫)
粉底白字所包起來的內容就是重點
public class MainActivity extends AppCompatActivity { private String CHANNEL_ID = "Coder"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); /**檢查手機版本是否支援通知;若支援則新增"頻道"*/ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){ NotificationChannel channel = new NotificationChannel( CHANNEL_ID, "DemoCode", NotificationManager.IMPORTANCE_DEFAULT); NotificationManager manager = getSystemService(NotificationManager.class); assert manager != null; manager.createNotificationChannel(channel); } /**初始化介面控件與點擊事件*/ Button btDefault,btCustom; btDefault = findViewById(R.id.button_DefaultNotification); btCustom = findViewById(R.id.button_CustomNotification); btDefault.setOnClickListener(onDefaultClick); btCustom.setOnClickListener(onCustomClick); } /**點選"系統預設通知"*/ private View.OnClickListener onDefaultClick = new View.OnClickListener() { @Override public void onClick(View v) { } }; /**點選"客製化通知"*/ private View.OnClickListener onCustomClick = new View.OnClickListener() { @Override public void onClick(View v) { } };
3. 撰寫基本Notification
接下來就是撰寫基本版的通知了
通知的設置基本如下
NotificationCompat.Builder builder = new NotificationCompat.Builder(MainActivity.this,CHANNEL_ID) .setSmallIcon(R.drawable.ic_baseline_accessible_forward_24) .setContentTitle("哈囉你好!") .setContentText("跟你打個招呼啊~") .setAutoCancel(true) .setPriority(NotificationCompat.PRIORITY_HIGH) .setCategory(NotificationCompat.CATEGORY_MESSAGE);
如果英文還不錯的朋友應該看他方法的英文就知道大概在幹什麼了
由上而下是
設置小Icon
設置標題
設置內容
設置是否點到後自動消失
設置通知等級
設置通知類型
那這邊補上他方法的列表
->https://developer.android.com/reference/androidx/core/app/NotificationCompat.Builder
最後把通知發出去
/**發出通知*/ NotificationManagerCompat notificationManagerCompat = NotificationManagerCompat.from(MainActivity.this); notificationManagerCompat.notify(1,builder.build());
這部分的全部
/**點選"系統預設通知"*/ private View.OnClickListener onDefaultClick = new View.OnClickListener() { @Override public void onClick(View v) { /**建置通知欄位的內容*/ NotificationCompat.Builder builder = new NotificationCompat.Builder(MainActivity.this,CHANNEL_ID) .setSmallIcon(R.drawable.ic_baseline_accessible_forward_24) .setContentTitle("哈囉你好!") .setContentText("跟你打個招呼啊~") .setAutoCancel(true) .setPriority(NotificationCompat.PRIORITY_HIGH) .setCategory(NotificationCompat.CATEGORY_MESSAGE); /**發出通知*/ NotificationManagerCompat notificationManagerCompat = NotificationManagerCompat.from(MainActivity.this); notificationManagerCompat.notify(1,builder.build()); } };
到這邊就可以順利發出通知了(・ω・)b
接下來就是客製化通知的部分
4. 撰寫客製Notification+點擊事件
接著是客製的通知
客製的通知需要自已畫一個介面,而在最上面的部分我們已經把介面寫好了
剛剛沒加入?在這邊自己去複製
通知的View寫法跟我們一般認知的寫法有點不太一樣
他是靠RemoteViews去寫介面,然後在載入通知
如下
/**建立要嵌入在通知裡的介面*/ RemoteViews view = new RemoteViews(getPackageName(),R.layout.custom_notification); /**建置通知欄位的內容*/ NotificationCompat.Builder builder = new NotificationCompat.Builder(MainActivity.this,CHANNEL_ID) .setSmallIcon(R.drawable.ic_baseline_directions_bike_24) .setContent(view) .setAutoCancel(true) .setOnlyAlertOnce(true) .setPriority(NotificationCompat.PRIORITY_HIGH) .setCategory(NotificationCompat.CATEGORY_MESSAGE); NotificationManagerCompat notificationManagerCompat = NotificationManagerCompat.from(MainActivity.this); /**發出通知*/ notificationManagerCompat.notify(1,builder.build());
在這邊可以先執行一次,應該就會顯示客製通知了
那麼上面的元件又要如何取得他的控制呢?
如下
/**建立要嵌入在通知裡的介面*/ RemoteViews view = new RemoteViews(getPackageName(),R.layout.custom_notification); /**設置通知內的控件要做的事*/ /*設置標題*/ view.setTextViewText(R.id.textView_Title,"哈囉你好!"); /*設置圖片*/ view.setImageViewResource( R.id.imageView_Icon,R.drawable.ic_baseline_directions_bike_24); //以下略
兩個粉底白字的部分就是設置圖片&標題文字的方法
了解控件設置後,接下來就是點擊事件了
我們來設置NotificationReceiver.java吧
創的過程省略,我直接給你內容
public class NotificationReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { /**接收點擊事件*/ switch (intent.getAction()){ case "Hi": Toast.makeText(context, "哈囉!", Toast.LENGTH_SHORT).show(); break; case "Close": NotificationManager manager = (NotificationManager)context.getSystemService(NOTIFICATION_SERVICE); manager.cancel(1); break; } } }
然後來到AndroidManifest.xml
加入粉底白字的部分
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.jetec.notificationdemo"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <receiver android:name=".NotificationReceiver"/> </application> </manifest>
最後是點擊事件的部分
基本上
1. 設置一個Intent連結NotificationReceiver(紫)
2. 將Intent載入PendingIntent
3. 把PendingIntent放到指定的Button內(粉&藍)
/**建立要嵌入在通知裡的介面*/ RemoteViews view = new RemoteViews(getPackageName(),R.layout.custom_notification); /**初始化Intent,攔截點擊事件*/ Intent intent = new Intent(MainActivity.this,NotificationReceiver.class); /**設置通知內"Hi"這個按鈕的點擊事件(以Intent的Action傳送標籤,標籤為Hi)*/ intent.setAction("Hi"); PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.this ,0,intent,PendingIntent.FLAG_CANCEL_CURRENT); /**設置通知內"Close"這個按鈕的點擊事件(以Intent的Action傳送標籤,標籤為Close)*/ intent.setAction("Close"); PendingIntent close = PendingIntent.getBroadcast(MainActivity.this ,0,intent,PendingIntent.FLAG_CANCEL_CURRENT); /**設置通知內的控件要做的事*/ /*設置標題*/ view.setTextViewText(R.id.textView_Title,"哈囉你好!"); /*設置圖片*/ view.setImageViewResource( R.id.imageView_Icon,R.drawable.ic_baseline_directions_bike_24); /*設置"Hi"按鈕點擊事件(綁pendingIntent)*/ view.setOnClickPendingIntent(R.id.button_Noti_Hi,pendingIntent); /*設置"Close"按鈕點擊事件(綁close)*/ view.setOnClickPendingIntent(R.id.button_Noti_Close,close);
PO一下全部
/**點選"客製化通知"*/ private View.OnClickListener onCustomClick = new View.OnClickListener() { @Override public void onClick(View v) { /**建立要嵌入在通知裡的介面*/ RemoteViews view = new RemoteViews(getPackageName(),R.layout.custom_notification); /**初始化Intent,攔截點擊事件*/ Intent intent = new Intent(MainActivity.this,NotificationReceiver.class); /**設置通知內"Hi"這個按鈕的點擊事件(以Intent的Action傳送標籤,標籤為Hi)*/ intent.setAction("Hi"); PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.this ,0,intent,PendingIntent.FLAG_CANCEL_CURRENT); /**設置通知內"Close"這個按鈕的點擊事件(以Intent的Action傳送標籤,標籤為Close)*/ intent.setAction("Close"); PendingIntent close = PendingIntent.getBroadcast(MainActivity.this ,0,intent,PendingIntent.FLAG_CANCEL_CURRENT); /**設置通知內的控件要做的事*/ /*設置標題*/ view.setTextViewText(R.id.textView_Title,"哈囉你好!"); /*設置圖片*/ view.setImageViewResource( R.id.imageView_Icon,R.drawable.ic_baseline_directions_bike_24); /*設置"Hi"按鈕點擊事件(綁pendingIntent)*/ view.setOnClickPendingIntent(R.id.button_Noti_Hi,pendingIntent); /*設置"Close"按鈕點擊事件(綁close)*/ view.setOnClickPendingIntent(R.id.button_Noti_Close,close); /**建置通知欄位的內容*/ NotificationCompat.Builder builder = new NotificationCompat.Builder(MainActivity.this,CHANNEL_ID) .setSmallIcon(R.drawable.ic_baseline_directions_bike_24) .setContent(view) .setAutoCancel(true) .setOnlyAlertOnce(true) .setPriority(NotificationCompat.PRIORITY_HIGH) .setCategory(NotificationCompat.CATEGORY_MESSAGE); NotificationManagerCompat notificationManagerCompat = NotificationManagerCompat.from(MainActivity.this); /**發出通知*/ notificationManagerCompat.notify(1,builder.build()); } };
至此可以執行看看是否一切正常
接下來的就交給各位自己理解囉!(・ωー)~☆
最後PO一下全部
public class MainActivity extends AppCompatActivity { private String CHANNEL_ID = "Coder"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); /**檢查手機版本是否支援通知;若支援則新增"頻道"*/ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){ NotificationChannel channel = new NotificationChannel( CHANNEL_ID, "DemoCode", NotificationManager.IMPORTANCE_DEFAULT); NotificationManager manager = getSystemService(NotificationManager.class); assert manager != null; manager.createNotificationChannel(channel); } /**初始化介面控件與點擊事件*/ Button btDefault,btCustom; btDefault = findViewById(R.id.button_DefaultNotification); btCustom = findViewById(R.id.button_CustomNotification); btDefault.setOnClickListener(onDefaultClick); btCustom.setOnClickListener(onCustomClick); } /**點選"系統預設通知"*/ private View.OnClickListener onDefaultClick = new View.OnClickListener() { @Override public void onClick(View v) { /**建置通知欄位的內容*/ NotificationCompat.Builder builder = new NotificationCompat.Builder(MainActivity.this,CHANNEL_ID) .setSmallIcon(R.drawable.ic_baseline_accessible_forward_24) .setContentTitle("哈囉你好!") .setContentText("跟你打個招呼啊~") .setAutoCancel(true) .setPriority(NotificationCompat.PRIORITY_HIGH) .setCategory(NotificationCompat.CATEGORY_MESSAGE); /**發出通知*/ NotificationManagerCompat notificationManagerCompat = NotificationManagerCompat.from(MainActivity.this); notificationManagerCompat.notify(1,builder.build()); } }; /**點選"客製化通知"*/ private View.OnClickListener onCustomClick = new View.OnClickListener() { @Override public void onClick(View v) { /**建立要嵌入在通知裡的介面*/ RemoteViews view = new RemoteViews(getPackageName(),R.layout.custom_notification); /**初始化Intent,攔截點擊事件*/ Intent intent = new Intent(MainActivity.this,NotificationReceiver.class); /**設置通知內"Hi"這個按鈕的點擊事件(以Intent的Action傳送標籤,標籤為Hi)*/ intent.setAction("Hi"); PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.this ,0,intent,PendingIntent.FLAG_CANCEL_CURRENT); /**設置通知內"Close"這個按鈕的點擊事件(以Intent的Action傳送標籤,標籤為Close)*/ intent.setAction("Close"); PendingIntent close = PendingIntent.getBroadcast(MainActivity.this ,0,intent,PendingIntent.FLAG_CANCEL_CURRENT); /**設置通知內的控件要做的事*/ /*設置標題*/ view.setTextViewText(R.id.textView_Title,"哈囉你好!"); /*設置圖片*/ view.setImageViewResource( R.id.imageView_Icon,R.drawable.ic_baseline_directions_bike_24); /*設置"Hi"按鈕點擊事件(綁pendingIntent)*/ view.setOnClickPendingIntent(R.id.button_Noti_Hi,pendingIntent); /*設置"Close"按鈕點擊事件(綁close)*/ view.setOnClickPendingIntent(R.id.button_Noti_Close,close); /**建置通知欄位的內容*/ NotificationCompat.Builder builder = new NotificationCompat.Builder(MainActivity.this,CHANNEL_ID) .setSmallIcon(R.drawable.ic_baseline_directions_bike_24) .setContent(view) .setAutoCancel(true) .setOnlyAlertOnce(true) .setPriority(NotificationCompat.PRIORITY_HIGH) .setCategory(NotificationCompat.CATEGORY_MESSAGE); NotificationManagerCompat notificationManagerCompat = NotificationManagerCompat.from(MainActivity.this); /**發出通知*/ notificationManagerCompat.notify(1,builder.build()); } }; }
那麼這篇文章就寫到這裡了,FCM我之後也會寫...但等我先研究透徹就是了QQ
感謝各位的閱讀,希望本文有幫助到你(-‿◦)
那麼..
留言列表