gpt4 book ai didi

android - DP5 7.0 - 向未决 Intent 添加额外内容会失败吗?

转载 作者:塔克拉玛干 更新时间:2023-11-02 09:02:00 26 4
gpt4 key购买 nike

在跟踪器上添加链接问题: 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);
}

我的“SET_NOTIFICATION_INTENT”的 AlarmManagerUtil @onReceive 看起来像这样:

public void fireNotification(Context context, Intent intent) {
List<Reminder> reminderToFire = Parcels.unwrap(intent.getParcelableExtra(REMINDER_EXTRA));
long timeToFire = intent.getLongExtra("time", 0L); //.... }

奇怪的是“reminderToFire”在这里仅在 Android N 设备上为空,但 timeToFire 是正确的。

我认为它与 Parceler 库有关?我正在使用 Java 1.8 进行编译并以 Android API 24 为目标。

我确实在网上四处寻找这个问题的答案,但我的情况有点独特,因为代码 100% 适用于所有先前版本的 Android(N 预览版以下的所有内容)...所以我正在关注尽我所能回答以下问题:

How can I correctly pass unique extras to a pending intent?

还有其他人有这个问题吗?

最佳答案

对于任何最终在 AlarmManager 上大发雷霆(还没有放弃并转向 JobScheduler)的人来说,Google 在生产 API 24 构建中不支持将 Parcelable 对象传递到 AlarmManager。

我解决这个问题的方式:如果您需要将列表(或单个对象)发送到 AlarmManager,请将该项目作为字符串存储到 SharedPreferences 中。 (Gson.toJson(object, type)) 如果对象是一个接口(interface),那么有很多接口(interface)适配器解决方案。我发现一个漂浮在 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;
}
}

设置好适配器后,如果您正在使用某种 DI 框架(即 Dagger2),则无需每次都使用 TypeAdapter 设置 GS0N...

@Singleton
@Provides
public Gson providesGson() {
return new GsonBuilder()
.registerTypeAdapter(YourInterfaceClass.class, new InterfaceAdapter<YourInterfaceClass>())
.create();

所以你所要做的就是运行......

/**
* 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();
}

希望这对您有所帮助。当然,当您需要从共享首选项中获取此对象时......

String json = sharedPrefs.getString(YOUR_KEY, "No object found");

执行典型的 List object = gson.fromJson(json, type) 应该可行。

干杯。

关于android - DP5 7.0 - 向未决 Intent 添加额外内容会失败吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38466080/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com