假设地址 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>
报警器.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 还是会发生奇怪的事情,从应用程序崩溃到整个系统卡住。我知道我应该异步运行它。但是如何呢?
最佳答案
你必须使用AsyncTask
。
Android 文档在这里: Async Class 非常简单。
此外,如果您希望它定期运行,请考虑使用服务
( 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(...);
关于android - 检查站点以显示通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13674491/