AlarmReceiver.java 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. package com.ivalentin.margolariak;
  2. //TODO: This doesn't work. Revise once the notification API is ready
  3. import android.app.Activity;
  4. import android.app.AlarmManager;
  5. import android.app.NotificationManager;
  6. import android.app.PendingIntent;
  7. import android.content.ComponentName;
  8. import android.content.Context;
  9. import android.content.Intent;
  10. import android.content.SharedPreferences;
  11. import android.content.pm.PackageManager;
  12. import android.database.Cursor;
  13. import android.database.sqlite.SQLiteDatabase;
  14. import android.graphics.BitmapFactory;
  15. import android.media.RingtoneManager;
  16. import android.support.v4.app.NotificationCompat;
  17. import android.support.v4.app.TaskStackBuilder;
  18. import android.content.BroadcastReceiver;
  19. import android.util.Log;
  20. import org.json.JSONArray;
  21. import org.json.JSONObject;
  22. /**
  23. * Manages alarms to perform actions in the background, such as sync and receive notifications.
  24. *
  25. * @see BroadcastReceiver
  26. *
  27. * @author Iñigo Valentin
  28. *
  29. */
  30. public class AlarmReceiver extends BroadcastReceiver {
  31. /**
  32. * Actions to be performed when an alarm is received.
  33. * Performs a full sync, and gets the pending notifications.
  34. *
  35. * @param context Context of the activity or application
  36. * @param intent Receiver intent
  37. *
  38. * @see android.content.BroadcastReceiver#onReceive(android.content.Context, android.content.Intent)
  39. */
  40. @Override
  41. @SuppressWarnings("deprecation")
  42. public void onReceive(Context context, Intent intent) {
  43. Log.d("Alarm", "Received");
  44. //Open the preferences to be available several times later.
  45. SharedPreferences preferences = context.getSharedPreferences(GM.PREFERENCES.PREFERNCES, Context.MODE_PRIVATE);
  46. FetchURL fu;
  47. //Check if the user wants to receive notifications
  48. if (preferences.getBoolean(GM.PREFERENCES.KEY.NOTIFICATIONS, GM.PREFERENCES.DEFAULT.NOTIFICATIONS)){
  49. //Get the file
  50. try{
  51. fu = new FetchURL();
  52. fu.Run(GM.API.SERVER + GM.API.NOTIFICATION.PATH);
  53. Log.d("NOTIFICATIONS", "Fetched notifications");
  54. //Parse info
  55. String o = fu.getOutput().toString();
  56. //Open database
  57. SQLiteDatabase db = context.openOrCreateDatabase(GM.DB.NAME, Activity.MODE_PRIVATE, null);
  58. if (db.isReadOnly()){
  59. Log.e("NOTIFICATIONS", "Database is locked and in read only mode.");
  60. return;
  61. }
  62. Cursor cursor;
  63. //Values for parsing
  64. String not, title_es, title_en, title_eu, text_es, text_en, text_eu, dtime, action;
  65. int id, gm, duration;
  66. int counter = 0;
  67. while (counter < 10 && o.contains("\"}")){
  68. //Get the notifications
  69. not = o.substring(o.indexOf("{\"") + 2, o.indexOf("\"}"));
  70. //Extract data
  71. id = Integer.valueOf(not.substring(not.indexOf("\"id\":") + 6, not.indexOf("\",")));
  72. title_es = not.substring(not.indexOf("\"title_es\":") + 12, not.indexOf("\"", not.indexOf("\"title_es\":") + 13));
  73. title_en = not.substring(not.indexOf("\"title_en\":") + 12, not.indexOf("\"", not.indexOf("\"title_en\":") + 13));
  74. title_eu = not.substring(not.indexOf("\"title_eu\":") + 12, not.indexOf("\"", not.indexOf("\"title_eu\":") + 13));
  75. text_es = not.substring(not.indexOf("\"text_es\":") + 11, not.indexOf("\"", not.indexOf("\"text_es\":") + 12));
  76. text_en = not.substring(not.indexOf("\"text_en\":") + 11, not.indexOf("\"", not.indexOf("\"text_en\":") + 12));
  77. text_eu = not.substring(not.indexOf("\"text_eu\":") + 11, not.indexOf("\"", not.indexOf("\"text_eu\":") + 12));
  78. dtime = not.substring(not.indexOf("\"dtime\":") + 9, not.indexOf("\"", not.indexOf("\"dtime\":") + 10));
  79. action = not.substring(not.indexOf("\"action\":") + 10, not.indexOf("\"", not.indexOf("\"action\":") + 11));
  80. gm = Integer.valueOf(not.substring(not.indexOf("\"gm\":") + 6, not.indexOf("\"", not.indexOf("\"gm\":") + 7)));
  81. duration = Integer.valueOf(not.substring(not.indexOf("\"duration\":") + 12, not.indexOf("\"", not.indexOf("\"duration\":") + 13)));
  82. duration = 60;
  83. //Compare with the database
  84. cursor = db.rawQuery("SELECT id FROM notification WHERE id = " + id + ";", null);
  85. if (cursor.getCount() == 0){
  86. db.execSQL("INSERT INTO notification (id, title_es, title_en, title_eu, text_es, text_en, text_eu, dtime, internal, duration, action) VALUES " +
  87. "(" + id + ", \"" + title_es + "\", \"" + title_en + "\", \"" + title_eu + "\", \"" + text_es + "\", \"" + text_en + "\", \"" + text_eu + "\", \"" + dtime + "\", " + gm + ", " + duration + ", \"" + action + "\");");
  88. }
  89. cursor.close();
  90. //TODO: Show notification;
  91. o = o.substring(o.indexOf("\"}") + 3);
  92. counter ++;
  93. }
  94. db.close();
  95. //Parse info
  96. /*String o = fu.getOutput().toString();
  97. while (o.contains("<notification>")){
  98. //Get non-language-dependant fields
  99. String notification = o.substring(o.indexOf("<notification>") + 14, o.indexOf("</notification>"));
  100. String id = notification.substring(notification.indexOf("<id>") + 4, notification.indexOf("</id>"));
  101. String action = notification.substring(notification.indexOf("<action>") + 8, notification.indexOf("</action>"));
  102. //Is the notification seen already?
  103. //TODO: Create a db table for this
  104. //Get data from database
  105. SQLiteDatabase db = SQLiteDatabase.openDatabase(context.getDatabasePath(GM.DB.NAME).getAbsolutePath(), null, SQLiteDatabase.NO_LOCALIZED_COLLATORS | SQLiteDatabase.OPEN_READONLY);
  106. final Cursor cursor;
  107. cursor = db.rawQuery("SELECT id, seen FROM notification WHERE id = " + id + ";", null);
  108. if (cursor.getCount() == 0){
  109. }
  110. else {
  111. if (cursor.getInt(1) == 0) {
  112. String lang = GM.getLang();
  113. String title = notification.substring(notification.indexOf("<title_" + lang + ">") + 10, notification.indexOf("</title_" + lang + ">"));
  114. String text = notification.substring(notification.indexOf("<text_" + lang + ">") + 9, notification.indexOf("</text_" + lang + ">"));
  115. //Get the notification manager ready
  116. NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
  117. //Variables to create intents for each notification
  118. Intent resultIntent;
  119. TaskStackBuilder stackBuilder;
  120. //Send the notification.
  121. NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context)
  122. .setSmallIcon(R.drawable.ic_notification)
  123. .setContentTitle(title)
  124. .setAutoCancel(true)
  125. .setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_launcher))
  126. .setVibrate((new long[]{400, 400, 400}))
  127. .setColor(context.getResources().getColor(R.color.background_notification))
  128. .setSubText(context.getString(R.string.app_name))
  129. .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
  130. .setContentText(text);
  131. // Creates an intent for an Activity to be launched from the notification.
  132. resultIntent = new Intent(context, MainActivity.class);
  133. resultIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
  134. //Set extras depending on type.
  135. resultIntent.putExtra(GM.EXTRA.TEXT, text);
  136. resultIntent.putExtra(GM.EXTRA.TITLE, title);
  137. resultIntent.putExtra(GM.EXTRA.ACTION, action);
  138. //Add the intent to the notification.
  139. stackBuilder = TaskStackBuilder.create(context);
  140. stackBuilder.addParentStack(MainActivity.class);
  141. // Adds the Intent that starts the Activity to the top of the stack.
  142. stackBuilder.addNextIntent(resultIntent);
  143. PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
  144. mBuilder.setContentIntent(resultPendingIntent);
  145. //Actually send the notification.
  146. mNotificationManager.notify(Integer.parseInt(id), mBuilder.build());
  147. //Mark as notified
  148. db.execSQL("UPDATE notification SET seen = 1 WHERE id = " + id);
  149. }
  150. }
  151. o = o.substring(o.indexOf("</notification>") + 15);
  152. }*/
  153. }
  154. catch(NumberFormatException ex) {
  155. Log.e("NOTIFICATION", "Error parsing remote file: " + ex.toString());
  156. }
  157. catch (Exception ex){
  158. Log.e("NOTIFICATION", "Error fetching notifications: " + ex.toString());
  159. }
  160. }
  161. //Perform a background sync
  162. new Sync(context).execute();
  163. }
  164. /**
  165. * Sets a repeating alarm.
  166. * When the alarm fires, the app broadcasts an Intent to this WakefulBroadcastReceiver.
  167. * @param context The context of the app
  168. */
  169. public void setAlarm(Context context) {
  170. //Only do this if the preference is enabled
  171. SharedPreferences prefs = context.getSharedPreferences(GM.PREFERENCES.PREFERNCES, Context.MODE_PRIVATE);
  172. if (prefs.getBoolean(GM.PREFERENCES.KEY.SYNC, GM.PREFERENCES.DEFAULT.SYNC)) {
  173. AlarmManager alarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
  174. Intent intent = new Intent(context, AlarmReceiver.class);
  175. PendingIntent alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
  176. //Set the alarm cycle.
  177. //alarmMgr.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, GM.PERIOD_SYNC.FESTIVALS, GM.PERIOD_SYNC.NORMAL, alarmIntent);
  178. alarmMgr.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, GM.PERIOD_SYNC.FESTIVALS, GM.PERIOD_SYNC.FESTIVALS, alarmIntent);
  179. // Enable SampleBootReceiver to automatically restart the alarm when the device is rebooted.
  180. ComponentName receiver = new ComponentName(context, BootReceiver.class);
  181. PackageManager pm = context.getPackageManager();
  182. pm.setComponentEnabledSetting(receiver, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
  183. }
  184. }
  185. }