React Native 實(shí)現(xiàn)iOS和Android自定義消息推送通知聲音

因?yàn)楣綼pp的需求,需要加個(gè)自定義消息推送通知聲音痹栖,因?yàn)椴欢沧康脑灾氨豢撕芫貌t空,查了很多資料揪阿,終于搞定了,下面分享iOS和Android環(huán)境下的如何根據(jù)后臺傳過來的參數(shù)來指定播放app端的消息通知聲音咆畏。
開始之前南捂,需要先安裝三方庫jpush-react-native,這里我就不詳細(xì)說了旧找,按照文檔做就可以了溺健。

iOS端

由于自定義通知聲音還是由 iOS 系統(tǒng)來播放的,所以對音頻數(shù)據(jù)格式有限制钮蛛,可以是如下四種之一:

Linear PCM
MA4 (IMA/ADPCM)
μLaw
aLaw
對應(yīng)音頻文件格式是 aiff鞭缭,wav,caf 文件愿卒,文件也必須放到 app 的 mainBundle 目錄中缚去。
自定義通知聲音的播放時(shí)間必須在 30s 內(nèi),如果超過這個(gè)限制琼开,則將用系統(tǒng)默認(rèn)通知聲音替代易结。
可以使用 afconvert 工具來處理音頻文件格式,在終端中敲入如下命令就可以將一個(gè) mp3 文件轉(zhuǎn)換成 caf 文件:

$ afconvert test.mp3 test.caf -d ima4 -f caff -v

轉(zhuǎn)換完成后就可以將 test.caf 這個(gè)文件拖入 Xcode 工程中柜候,編譯運(yùn)行項(xiàng)目在真機(jī)上搞动。


image.png

發(fā)送推送通知時(shí),只需后臺配置 sound 字段的值為導(dǎo)入到工程中的音頻文件名渣刷,這里即就是 test.caf鹦肿。

如果要用系統(tǒng)自帶的聲音,必須傳'default',不然app端就沒有聲音了辅柴。

iOS的就搞定了箩溃,是不是很簡單瞭吃。這里其實(shí)用不著jpush-react-native庫,只要還是為了下面的安卓使用的涣旨。

Android端

安卓端的就稍微有點(diǎn)復(fù)雜了歪架,因?yàn)椴欢沧康脑颍宋也簧贂r(shí)間霹陡。
首先將聲音文件放在raw目錄下和蚪,沒有此目錄自己創(chuàng)建一個(gè)

注意,此時(shí)就用到了jpush-react-native庫了烹棉,文件要放在庫里攒霹,還有一點(diǎn)就是安卓自定義聲音只支持發(fā)送自定義消息,發(fā)送普通通知是不可以的浆洗。

WechatIMG36.jpeg

然后到j(luò)push-react-native里的android/src/main/java/cn/jpush/reactnativejpush下找到JPushModule.java修改里面的代碼
找到接收自定義消息函數(shù)JPushReceiver催束,將里面的接收自定義函數(shù)代碼

public static class JPushReceiver extends BroadcastReceiver {

        public JPushReceiver() {
        }

