有人知道Android 7.0(Nougat)与Android 6.0(Lollipop)相比如何处理意图附加功能有什么变化吗?
长话短说:我的应用程序可以在4.1(16)到6.0(23)的所有版本上运行,但在android 7.0(24)上崩溃了!
应用程序创建一个待定意图,意图是具有附加功能的自定义广播接收器。但是,在Android 7上,广播接收器收到的意图中没有任何附加内容。
public static async Task<TOut[]> ForEachAsync<TIn, TOut>(
IEnumerable<TIn> inputEnumerable,
Func<TIn, Task<TOut>> asyncProcessor,
int? maxDegreeOfParallelism = null)
{
IEnumerable<Task<TOut>> tasks;
if (maxDegreeOfParallelism != null)
{
SemaphoreSlim throttler = new SemaphoreSlim(maxDegreeOfParallelism.Value, maxDegreeOfParallelism.Value);
tasks = inputEnumerable.Select(
async input =>
{
await throttler.WaitAsync();
try
{
return await asyncProcessor(input).ConfigureAwait(false);
}
finally
{
throttler.Release();
}
});
}
else
{
tasks = inputEnumerable.Select(asyncProcessor);
}
await Task.WhenAll(tasks);
}
MainActivity.java
Intent intent = new Intent(context, PollServerReceiver.class);
// TODO: Remove after DEBUGGING is completed!
intent.putExtra("TESTING1", "testing1");
intent.putExtra("TESTING2", "testing2");
intent.putExtra("TESTING3", "testing3");
// PendingIntent to be triggered when the alarm goes off.
final PendingIntent pIntent = PendingIntent.getBroadcast(context,
PollServerReceiver.REQUEST_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT);
// Setup alarm to schedule our service runs.
AlarmManager alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarm.setRepeating(AlarmManager.RTC_WAKEUP, firstRun, freqMilis, pIntent);
PollServerReceiver.java
堆栈跟踪显然会将NullPointerException作为崩溃的原因。 如果它会在所有版本中崩溃,那就不会那么奇怪,但在这种情况下它只是最新的android。有人有任何想法吗?
注意:我尝试使用不同的标记创建待处理的意图,包括(Bundle extras = intent.getExtras();
Log.d(TAG, "onReceive: TESTING1 = " + extras.getString("TESTING1")); // null here
// None of the three "TESTING*" keys are there!
for (String key : extras.keySet()) {
Object value = extras.get(key);
Log.d(TAG, String.format("onReceive extra keys: %s %s (%s)", key, value.toString(), value.getClass().getName()));
}
,0
,PendingIntent.FLAG_UPDATE_CURRENT
)仍然得到完全相同的结果。
答案 0 :(得分:15)
将自定义Parcelable
放在PendingIntent
中从未如此可靠,it flat-out will not work in an AlarmManager
PendingIntent
on Android 7.0。其他进程可能需要将值填入Intent
,这涉及到操作附加内容,并且无法在任何进程中执行,而是自己的进程,因为没有其他进程具有您的自定义Parcelable
类
This SO answer有一种解决方法,其形式是Parcelable
将您自己转换为byte[]
。
答案 1 :(得分:2)
我有类似的问题,但我认为我找到了一个简单的解决方案。将您的数据放入Bundle中,并根据您的意图发送该Bundle。在我的情况下,我想用我的意图发送一个可序列化的对象。
设置闹钟:
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmReciever.class);
Bundle bundle = new Bundle();
//creating an example object
ExampleClass exampleObject = new ExampleClass();
//put the object inside the Bundle
bundle.putSerializable("example", exampleObject);
//put the Bundle inside the intent
intent.putExtra("bundle",bundle);
PendingIntent alarmIntent = PendingIntent.getBroadcast(context, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT);
//setup the alarm
alarmManager.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), alarmIntent);
收到警报:
public class AlarmReciever extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// get the Bundle
Bundle bundle = intent.getBundleExtra("bundle");
// get the object
ExampleClass exampleObject = (ExampleClass)bundle.getSerializable("example");
}
}
它对我来说很好。希望它有所帮助:)