Android 7.0 BroadcastReceiver接收pendingIntent 傳遞過來序列化數(shù)據(jù)

問題比較少見,只有你在跨進程傳遞數(shù)據(jù)的時候會碰到,如pendingIntent中

在7.0中通過pendingIntent的bundle傳遞的數(shù)據(jù)時,你會發(fā)現(xiàn)serializable和parcelable的數(shù)據(jù)拿不到

如果你只傳了string,那是沒問題的,但是如果你傳了string和一個serializable你會發(fā)現(xiàn),不光serializable拿不到,連string也拿不到了,黑人問好臉吧

原因參考:

https://commonsware.com/blog/2016/07/22/be-careful-where-you-use-custom-parcelables.html

解決方案:

https://stackoverflow.com/questions/18000093/how-to-marshall-and-unmarshall-a-parcelable-to-a-byte-array-with-help-of-parcel/18000094#18000094

他的解決方法很獨特,將所有數(shù)據(jù)轉為基本類型bytes再去傳遞,當然,這可以解決我們的問題

然后我就想既然byte能解決,只傳string也沒問題,那為什么不干脆直接傳string嗯,所以另一個簡單的修改方法就是把所有的對象全部轉成jsonstring去傳遞,也可以解決問題

然后續(xù)繼續(xù)尋找有沒有更加合適的方案時發(fā)現(xiàn)google的issuetracker中有個大神發(fā)現(xiàn)了一個更簡單的方法,直接把所有數(shù)據(jù)放到bundle里,然后將bundler作為參數(shù)傳遞即intent.putExtra("data",bundle)也可以解決問題

詳情參考:

https://issuetracker.google.com/issues/37097877

以下是簡單例子:

public class LongRunningService extends Service {

? ? private MeasurePlan measurePlan;

? ? @Nullable

? ? @Override

? ? public IBinder onBind(Intent intent) {

? ? ? ? return null;

? ? }

? ? @Override

? ? public int onStartCommand(Intent intent, int flags, int startId) {

? ? ? AlarmManager manager = (AlarmManager) getSystemService(ALARM_SERVICE);

? ? ? Intent intent = new Intent(this, AlarmReceiver.class);? //AlarmReceiver:繼承BroadcastReceiver的類

? ? ? Bundle bundle = new Bundle();

? ? ? bundle.putSerializable("MeasurePlan", measurePlan); //measurePlan:要傳遞的實體類

? ? ? intent.putExtra("data",bundle);

? ? ? //參數(shù):getBroadcast(Context?context,?int?requestCode,?Intent?intent,?int?flags),flag是標記的意思,可以通過PendingIntent點調用不同標記

? ? ? PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, 0);

? ? ? //ELAPSED_REALTIME_WAKEUP表示讓定時任務的出發(fā)時間從系統(tǒng)開機算起,并且會喚醒CPU。

? ? ? manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, pi);

? }

}

AlarmManager里面一些方法?:

1.set(int type,long startTime,PendingIntent pi);

該方法用于設置一次性鬧鐘,第一個參數(shù)表示鬧鐘類型,第二個參數(shù)表示鬧鐘執(zhí)行時間,第三個參數(shù)表示鬧鐘響應動作。

2.setRepeating(int type,long triggerAtTime,long intervalTime,PendingIntent pi);

該方法用于設置重復鬧鐘,第一個參數(shù)表示鬧鐘類型,第二個參數(shù)表示鬧鐘首次執(zhí)行時間,第三個參數(shù)表示鬧鐘兩次執(zhí)行的間隔時間, 第三個參數(shù)表示鬧鐘響應動作。

3.setInexactRepeating(int type,long startTime,long intervalTime,PendingIntent pi);

該方法也用于設置重復鬧鐘,與第二個方法相似,不過其兩個鬧鐘執(zhí)行的間隔時間不是固定的而已。

type:鬧鐘類型,有五個可選值

1.ELAPSED_REALTIME:以手機開機的時間為基準

2.ELAPSED_REALTIME_WAKEUP:以手機開機的時間為基準,并且可以在休眠時發(fā)出廣播

3.RTC:以UTC標準時間為基準

4.RTC_WAKEUP:以UTC標準時間為基準,并且可以在休眠時發(fā)出廣播。這種方式是最常見的形式。

5.POWER_OFF_WAKEUP:關機狀態(tài)下也能進行提示

long startTime:

表示鬧鐘第一次執(zhí)行的時間,可以自己設置,也可以使用系統(tǒng)當前時間,以毫秒為單位。本屬性與第?

一個屬性(type)密切相關,如果第一個參數(shù)對 應的鬧鐘使用的是相對時間(ELAPSED_REALTIME和ELAPSED_REALTIME_WAKEUP), 那么本屬性就得使用相對時間(相對于 系統(tǒng)啟動時間來?

說),比如當前時間就表示為:SystemClock.elapsedRealtime(); 如果第一個參數(shù)對應的鬧鐘使用的是絕對時間 (RTC、RTC_WAKEUP、POWER_OFF_WAKEUP),那么本屬性就得使用絕對時間, 比如當前時間就表示 為:System.currentTimeMillis()。

long intervalTime:?

鬧鐘的間隔時間,也是毫秒為單位。

PendingIntent pi:?

這個就是我們可以執(zhí)行的動作,可以去啟動一個service,發(fā)送一個廣播,啟動一個activity,方法一看就明白了。?

最后一個小提示:?

Calendar.HOUR_OF_DAY (24小時)?

Calendar.HOUR (12小時)

完成之后在自定義類中獲取數(shù)據(jù):

public class AlarmReceiver extends BroadcastReceiver {

? ? private MeasurePlan measurePlan;

? ? private MedicinePlan medicinePlan;

? ? @Override

? ? public void onReceive(Context context, Intent intent) {

? ? Bundle data = intent.getBundleExtra("data");

? ? medicinePlan = (MedicinePlan)data.get("MedicinePlan");

? }

}

最后是清單文件AndroidManifest.xml的注冊:

<service android:name=".activitys.inform.remindservice.LongRunningService" />

<receiver

? ? android:name=".activitys.inform.remindservice.AlarmReceiver">

</receiver>

---------------------

作者:EncounterTo

來源:CSDN

原文:https://blog.csdn.net/EncounterTo/article/details/79305324

版權聲明:本文為博主原創(chuàng)文章,轉載請附上博文鏈接!

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容