        @Override
        public void onReceive(Context context, Intent data) {
            mCachedBundle = data.getExtras();
            if (JPushInterface.ACTION_MESSAGE_RECEIVED.equals(data.getAction())) {
                try {
                    String message = data.getStringExtra(JPushInterface.EXTRA_MESSAGE);
                    Logger.i(TAG, "收到自定義消息: " + message);
                    if (mRAC != null) {
                        WritableMap map = Arguments.createMap();
                        map.putString("message", message);
                        map.putString("extras", data.getExtras().getString(JPushInterface.EXTRA_EXTRA));
                        mRAC.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
                                .emit(RECEIVE_CUSTOM_MESSAGE, map);
                    } else {
                        mEvent = RECEIVE_CUSTOM_MESSAGE;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } else if (JPushInterface.ACTION_NOTIFICATION_RECEIVED.equals(data.getAction())) {

改成

public static class JPushReceiver extends BroadcastReceiver {

        public JPushReceiver() {
        }

        @Override
        public void onReceive(Context context, Intent data) {
            mCachedBundle = data.getExtras();
            if (JPushInterface.ACTION_MESSAGE_RECEIVED.equals(data.getAction())) {
               processCustomMessage(context, mCachedBundle);
                try {
                    String message = data.getStringExtra(JPushInterface.EXTRA_MESSAGE);
                    Logger.i(TAG, "收到自定義消息: " + message);
                    if (mRAC != null) {
                        WritableMap map = Arguments.createMap();
                        map.putString("message", message);
                        map.putString("extras", data.getExtras().getString(JPushInterface.EXTRA_EXTRA));
                        mRAC.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
                                .emit(RECEIVE_CUSTOM_MESSAGE, map);
                    } else {
                        mEvent = RECEIVE_CUSTOM_MESSAGE;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } else if (JPushInterface.ACTION_NOTIFICATION_RECEIVED.equals(data.getAction())) {

其實(shí)就是多加了一行processCustomMessage(context, mCachedBundle);
然后在寫processCustomMessage函數(shù)

private void processCustomMessage(Context context, Bundle bundle) {

            NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

            NotificationCompat.Builder notification = new NotificationCompat.Builder(context);

             String message = bundle.getString(JPushInterface.EXTRA_MESSAGE);
            String title = bundle.getString(JPushInterface.EXTRA_TITLE);
            notification.setAutoCancel(true)
                    .setContentText(message)
                    .setContentTitle(title)
                    .setSmallIcon(R.mipmap.ic_launcher);
            String extras = bundle.getString(JPushInterface.EXTRA_EXTRA);
            if (!TextUtils.isEmpty(extras)) {
                try {
                    JSONObject extraJson = new JSONObject(extras);
                    if (null != extraJson && extraJson.length() > 0) {

                        String sound = extraJson.getString("sound");
                        if("invite_price.mp3".equals(sound)){
                            notification.setSound(Uri.parse("android.resource://" + context.getPackageName() + "/" +R.raw.invite_price));
                        }else if("test.mp3".equals(sound)){
                            notification.setSound(Uri.parse("android.resource://" + context.getPackageName() + "/" +R.raw.test));
                        }else{
                            notification.setDefaults(1);
                        }

                    }
                } catch (JSONException e) {

                }

            }
            int timecurrentTimeMillis =(int)System.currentTimeMillis()/1000 ;
            Intent intent = new Intent();
            intent.setClass(context, JPushReceiver.class);
            intent.setAction(JPushInterface.ACTION_NOTIFICATION_OPENED);
            intent.putExtras(bundle);
            PendingIntent pendingIntent = PendingIntent.getBroadcast(context, timecurrentTimeMillis, intent, PendingIntent.FLAG_ONE_SHOT);
            notification.setContentIntent(pendingIntent);
            notificationManager.notify(timecurrentTimeMillis, notification.build());
}

注意后臺傳給你的參數(shù)是在extras里的,里面的sound字段就對應(yīng)你本地的文件名辅髓,比如我這里的invite_price.mp3文件泣崩,sound即為'invite_price.mp3',如果想要使用系統(tǒng)默認(rèn)的,那就傳個(gè)不存在的文件名洛口,統(tǒng)一最好就用'default'吧矫付。timecurrentTimeMillis是通知唯一標(biāo)識符,如果不設(shè)置的話第焰,相當(dāng)于id一直沒變买优,這樣會(huì)導(dǎo)致新的通知會(huì)覆蓋舊的通知,通知列表永遠(yuǎn)只有1個(gè)挺举。最后如果提示有紅色的未定義的函數(shù)名杀赢,引入一下就好了。

      int timecurrentTimeMillis =(int)System.currentTimeMillis()/1000 ;
      Intent intent = new Intent();
      intent.setClass(context, JPushReceiver.class);
      intent.setAction(JPushInterface.ACTION_NOTIFICATION_OPENED);
      intent.putExtras(bundle);
      PendingIntent pendingIntent = PendingIntent.getBroadcast(context, timecurrentTimeMillis, intent, PendingIntent.FLAG_ONE_SHOT);
      notification.setContentIntent(pendingIntent);
      notificationManager.notify(timecurrentTimeMillis, notification.build());

這塊代碼的意思是點(diǎn)擊通知并且發(fā)送到廣播里湘纵,這樣在js里就可以通過JPushModule.addReceiveOpenNotificationListener()來監(jiān)聽到點(diǎn)擊通知的事件脂崔。

至此,iOS和Android的自定義通知聲音就OK啦梧喷。如果有哪里寫的不好的砌左,還望指正啊,不明白的也可以在下面留言铺敌,我看到就會(huì)回復(fù)的汇歹。或者加jpush-react-native官方群553406342

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末偿凭,一起剝皮案震驚了整個(gè)濱河市产弹,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌弯囊,老刑警劉巖痰哨,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件胶果,死亡現(xiàn)場離奇詭異,居然都是意外死亡斤斧,警方通過查閱死者的電腦和手機(jī)稽物,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來折欠,“玉大人,你說我怎么就攤上這事吼过∪袂兀” “怎么了?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵盗忱,是天一觀的道長酱床。 經(jīng)常有香客問我,道長趟佃,這世上最難降的妖魔是什么扇谣? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮闲昭,結(jié)果婚禮上罐寨,老公的妹妹穿的比我還像新娘。我一直安慰自己序矩,他們只是感情好鸯绿,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著簸淀,像睡著了一般瓶蝴。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上租幕,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天舷手,我揣著相機(jī)與錄音,去河邊找鬼劲绪。 笑死男窟,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的珠叔。 我是一名探鬼主播蝎宇,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼祷安!你這毒婦竟也來了姥芥?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤汇鞭,失蹤者是張志新(化名)和其女友劉穎凉唐,沒想到半個(gè)月后庸追,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡台囱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年淡溯,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片簿训。...
    茶點(diǎn)故事閱讀 38,569評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡咱娶,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出强品,到底是詐尸還是另有隱情膘侮,我是刑警寧澤,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布的榛,位于F島的核電站琼了,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏夫晌。R本人自食惡果不足惜雕薪,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望晓淀。 院中可真熱鬧所袁,春花似錦、人聲如沸凶掰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽锄俄。三九已至局劲,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間奶赠,已是汗流浹背鱼填。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留毅戈,地道東北人苹丸。 一個(gè)月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像苇经,于是被迫代替她去往敵國和親赘理。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評論 2 348

推薦閱讀更多精彩內(nèi)容