java - 如何通过 PendingIntent 将自定义可序列化对象传递给 BroadcastReceiver

标签 java android android-pendingintent android-broadcastreceiver

我正在尝试使用 PendingIntent 将自定义序列化对象从我的 IntentService 传递到 BroadcastReceiver。

这是我的自定义对象:

行.java

public class Row implements Serializable {
    private String name;
    private String address;

    public Row(BluetoothDevice device) {
        this.name = device.getName();
        this.address = device.getAddress();
    }
}

这是我的 IntentService

MyIntentService.java

public class MyIntentService extends IntentService {

    public MyIntentService() {
        super("MyIntentService");
    }

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    protected void onHandleIntent(Intent workIntent) {
        AlarmManager alarmMgr;
        PendingIntent alarmPendingIntent;
        Intent alarmIntent;
        // The object "RowsList" is passed from my MainActivity and is correctly received by my IntentService.
        // NO PROBLEMS HERE
        Row[] arrRows = (Row[])workIntent.getSerializableExtra("RowsList");

        Log.i(TAG, "Inside Intent Service...");

        int interval = 2;
        try{
            if(interval != 0) {
                alarmMgr = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
                alarmIntent = new Intent(this, AlarmReceiver.class);
                alarmIntent.putExtra("IntentReason", "Reason"); // THIS GETS PASSED
                alarmIntent.putExtra("RowsList", arrRows); // THIS DOES NOT GET PASSED
                alarmPendingIntent = PendingIntent.getBroadcast(this, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);

                alarmMgr.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + (interval * 1000), alarmPendingIntent);
                }
        }
        catch (Exception ignored){}
    }
}

主 Activity .java

// NO PROBLEMS HERE
private Intent myIntent;
myIntent = new Intent(getApplicationContext(), MyIntentService.class);
Log.i(TAG, "Starting Intent Service...");

myIntent.putExtra("RowsList", arrRows);
getApplicationContext().startService(intentListenBT);

这是我的广播接收器:

AlarmReceiver.java

public class AlarmReceiver extends BroadcastReceiver {

    Row[] arrRows;

    @Override
    public void onReceive(Context context, Intent intent) {
        this.context = context;
        String str = intent.getStringExtra("IntentReason"); // RECEIVED AS "Reason"
        arrRows = (Row[])intent.getSerializableExtra("RowsList"); // HERE IT IS null
    }
}

最烦人的部分是这段代码之前在我的 Nexus 6P (Lollipop 6.0 API23) 上运行。一旦我将同一部手机更新到 Android 7.0(Nougat),它就停止工作了。 Nougat 中是否有任何变化导致此问题?

注意:

我在带有 API 23 的 Nexus 6P 上使用模拟器运行我的代码,它工作正常。

最佳答案

您很可能遇到与 custom Parcelable implementations 相同的问题.从该博客文章中解释我自己:基本上,如果一个核心操作系统进程需要修改 Intent extras,该进程最终会尝试重新创建您的 Serializable 对象作为设置的一部分extras Bundle 用于修改。该进程没有您的类,因此会出现运行时异常。

The most annoying part is that this code was working previously on my Nexus 6P (Lollipop 6.0 API23).

行为会因 Android 版本、您使用 PendingIntent 的方式以及可能因固件/ROM 而异。不要假设您当前的实现在任何 Android 版本上都是可靠的。

您唯一的选择是不要将 Serializable 直接放在 Intent extra 中。使用 Serializable 以外的东西(例如,嵌套的 Bundle),将 Serializable 转换为 byte[],等

This sample app演示后一种方法,应用于 Parcelable 对象。 same basic technique应该适用于 Serializable。 (向 AyeVeeKay 提示评论中的链接)。

关于java - 如何通过 PendingIntent 将自定义可序列化对象传递给 BroadcastReceiver,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39209579/

相关文章:

java - Location Manager.RequestLocationUpdates 使用 pendingIntent 始终广播相同的位置,当 gps 提供商需要很长时间才能获取位置时

java - 检查 AlarmManager 任务是否正在进行

java - 删除此 token (其他)

java - 如何在饼图扇区内显示值

java - 与 postgreSQL 数据库连接的非法 UTF-8 序列

android - 更改微调器背景会生成深色边框

android - java.lang.NoSuchFieldError : no "Ljava/lang/String;" field JNI 错误

java - Android:IllegalStateException 调用 DialogFragment

android - 如何找出Android应用程序需要的权限

android - 如何获取在关机和开机之间传递的警报通知