我正在尝试在SmsReceiver Broadcast上执行AsyncTask。我的代码的问题在于,如果在SMS广播接收器触发时没有互联网连接可用,则AsyncTask不会执行。如果没有可用的互联网连接,我想安排AsyncTask在接下来的20分钟内以4分钟的间隔运行5次。如果执行任何AsyncTask,都会收到服务器的响应,然后取消下一次执行并更新UI。我可以在onPostExecute()中更新UI。我之前在这里问过这个问题,但是没有任何代码帮助。ScheduledExecutorService上有很多帖子安排AsyncTask以x分钟的间隔运行,但是我找不到任何提及AsyncTask以x分钟的间隔运行x分钟的消息。仅在Android官方网站上有Beeper示例,但我不明白如何操作代码以使其正常工作。如果有人可以帮助我,使我有义务使此代码正常工作。
SmsReceiver.java
public class SmsReceiver extends BroadcastReceiver {
static boolean flagAlarmSet;
static int count;
public void onReceive(Context context, Intent intent) {
final String ACTION_SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
String action = intent.getAction();
if (action.equals(ACTION_SMS_RECEIVED) || action.equals("ActionRetry")) {
Log.d("SmsReceiver Broadcast triggered", "OK");
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
Log.d("Internet is connected", "flagAlarmSet to: " + flagAlarmSet);
//if (flagAlarmSet) { //Removed
count = 0;
flagAlarmSet = false;
CancelAlarm(context);
Log.d("Alarm cancelled", "Alarm");
//} //Removed
//start AsyncTask even if flag was not set, you could have internet the first time in
try {
Log.d("Executing TheTask()", "OK");
new TheTask().execute("http://somedomain.tld/index.php?userId=12345678");
} catch (Exception e) {
Log.d("TheTask Execution Error", "FAIL");
e.printStackTrace();
}
}
if (networkInfo == null) {
if (!flagAlarmSet){
Log.d("Internet is NOT connected.", "Schedule Retry");
flagAlarmSet = true;
SetAlarm(context);
Log.d("Alarm Set", "Alarm");
}
else{
count++;
if (count >= 5){
Log.d("Internet is NOT connected.", "Max Tries Reached, Cancel Alarm");
count = 0;
flagAlarmSet = false;
CancelAlarm(context);
}
}
}
}
}
class TheTask extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... arg0) {
String text = null;
try {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(arg0[0]);
HttpResponse resp = httpclient.execute(httppost);
HttpEntity ent = resp.getEntity();
text = EntityUtils.toString(ent);
} catch (Exception e) {
e.printStackTrace();
}
return text;
}
@Override
protected void onPreExecute() {
Log.d("Test onPreExecute.", "OK");
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
Log.d("Result from server", result);
}
}
public void SetAlarm(Context context)
{
AlarmManager am=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, SmsReceiver.class);
i.setAction("ActionRetry");
PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 1000 * 60 * 4, 1000 * 60 * 4, pi); // Millisec * Second * Minute
}
public void CancelAlarm(Context context)
{
Intent intent = new Intent(context, SmsReceiver.class);
intent.setAction("ActionRetry");
PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(sender);
}
}
编辑:1
更新了代码,但是如果仍然没有Internet连接可用,则不会触发SetAlarm。我来自PHP背景。在PHP中,使用cron作业设置重复任务很容易。但这是我第一次编写Java代码。到现在为止,AsyncTask可以正常运行,但是我真的不知道所有这些东西在哪里增加计数?
编辑:2
更新的代码。
编辑:3
更新的代码。现在正在工作。
解决此问题的一种方法是使用PendingIntent和AlarmManager重新安排没有互联网可用的时间。
这样的事情(您将需要更新flagAlarmSet并在适当的地方计数):
if (networkInfo != null && networkInfo.isConnected()) {
Log.d("Network is connected. Executing TheTask()", "OK");
if (flagAlarmSet == true){
flagAlarmSet = false;
CancelAlarm(context);
}
new TheTask().execute("http://somedomain.tld/index.php?userId=12345678");
}
if (networkInfo == null) {
Log.d("Network is NOT connected.", "FAIL");
if (flagAlarmSet == false){
Log.d("Network is NOT connected.", "Schedule Retry");
flagAlarmSet = true;
SetAlarm(context);
}
else{
if (count > 5){
Log.d("Network is NOT connected.", "Max Tries Reached, Cancel Alarm");
flagAlarmSet = false;
CancelAlarm(context);
}
}
}
像这样安排/取消警报:
public void SetAlarm(Context context)
{
AlarmManager am=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, SmsReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000 * 60 * 4, pi); // Millisec * Second * Minute
}
public void CancelAlarm(Context context)
{
Intent intent = new Intent(context, SmsReceiver.class);
PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(sender);
}
参考:警报管理器示例
需要注意的另一件事是,如果您打算使用接收到的消息,则需要以某种方式缓存该消息以在重新计划的PendingIntent中使用。
请参阅getMessagesFromIntent()
文档:
示例:在Android中发送和接收SMS和MMS(Kit Kat之前的Android 4.4)
编辑:在此处重新设置计数:
else{
if (count >= 5){
Log.d("Network is NOT connected.", "Max Tries Reached, Cancel Alarm");
count = 0;
flagAlarmSet = false;
CancelAlarm(context);
}
编辑2:好的,我想我明白了问题所在。您将需要向该意图添加一个动作,并在中查找“ ActionRetry” onReceive()
。
我刚刚测试了它,它可以工作。
看一下下面的更新代码:
public class SmsReceiver extends BroadcastReceiver {
static boolean flagAlarmSet;
static int count;
public void onReceive(Context context, Intent intent) {
final String ACTION_SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
String action = intent.getAction();
if (action.equals(ACTION_SMS_RECEIVED) || action.equals("ActionRetry")) {
Log.d("SmsReceiver Broadcast triggered", "OK");
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
Log.d("Network is connected. Executing TheTask()", "OK");
Log.d("connected", "flagAlarmSet to: " + flagAlarmSet);
//if (flagAlarmSet) { //Removed
count = 0;
flagAlarmSet = false;
CancelAlarm(context);
Log.d("Alarm cancelled", "Alarm");
//} //Removed
//start AsyncTask even if flag was not set, you could have internet the first time in
try {
Log.d("SmsReceiver Broadcast triggered", "OK");
new TheTask().execute("http://somedomain.tld/index.php?userId=12345678");
} catch (Exception e) {
Log.d("TheTask Execution Error", "FAIL");
e.printStackTrace();
}
}
if (networkInfo == null) {
Log.d("Network is NOT connected.", "FAIL");
if (!flagAlarmSet){
Log.d("Network is NOT connected.", "Schedule Retry");
flagAlarmSet = true;
SetAlarm(context);
Log.d("Alarm Set", "Alarm");
}
else{
count++;
if (count >= 5){
Log.d("Network is NOT connected.", "Max Tries Reached, Cancel Alarm");
count = 0;
flagAlarmSet = false;
CancelAlarm(context);
}
}
}
}
}
class TheTask extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... arg0) {
String text = null;
try {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(arg0[0]);
HttpResponse resp = httpclient.execute(httppost);
HttpEntity ent = resp.getEntity();
text = EntityUtils.toString(ent);
} catch (Exception e) {
e.printStackTrace();
}
return text;
}
@Override
protected void onPreExecute() {
Log.d("Test onPreExecute.", "OK");
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
Log.d("Result from server", result);
}
}
public void SetAlarm(Context context)
{
AlarmManager am=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, SmsReceiver.class);
i.setAction("ActionRetry");
PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 1000 * 60 * 4, 1000 * 60 * 4, pi); // Millisec * Second * Minute
}
public void CancelAlarm(Context context)
{
Intent intent = new Intent(context, SmsReceiver.class);
intent.setAction("ActionRetry");
PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(sender);
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句