AlarmReceiver.java 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. package com.ivalentin.margolariak;
  2. import java.text.SimpleDateFormat;
  3. import java.util.Calendar;
  4. import java.util.Locale;
  5. import android.app.AlarmManager;
  6. import android.app.NotificationManager;
  7. import android.app.PendingIntent;
  8. import android.content.ComponentName;
  9. import android.content.Context;
  10. import android.content.Intent;
  11. import android.content.SharedPreferences;
  12. import android.content.pm.PackageManager;
  13. import android.graphics.BitmapFactory;
  14. import android.media.RingtoneManager;
  15. import android.support.v4.app.NotificationCompat;
  16. import android.support.v4.app.TaskStackBuilder;
  17. import android.content.BroadcastReceiver;
  18. import android.util.Log;
  19. /**
  20. * Manages alarms to perform actions in the background, such as sync and receive notifications.
  21. *
  22. * @see BroadcastReceiver
  23. *
  24. * @author Iñigo Valentin
  25. *
  26. */
  27. public class AlarmReceiver extends BroadcastReceiver {
  28. /**
  29. * Actions to be performed when an alarm is received.
  30. * Performs a full sync, and gets the pending notifications.
  31. *
  32. * @param context Context of the activity or application
  33. * @param intent Receiver intent
  34. *
  35. * @see android.content.BroadcastReceiver#onReceive(android.content.Context, android.content.Intent)
  36. */
  37. @Override
  38. @SuppressWarnings("deprecation")
  39. public void onReceive(Context context, Intent intent) {
  40. Log.d("Alarm", "Received");
  41. //Open the preferences to be available several times later.
  42. SharedPreferences settings = context.getSharedPreferences(GM.PREF, Context.MODE_PRIVATE);
  43. FetchURL fu;
  44. //Check if the user wants to receive notifications
  45. if (settings.getInt(GM.PREF_NOTIFICATION , GM.DEFAULT_PREF_NOTIFICATION) == 1){
  46. //Get the file
  47. try{
  48. fu = new FetchURL();
  49. fu.Run(GM.SERVER + "/app/notifications.php");
  50. Log.d("Alarm", "Fetched notifications");
  51. //Parse info
  52. String o = fu.getOutput().toString();
  53. while (o.contains("<notification>")){
  54. //Get non-language-dependant fields
  55. String notification = o.substring(o.indexOf("<notification>") + 14, o.indexOf("</notification>"));
  56. String id = notification.substring(notification.indexOf("<id>") + 4, notification.indexOf("</id>"));
  57. String action = notification.substring(notification.indexOf("<action>") + 8, notification.indexOf("</action>"));
  58. //Is the notification seen already?
  59. if(!settings.getBoolean(GM.NOTIFICATION_SEEN_ + id, false)){
  60. String lang = GM.getLang();
  61. String title = notification.substring(notification.indexOf("<title_" + lang + ">") + 10, notification.indexOf("</title_" + lang + ">"));
  62. String text = notification.substring(notification.indexOf("<text_" + lang + ">") + 9, notification.indexOf("</text_" + lang + ">"));
  63. //Get the notification manager ready
  64. NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
  65. //Variables to create intents for each notification
  66. Intent resultIntent;
  67. TaskStackBuilder stackBuilder;
  68. //Send the notification.
  69. NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context)
  70. .setSmallIcon(R.drawable.ic_notification)
  71. .setContentTitle(title)
  72. .setAutoCancel(true)
  73. .setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_launcher))
  74. .setVibrate((new long[] { 400, 400, 400}))
  75. .setColor(context.getResources().getColor(R.color.background_notification))
  76. .setSubText(context.getString(R.string.app_name))
  77. .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
  78. .setContentText(text);
  79. // Creates an intent for an Activity to be launched from the notification.
  80. resultIntent = new Intent(context, MainActivity.class);
  81. resultIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
  82. //Set extras depending on type.
  83. resultIntent.putExtra(GM.EXTRA_TEXT, text);
  84. resultIntent.putExtra(GM.EXTRA_TITLE, title);
  85. resultIntent.putExtra(GM.EXTRA_ACTION, action);
  86. //Add the intent to the notification.
  87. stackBuilder = TaskStackBuilder.create(context);
  88. stackBuilder.addParentStack(MainActivity.class);
  89. // Adds the Intent that starts the Activity to the top of the stack.
  90. stackBuilder.addNextIntent(resultIntent);
  91. PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
  92. mBuilder.setContentIntent(resultPendingIntent);
  93. //Actually send the notification.
  94. mNotificationManager.notify(Integer.parseInt(id), mBuilder.build());
  95. //Mark as notified
  96. SharedPreferences.Editor editor = settings.edit();
  97. editor.putBoolean(GM.NOTIFICATION_SEEN_ + id, true);
  98. editor.apply();
  99. }
  100. o = o.substring(o.indexOf("</notification>") + 15);
  101. }
  102. }
  103. catch(Exception ex) {
  104. Log.e("Notification error", "Error fetching remote file: " + ex.toString());
  105. }
  106. }
  107. //Get location
  108. boolean result = false;
  109. fu = new FetchURL();
  110. fu.Run(GM.SERVER + "/app/location.php");
  111. String lat = "", lon = "";
  112. String o = fu.getOutput().toString();
  113. Log.d("Alarm", "Fetched location");
  114. if (o.contains("<location>none</location>"))
  115. result = false;
  116. if (o.contains("<lat>") && o.contains("<lon>")){
  117. lat = o.substring(o.indexOf("<lat>") + 5, o.indexOf("</lat>"));
  118. lon = o.substring(o.indexOf("<lon>") + 5, o.indexOf("</lon>"));
  119. result = true;
  120. }
  121. SharedPreferences.Editor editor = settings.edit();
  122. if (result){
  123. editor.putLong(GM.PREF_GM_LATITUDE, Double.doubleToLongBits(Double.parseDouble(lat)));
  124. editor.putLong(GM.PREF_GM_LONGITUDE, Double.doubleToLongBits(Double.parseDouble(lon)));
  125. editor.putString(GM.PREF_GM_LOCATION, new SimpleDateFormat("yyyyMMddHHmmss", Locale.US).format(Calendar.getInstance().getTime()));
  126. }
  127. else{
  128. editor.putString(GM.PREF_GM_LOCATION, GM.DEFAULT_PREF_GM_LOCATION);
  129. }
  130. editor.apply();
  131. //Perform a background sync
  132. new Sync(context).execute();
  133. }
  134. /**
  135. * Sets a repeating alarm.
  136. * When the alarm fires, the app broadcasts an Intent to this WakefulBroadcastReceiver.
  137. * @param context The context of the app
  138. */
  139. public void setAlarm(Context context) {
  140. AlarmManager alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
  141. Intent intent = new Intent(context, AlarmReceiver.class);
  142. PendingIntent alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
  143. //Set the alarm cycle.
  144. alarmMgr.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, GM.PERIOD_SYNC, GM.PERIOD_SYNC, alarmIntent);
  145. // Enable SampleBootReceiver to automatically restart the alarm when the device is rebooted.
  146. ComponentName receiver = new ComponentName(context, BootReceiver.class);
  147. PackageManager pm = context.getPackageManager();
  148. pm.setComponentEnabledSetting(receiver, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
  149. }
  150. }