Suppose the address www.foo.com/notification.txt is updated often with a formatted string that must be shown as a notification in an Android device. What’s the best approach for getting that string?
I’ve tried several things. My last attempt was creating a class that extends a BroadcastReceiver and configuring ALARM_SERVICE to call it repeatedly:
AndroidManifest.xml:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"></uses-permission>
<receiver android:process=":remote" android:name="Alarm"></receiver>
<receiver android:name=".AutoStart">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"></action>
</intent-filter>
</receiver>
Alarm.java:
package br.com.mypackage.cfqm;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import android.app.AlarmManager;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.StrictMode;
import android.preference.PreferenceManager;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.TaskStackBuilder;
import android.util.Log;
import android.widget.Toast;
public class Alarm extends BroadcastReceiver
{
int period_ms = 5*60*1000;
SharedPreferences prefs;
String user;
String pass;
Context context;
public void check_notifications(){
//http request to get and parse the notifications
String[] notifications = http_request("http://foo.com/notification.html")).split("\n");
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancelAll();
int notification_next_id = 0;
for (String notification_line:notifications){
String[] notification = notification_line.split(";");
if (notification.length==3)
notify(notification_next_id++,notification[0],notification[1],notification[2]);
}
}
public void notify(Integer id,String title,String text,String url){
//displays a single notification
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationCompat.Builder notificationBuilder =
new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.ic_action_search)
.setAutoCancel(true)
.setContentTitle(title)
.setContentText(text);
Intent resultIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addParentStack(Main.class);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0,PendingIntent.FLAG_UPDATE_CURRENT);
notificationBuilder.setContentIntent(resultPendingIntent);
notificationManager.notify(id,notificationBuilder.build());
Log.v("cfqm","notificado");
}
public String http_request(String url) {
//makes a http request
try {
HttpClient httpClient = new DefaultHttpClient();
HttpContext localContext = new BasicHttpContext();
HttpGet httpGet = new HttpGet(url);
HttpResponse response = httpClient.execute(httpGet, localContext);
String result = "";
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
String line = null;
while ((line = reader.readLine()) != null)
result += line + "\n";
return result;
}
catch (Exception e){
e.printStackTrace();
return "";
}
}
@Override
public void onReceive(Context ctx, Intent intent)
{
context = ctx;
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
// The function below will be called periodically
check_notifications();
}
public void SetAlarm(Context context)
{
prefs = PreferenceManager.getDefaultSharedPreferences(context);
user = prefs.getString("user","");
pass = prefs.getString("pass","");
AlarmManager am = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, Alarm.class);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), period_ms, pi); // Millisec * Second * Minute
}
public void CancelAlarm(Context context)
{
Intent intent = new Intent(context, Alarm.class);
PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(sender);
}
}
I can make the function check_notifications to run repeatedly if all I do there is Log a string. But wheter I use http_request inside weird things happen, from the app crashing, to the whole system freezing. I understand I was supposed to run it async. But how?
You have to use
AsyncTask.Android Documentation here:
Async Class
Its pretty simple.
Also if you want this to run periodically, consider using a
Service(Service Class)Also the app crashes because you are running something on main thread, and not in the background. So everything freezes until you got the result from webpage.
And in situations of heavy load on that webpage you have to wait.
Async class Example:
And then, create a new AsyncTask object, and start the task like this: