AlarmManager与应用程序一起死亡
问题描述:
我创建了一个应用程序来发送消息使用报警管理器,但如果我长时间的报警应用程序被android自动杀死,所以我需要防止应用程序被杀死。请告诉我该怎么做。AlarmManager与应用程序一起死亡
Calendar cal = Calendar.getInstance();
int currentApiVersion = android.os.Build.VERSION.SDK_INT;
if (currentApiVersion > android.os.Build.VERSION_CODES.LOLLIPOP_MR1) {
cal.set(Calendar.MINUTE, time_picker.getMinute());
cal.set(Calendar.HOUR_OF_DAY, time_picker.getHour());
} else {
//Setting the date and time from the time picker
cal.set(Calendar.MINUTE, time_picker.getCurrentMinute());
cal.set(Calendar.HOUR_OF_DAY, time_picker.getCurrentHour());
}
//System clock time
Calendar c = Calendar.getInstance();
Long a ;//=(long) (Calendar.getInstance().get(Calendar.SECOND) * 1000);
if(cal.get(Calendar.HOUR_OF_DAY) < c.get(Calendar.HOUR_OF_DAY))
h = (cal.get(Calendar.HOUR_OF_DAY) + 24 - c.get(Calendar.HOUR_OF_DAY)) * 60;
else
h = (cal.get(Calendar.HOUR_OF_DAY) - c.get(Calendar.HOUR_OF_DAY * 60;
m = (cal.get(Calendar.MINUTE) - c.get(Calendar.MINUTE));
a = (m + h) * 60;
myIntent = new Intent(this, MyReceiver.class);
myIntent.putExtra("pos", array.select);
//Pending Intent for sending the intent afterwards
pendingIntent[array.select] = PendingIntent.getBroadcast(this.getApplicationContext(), array.select, myIntent, 0);
alarmManager[array.select] = (AlarmManager) (this.getSystemService(Context.ALARM_SERVICE));
alarmManager[array.select].set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + a * 1000, pendingIntent[array.select]);
pendingarray.add(pendingIntent[array.select]);
sms_list.Phone[array.select] = Phone;
Intent back = new Intent(this, sms_list.class);
back.putExtra("PHONE", Phone);
back.putExtra("Flag",2);
back.putExtra("MSG", Message);
back.putExtra("HOUR", (int) cal.get(Calendar.HOUR_OF_DAY));
back.putExtra("MIN", (int) cal.get(Calendar.MINUTE));
back.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(back);
如果答案是唤醒锁,请告诉我在哪里使用它。
答
广播接收机应该触发报警。
如果它执行长时间运行,则应该使用线程或服务。它们都可以从接收器启动。
编辑
作为一个简单的例子,我用一个按钮的onClickListener这种方法在活动:
scheduleAlarm(name);
方法:
public void scheduleAlarm(String client)
{
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
String delay = sharedPref.getString(SettingsActivity.PREF_DELIVERY_DELAY, "48");
// time at which alarm will be scheduled here alarm is scheduled at 1 day from current time,
// we fetch the current time in milliseconds and added 1 day time
// i.e. 24*60*60*1000= 86,400,000 milliseconds in a day
Long time = new GregorianCalendar().getTimeInMillis()+ Integer.parseInt(delay) * 1000; //todo change seconds to hours
// create an Intent and set the class which will execute when Alarm triggers, here we have
// given AlarmReciever in the Intent, the onRecieve() method of this class will execute when
// alarm triggers and
//we will write the code to send SMS inside onRecieve() method pf Alarmreciever class
Intent intentAlarm = new Intent(this, AlarmReceiver.class);
intentAlarm.putExtra("CLIENT", client);
// create the object
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
//set the alarm for particular time
//todo string res
alarmManager.set(AlarmManager.RTC_WAKEUP,time, PendingIntent.getBroadcast(this,1, intentAlarm, PendingIntent.FLAG_UPDATE_CURRENT));
Toast.makeText(this, "Alarm Scheduled in " + delay + " hours", Toast.LENGTH_LONG).show();
}
最后,AlarmReceiver.java
package com.patrickmiller.test2;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.support.v4.app.NotificationCompat;
import android.widget.Toast;
public class AlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent)
{
Toast.makeText(context, "Alarm received", Toast.LENGTH_SHORT).show();
String client = intent.getStringExtra("CLIENT");
Notify(context, client);
}
public void Notify(Context context, String client) {
//todo expanded layout with options Fiche de contact | Rapport and cover image
//todo send name, address, phone, email and id through Intent to ContactClientActivity
//todo delete notification when generated
try {
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context)
//todo set notification icon, content title and content text as string resources
.setSmallIcon(R.drawable.warning)
.setContentTitle(client)
.setContentText("N'oubliez pas de générer le rapport du client");
Intent resultIntent = new Intent(context, ContactClientActivity.class);
//todo may need to expend instead of calling activity. Buttons will do.
// Because clicking the notification opens a new ("special") activity, there's
// no need to create an artificial back stack.
PendingIntent resultPendingIntent =
PendingIntent.getActivity(
context,
0,
resultIntent,
PendingIntent.FLAG_UPDATE_CURRENT
);
mBuilder.setContentIntent(resultPendingIntent);
// Sets an ID for the notification
int mNotificationId = 001;
// Gets an instance of the NotificationManager service
NotificationManager mNotifyMgr = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
// Builds the notification and issues it.
mNotifyMgr.notify(mNotificationId, mBuilder.build());
}
catch(Exception e) {
Toast.makeText(context, String.valueOf(e), Toast.LENGTH_LONG).show();
}
}
}
你不必关心客户的事情。只是我的预定警报的方式..
我的操作是短暂的,这是发送通知。如果您计划长时间运行,则应从接收器启动服务或线程(onReceive回拨方法)。
答
好吧,您的应用程序已完成,因为它正在主线程中运行,所以您需要在应用程序关闭时未杀死的其他线程中创建此进程。从官方页面检查这个documentation。如果你决定开始使用asyncTask类,请检查这个reference
答
你可以使用一个服务来做到这一点,这也将在设备重新启动后工作。您还必须提供服务foreground以防止系统将其杀死。可以通过添加正在进行的通知来完成。请参阅下面的服务代码。
在你的清单中添加以下
<receiver
android:name=".Autostart"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
</intent-filter>
</receiver>
<service
android:name=".StarterService"
android:enabled="true"
android:exported="true" />
然后创建一个新的类,如下所示:
public class Autostart extends BroadcastReceiver {
/**
* Listens for Android's BOOT_COMPLETED broadcast and then executes
* the onReceive() method.
*/
@Override
public void onReceive(Context context, Intent arg1) {
Log.d("Autostart", "BOOT_COMPLETED broadcast received. Executing starter service.");
Intent intent = new Intent(context, StarterService.class);
context.startService(intent);
}
}
最后是你的服务如下:
public class StarterService extends Service {
private static final String TAG = "MyService";
/**
* starts the AlarmManager.
*/
@Override
public void onCreate() {
super.onCreate();
//TODO: Start ongoing notification here to make service foreground
}
@Override
public void onStart(Intent intent, int startid) {
//TODO: Put your AlarmManager code here
//TODO: you also need to add some logic to check if some previous work is pending in case of a device reboot
Log.d(TAG, "onStart");
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onDestroy() {
//TODO: cancel the notification
Log.d(TAG, "onDestroy");
}
}
现在你需要每当你需要发送消息时,要做的事情是call the service。 PS:我知道答案被接受,但希望这可以帮助你或其他人。
你在主线程中使用了这段代码吗? –
我不知道主线程,但是这个代码是在时间选取器活动中,并且它被称为在发射器活动中按下了设置的定时器按钮。 – Pritesh
如果您的代码在活动中,那意味着它在主UI线程中。 –