這篇要來寫關於android中"通知(Notification)"的用法

最近基於公司需求而開始研究它

就這樣研究了幾天..我覺得我最大的收穫是學會拼Notification這個單字ヾ(´¬`)ノ

 

沒有啦說笑的โ๏∀๏ใ

 

其實最近公司的專案有打算加入FCM推播通知

蛤?你問我FCM是什麼?

FCM全名為Firebase Cloud Message,就是你各位手機一天到晚收到的那個煩死人的廣播推播系統

以前端開發者的角度而言這是Google提供的一種推播服務

 

那今天我們不是要做,FCM那個下次(笑)

這次我們針對在手機前端的通知來做一個介紹

 

那麼,來看一下今天的範例吧!

 

以及Github

->https://github.com/thumbb13555/NotificationDemo

 


 

1. 檔案結構&介面

 

如圖

截圖 2020-12-05 下午3.52.54

 

NotificationReceiver.java等一下再創,因為還有別的東西要設定(-‿◦)

我們可以先來弄介面

 

activity_main.xml

Screenshot_1607155250

 

<?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

截圖 2020-12-05 下午4.09.18

 

<?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複製一下吧

->https://github.com/thumbb13555/NotificationDemo/blob/master/app/src/main/res/drawable/ic_baseline_accessible_forward_24.xml

->https://github.com/thumbb13555/NotificationDemo/blob/master/app/src/main/res/drawable/ic_baseline_directions_bike_24.xml

 


 

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+點擊事件

 

接著是客製的通知

客製的通知需要自已畫一個介面,而在最上面的部分我們已經把介面寫好了

剛剛沒加入?在這邊自己去複製

->https://github.com/thumbb13555/NotificationDemo/blob/master/app/src/main/res/layout/custom_notification.xml

 

通知的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());

 

在這邊可以先執行一次,應該就會顯示客製通知了

Screenshot_1607158716

 

那麼上面的元件又要如何取得他的控制呢?

如下

/**建立要嵌入在通知裡的介面*/
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吧

創的過程省略,我直接給你內容

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

加入粉底白字的部分

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一下全部

 

MainActivity.java

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

感謝各位的閱讀,希望本文有幫助到你(-‿◦)

 

那麼..

TK

arrow
arrow
    創作者介紹
    創作者 碼農日常 的頭像
    碼農日常

    碼農日常大小事

    碼農日常 發表在 痞客邦 留言(8) 人氣()