假设地址www.foo.com/notification.txt
经常使用格式化字符串更新,该字符串必须在Android设备中显示为通知。获得该字符串的最佳方法是什么?
我尝试过几件事。我的最后一次尝试是创建一个扩展BroadcastReceiver并配置ALARM_SERVICE以重复调用它的类:
的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);
}
}
如果我所做的只是记录一个字符串,我可以使函数check_notifications重复运行。但是,我使用http_request内部发生了奇怪的事情,从应用程序崩溃到整个系统冻结。我明白我应该运行它async。但是如何?
答案 0 :(得分:1)
您必须使用AsyncTask
。
此处的Android文档: Async Class 它很简单。
此外,如果您希望定期投放,请考虑使用Service
(Service Class)
此外,应用程序崩溃是因为您在主线程上运行某些内容,而不是在后台运行。所以一切都冻结,直到你从网页得到结果。 在该网页上负载很重的情况下,你必须等待。
异步类示例:
private class MyAsyncTask extends AsyncTask<URL, Integer, Integer> {
protected Integer doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
//This is for many urls. If you download staff only from one url use url[0] instead of a for-loop.
for (int i = 0; i < count; i++) {
//do something with url[i]
}
return 0; //or return some stats you can later use (eg how many bytes downloaded)
}
protected void onProgressUpdate(Integer... progress) {
//You can completely skip this method. It is to show a progress bar of how % is done
setProgressPercent(progress[0]);
}
protected void onPostExecute(Integer result) {
//This is where everything finishes, and you got the result of your webpage
showDialog("Downloaded " + result + " bytes");
}
}
然后,创建一个新的AsyncTask对象,并像这样开始任务:
asyncTaskObj.execute(...);