Scheduled local notifications on Android will now persist across reboots like on iOS.

Commiting changes from post-commit review.
#rnx
#rb Chris.Babcock, Pete.Procopio


#ROBOMERGE-SOURCE: CL 7265680 via CL 7271181
#ROBOMERGE-BOT: (v369-7254125)

[CL 7271330 by francois guimond in Main branch]
This commit is contained in:
francois guimond
2019-07-10 21:32:14 -04:00
parent d2f1547d3f
commit 7d276102ff
4 changed files with 101 additions and 35 deletions

View File

@@ -6,59 +6,109 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import org.json.JSONException;
import org.json.JSONObject;
import java.lang.ref.WeakReference;
import java.util.Iterator;
public class BootCompleteReceiver extends BroadcastReceiver
{
public static Logger Log = new Logger("UE4", "BootCompleteReceiver");
@Override
public void onReceive(Context context, Intent intent)
{
// restore any scheduled notifications
SharedPreferences preferences = context.getSharedPreferences("LocalNotificationPreferences", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
try
PendingResult pendingResult = goAsync();
Task task = new Task(pendingResult, context);
task.execute();
}
private static class Task extends AsyncTask<Void, Void, Void>
{
private PendingResult pendingResult;
private WeakReference<Context> context;
Task(PendingResult pendingResult, Context context)
{
boolean changed = false;
JSONObject notificationDetails = new JSONObject(preferences.getString("notificationDetails", "{}"));
for (Iterator<String> i = notificationDetails.keys(); i.hasNext(); )
this.pendingResult = pendingResult;
// prevent async task context leaks
this.context = new WeakReference<>(context.getApplicationContext());
}
@Override
protected Void doInBackground(Void... params)
{
Context context = this.context.get();
if (context == null)
{
try
// should technically never happen, since the application context will still exist until the receiver is recycled
return null;
}
// restore any scheduled notifications
SharedPreferences preferences = context.getSharedPreferences("LocalNotificationPreferences", Context.MODE_PRIVATE);
if (preferences == null)
{
// nothing to reschedule if the preferences don't exist
return null;
}
try
{
boolean changed = false;
JSONObject notificationDetails = new JSONObject(preferences.getString("notificationDetails", "{}"));
for (Iterator<String> iterator = notificationDetails.keys(); iterator.hasNext(); )
{
String key = i.next();
int notificationId = Integer.parseInt(key);
JSONObject details = notificationDetails.getJSONObject(key);
String targetDateTime = details.getString("local-notification-targetDateTime");
boolean localTime = details.getBoolean("local-notification-localTime");
String title = details.getString("local-notification-title");
String body = details.getString("local-notification-body");
String action = details.getString("local-notification-action");
String activationEvent = details.getString("local-notification-activationEvent");
if (!GameActivity.LocalNotificationScheduleAtTime(context, notificationId, targetDateTime, localTime, title, body, action, activationEvent))
try
{
// if it fails, remove from details
i.remove();
String key = iterator.next();
int notificationId = Integer.parseInt(key);
JSONObject details = notificationDetails.getJSONObject(key);
String targetDateTime = details.getString("local-notification-targetDateTime");
boolean localTime = details.getBoolean("local-notification-localTime");
String title = details.getString("local-notification-title");
String body = details.getString("local-notification-body");
String action = details.getString("local-notification-action");
String activationEvent = details.getString("local-notification-activationEvent");
if (!GameActivity.LocalNotificationScheduleAtTime(context, notificationId, targetDateTime, localTime, title, body, action, activationEvent))
{
// if it fails, remove from details
iterator.remove();
changed = true;
}
}
catch (NumberFormatException | JSONException e)
{
Log.error("Error reading notification details", e);
iterator.remove();
changed = true;
}
}
catch (NumberFormatException | JSONException e)
if (changed)
{
e.printStackTrace();
i.remove();
SharedPreferences.Editor editor = preferences.edit();
editor.putString("notificationDetails", notificationDetails.toString());
editor.commit();
}
}
if (changed)
catch (JSONException e)
{
editor.commit();
Log.error("Error reading notification details", e);
}
return null;
}
catch (JSONException e)
@Override
protected void onPostExecute(Void result)
{
e.printStackTrace();
super.onPostExecute(result);
// mark receiver as ready for recycle
pendingResult.finish();
}
}
}