開啟前臺(tái)服務(wù)

這兩天開始做一個(gè)音樂播放器,慢慢完善功能,打算把遇到的一些問題記下來,故對(duì)代碼沒有什么解釋。。希望讀者能有所收獲。
為了能讓讀者看的不那么難受,我把代碼拆開來講(完整的代碼就是拆分的拼起來),包括筆者遇到的兩個(gè)報(bào)異常的地方,解決后終于成功開啟。
效果圖在最后(簡(jiǎn)陋版看看就好)

如果哪里有誤歡迎指正,不,請(qǐng)務(wù)必指正。

先初始化我們定義的Layout

這個(gè)Layout就是下拉菜單欄顯示的樣式。

        views = new RemoteViews(getPackageName(), R.layout.notification_music);
        views.setTextViewText(R.id.tv_playmusic, musics.get(curMusic).getMusic());
        views.setTextViewText(R.id.tv_playsinger, musics.get(curMusic).getSinger());

RemoteViews能夠支持更改Layout中控件用到的資源(如更換背景),使用
setInt(int viewId, String methodName, int value),
其中methodName是調(diào)用的方法名(實(shí)際是以方法名通過反射),value是資源文件的id。

定義Layout中控件的點(diǎn)擊效果

        //next music
        Intent intentSkipNext = new Intent(MusicChangedReceiver.Action_Notification_SkipNext);
        PendingIntent skipNextPendingIntent = PendingIntent.getBroadcast(this, NEXT_PENDINGINTENT_REQUESTCODE,
                intentSkipNext, PendingIntent.FLAG_CANCEL_CURRENT);
        views.setOnClickPendingIntent(R.id.btn_skip_next, skipNextPendingIntent);

這部分只貼一個(gè),實(shí)際是通過發(fā)送廣播實(shí)現(xiàn)的,需要綁定一個(gè)BroadcastReceiver來接受廣播,在通過switch分Action進(jìn)行對(duì)應(yīng)處理。

定義點(diǎn)擊Notification的動(dòng)作(就是Layout除去定義了點(diǎn)擊事件的控件的位置)

我這里的動(dòng)作是啟動(dòng)MainActivity(設(shè)置了singleTask的啟動(dòng)模式)
注意這里沒有把PendingIntent放入RemoteViews中,而是要直接設(shè)置在Notification中(下一部分)

        Intent intentContent = new Intent(this, MainActivity.class);
        PendingIntent contentPendingIntent = PendingIntent.getActivity(this, CONTENT_PENDINGINTENT_REQUESTCODE,
                intentContent, PendingIntent.FLAG_CANCEL_CURRENT);

定義Notification移除時(shí)的動(dòng)作

我沒有定義,暫時(shí)沒這個(gè)需求。

創(chuàng)建Notification.Builder

從這里就可以看出來Notification使用了Builder模式
其中 setSmallIcon, setContentTitle, setContentText 是必須要有的,不然會(huì)出現(xiàn)異常前臺(tái)開啟失敗,反正最后不會(huì)顯示出來(因?yàn)樵O(shè)置了自定義的布局)

        builder = new Notification.Builder(this)
                // 設(shè)置小圖標(biāo)
                .setSmallIcon(R.drawable.ic_stop_red_40dp)
                // 設(shè)置標(biāo)題
                .setContentTitle("nemuniPlayer")
                // 設(shè)置內(nèi)容
                .setContentText("content")
                .setAutoCancel(false)
                //這里設(shè)置點(diǎn)擊Notification的動(dòng)作
                //這里設(shè)置點(diǎn)擊Notification的動(dòng)作
                //這里設(shè)置點(diǎn)擊Notification的動(dòng)作
                .setContentIntent(contentPendingIntent)
                .setContent(views);

獲取NotificationManager

        notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

!重點(diǎn)!設(shè)置NotificationChannel,8.0以上不設(shè)會(huì)報(bào)異常啟動(dòng)失敗

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            String CHANNEL_ID = "com.example.nemuni.channel";
            String CHANNEL_NAME = "Music Channel";
            NotificationChannel notificationChannel= new NotificationChannel(CHANNEL_ID, CHANNEL_NAME,
                    NotificationManager.IMPORTANCE_HIGH);
            notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
            notificationManager.createNotificationChannel(notificationChannel);
            builder.setChannelId(CHANNEL_ID);
        }

(我是不會(huì)說ID和NAME的命名都是我隨意的,確保ID唯一應(yīng)該就沒問題了吧)

剩下的就是啟動(dòng)了

        startForeground(NOTIFICATION_PENDINGINTENT_ID, builder.build());

這里的ID我使用了進(jìn)程的ID(反正我也就啟動(dòng)這一個(gè)前臺(tái)服務(wù))
private static final int NOTIFICATION_PENDINGINTENT_ID = android.os.Process.myPid();

順便貼onDestroy()里的取消操作吧

        if (notificationManager != null) {
            notificationManager.cancel(NOTIFICATION_PENDINGINTENT_ID);
            stopForeground(true);
        }
效果圖
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容