如何通过PendingIntent

时间:2016-08-29 15:11:36

标签: java android android-pendingintent android-broadcastreceiver

我正在尝试使用PendingIntent将自定义的Serialized对象从我的IntentService传递给BroadcastReceiver。

这是我的自定义对象:

Row.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){}
    }
}

MainActivity.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);

这是我的BroadcastReceiver:

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),它就停止了工作。在牛轧糖中是否有任何改变导致了这个问题?

注:

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

1 个答案:

答案 0 :(得分:15)

最有可能的是,您遇到了与custom Parcelable implementations相同的问题。从博客文章中解释自己:基本上,如果核心操作系统流程需要修改Intent个额外内容,那么该过程最终会尝试重新创建Serializable个对象,作为设置附加内容的一部分{{1}用于修改。该过程没有您的类,因此它会获得运行时异常。

  

最令人讨厌的部分是此代码之前在我的Nexus 6P(Lollipop 6.0 API23)上运行。

行为因Android版本,Bundle的使用方式以及固件/ ROM的使用方式而异。不要认为您当前的实现在任何Android版本上都是可靠的。

您唯一的选择是不要将PendingIntent直接放在Serializable额外费用中。使用Intent以外的内容(例如,嵌套Serializable),将Bundle转换为Serializable等等。

This sample app演示了后一种方法,适用于byte[]对象。 same basic technique适用于Parcelable。 (给评论中的链接提示AyeVeeKay。)