Ace*_*z44 8 android alarmmanager android-notifications parceler android-7.0-nougat
在跟踪器上添加关联问题:https://code.google.com/p/android/issues/detail? id = 216581 & thanks = 216581 & ts = 1468962325
所以我今天在我的Nexus 5X上安装了DP5 Android 7.0版本.我一直在开发一个应用程序,它使用Android的AlarmManager类在特定时间安排本地通知.在此版本发布之前,代码在运行KitKat,Lollipop和Marshmallow的设备上运行良好.
以下是我如何安排警报:
Intent intent = new Intent(context, AlarmManagerUtil.class);
intent.setAction(AlarmManagerUtil.SET_NOTIFICATION_INTENT);
intent.putExtra(AlarmManagerUtil.REMINDER_EXTRA, Parcels.wrap(reminders));
intent.putExtra("time", when.getMillis());
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
if (alarmManager != null) {
if (Build.VERSION.SDK_INT >= 23) {
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, when.getMillis(), pendingIntent);
} else if (Build.VERSION.SDK_INT >= 19) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, when.getMillis(), pendingIntent);
} else {
alarmManager.set(AlarmManager.RTC_WAKEUP, when.getMillis(), pendingIntent);
}
Run Code Online (Sandbox Code Playgroud)
我的AlarmManagerUtil @onReceive的"SET_NOTIFICATION_INTENT"如下所示:
public void fireNotification(Context context, Intent intent) {
List<Reminder> reminderToFire = Parcels.unwrap(intent.getParcelableExtra(REMINDER_EXTRA));
long timeToFire = intent.getLongExtra("time", 0L); //.... }
Run Code Online (Sandbox Code Playgroud)
奇怪的是,"reminderToFire" 仅在Android N设备上为空,但timeToFire是正确的.
我在想它与Parceler图书馆有什么关系?我正在使用Java 1.8编译并针对Android API 24.
我肯定在网上寻找答案,但我的情况有点独特,因为代码100%适用于所有先前版本的Android(N预览下面的所有内容)...所以我遵循以下答案尽我所能:
还有其他人有这个问题吗?
对于任何人结束了在这里拉你的头发了AlarmManager(并没有放弃,并去的jobscheduler还),谷歌在生产API构建24不支持传递Parcelable对象到AlarmManager.
解决这个问题的方法:如果需要将一个List(或单个对象)发送到AlarmManager,请将该项目作为String存储到SharedPreferences中.(Gson.toJson(object,type))如果对象是一个接口,那里有许多接口适配器解决方案.一个我发现在S/O周围漂浮:
public final class InterfaceAdapter<T> implements JsonSerializer<T>, JsonDeserializer<T> {
public JsonElement serialize(T object, Type interfaceType, JsonSerializationContext context) {
final JsonObject wrapper = new JsonObject();
wrapper.addProperty("type", object.getClass().getName());
wrapper.add("data", context.serialize(object));
return wrapper;
}
public T deserialize(JsonElement elem, Type interfaceType, JsonDeserializationContext context) throws JsonParseException {
final JsonObject wrapper = (JsonObject) elem;
final JsonElement typeName = get(wrapper, "type");
final JsonElement data = get(wrapper, "data");
final Type actualType = typeForName(typeName);
return context.deserialize(data, actualType);
}
private Type typeForName(final JsonElement typeElem) {
try {
return Class.forName(typeElem.getAsString());
} catch (ClassNotFoundException e) {
throw new JsonParseException(e);
}
}
private JsonElement get(final JsonObject wrapper, String memberName) {
final JsonElement elem = wrapper.get(memberName);
if (elem == null)
throw new JsonParseException("no '" + memberName + "' member found in what was expected to be an interface wrapper");
return elem;
}
}
Run Code Online (Sandbox Code Playgroud)
一旦你设置了适配器,如果你正在使用某种DI框架(即Dagger2),你就不需要每次使用TypeAdapter设置GS0N ......
@Singleton
@Provides
public Gson providesGson() {
return new GsonBuilder()
.registerTypeAdapter(YourInterfaceClass.class, new InterfaceAdapter<YourInterfaceClass>())
.create();
Run Code Online (Sandbox Code Playgroud)
所以你要做的就是跑......
/**
* stores yourInterfaceClass in shared prefs
*/
public void setNextReminder(List<YourInterfaceClass> yourInterfaceClass) {
Type type = new TypeToken<List<YourInterfaceClass>>() {}.getType();
sharedPrefs.edit().putString(YOUR_KEY, gson.toJson(yourInterfaceClass, type)).apply();
}
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助.当然,当你需要从共享的prefs中获取这个对象....
String json = sharedPrefs.getString(YOUR_KEY, "No object found");
Run Code Online (Sandbox Code Playgroud)
做典型的List object = gson.fromJson(json,type)应该可行.
干杯.
| 归档时间: |
|
| 查看次数: |
1133 次 |
| 最近记录: |