Запланируйте несколько автоматических задач, используя AlarmManager и Calendar
У меня есть этот кусок кода...
desc.setOnClickListener(new OnClickListener(){
public void onClick(View arg0){
alert.setTitle("Download");
alert.setIcon(R.drawable.go_down_3_32x32);
alert.setMessage("¿Donwload?");
alert.setPositiveButton("Yes", new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int id){
asyncForm2 af2 = new asyncForm2();
af2.execute(idU, mDbH);
}
});
alert.setNegativeButton("No", new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int id){
dialog.cancel();
}
});
AlertDialog alert0 = alert.create();
alert0.show();
}
});
Где desc - это переменная типа ImageView, alert - это переменная типа AlertDialog.Builder, idU - это целое число, а mDbH - это экземпляр DataBaseHelper (мой класс для обработки базы данных SQLite). Тогда у меня есть фон AsyncTask...
class asyncForm2 extends AsyncTask<Object,String,String>{
int idU;
DataBaseHelper db;
downloadData dd;
protected void onPreExecute(){
pDialog2 = new ProgressDialog(screen2.this);
pDialog2.setMessage("Loading...");
pDialog2.setIndeterminate(false);
pDialog2.setCancelable(true);
pDialog2.show();
}
protected String doInBackground(Object... params) {
idU = Integer.parseInt(params[0].toString());
db = (DataBaseHelper) params[1];
dd = new downloadData(idU,db);
if(dd.download(idU) == true){
return "ok";
}else{
return "err";
}
}
protected void onPostExecute(String result){
if(result == "ok"){
pDialog2.dismiss();
Toast.makeText(getApplicationContext(), "Success", Toast.LENGTH_SHORT).show();
setAlarms();
Toast.makeText(getApplicationContext(), "Alarms set!!", Toast.LENGTH_SHORT).show();
}else{
Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
vibrator.vibrate(200);
Toast.makeText(getApplicationContext(), "Error", Toast.LENGTH_SHORT).show();
}
}
}
При этом устанавливается соединение с сервером и загружаются все данные, необходимые для работы моего приложения... Затем в методе onPostExcecute вызывается метод setAlarms, который выполняет следующие действия:
private void setAlarms(){
// TODO Auto-generated method stub
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
Intent intent = new Intent(getApplicationContext(), AlarmReceiver.class);
intent.putExtra("ID_USER", idU);
String name1,name2;
String splits[];
int nameColumnIndex1, nameColumnIndex2;
mDbH.open();
Cursor itemCursor = null;
itemCursor = mDbH.getForms(idU);
if(itemCursor.moveToFirst() == false){
itemCursor.close();
mDbH.close();
}else{
for(itemCursor.moveToFirst();!itemCursor.isAfterLast();itemCursor.moveToNext()){
PendingIntent sender = PendingIntent.getBroadcast(screen.this, 0, intent, 0);
Calendar cal = GregorianCalendar.getInstance();
nameColumnIndex1 = itemCursor.getColumnIndexOrThrow(DataBaseHelper.FORM_SYNC_DURATION);
nameColumnIndex2 = itemCursor.getColumnIndexOrThrow(DataBaseHelper.FORM_SYNC_HOUR);
name1 = itemCursor.getString(nameColumnIndex1);
name2 = itemCursor.getString(nameColumnIndex2);
splits = name2.split(":");
if(name1.equals("DAILY")){
cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(splits[0]));
cal.set(Calendar.MINUTE, Integer.parseInt(splits[1]));
cal.set(Calendar.SECOND, Integer.parseInt(splits[2]));
}
if(name1.equals("WEEKLY")){
cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(splits[0]));
cal.set(Calendar.MINUTE, Integer.parseInt(splits[1]));
cal.set(Calendar.SECOND, Integer.parseInt(splits[2]));
if(cal.get(Calendar.DAY_OF_MONTH)+7 > cal.getActualMaximum(Calendar.DAY_OF_MONTH)){
cal.set(Calendar.DAY_OF_MONTH, (cal.get(Calendar.DAY_OF_MONTH)+7) - cal.getActualMaximum(Calendar.DAY_OF_MONTH));
if(cal.get(Calendar.MONTH) + 1 >= cal.getActualMaximum(Calendar.MONTH)+1){
cal.set(Calendar.MONTH, (cal.get(Calendar.MONTH) + 1) - (cal.getActualMaximum(Calendar.MONTH)+1));
cal.set(Calendar.YEAR, cal.get(Calendar.YEAR) + 1);
}else{
cal.set(Calendar.MONTH,cal.get(Calendar.MONTH)+1);
}
}else{
cal.set(Calendar.DAY_OF_MONTH, cal.get(Calendar.DAY_OF_MONTH)+7);
cal.set(Calendar.MONTH,cal.get(Calendar.MONTH)+1);
}
}
if(name1.equals("FORTNIGHTLY")){
cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(splits[0]));
cal.set(Calendar.MINUTE, Integer.parseInt(splits[1]));
cal.set(Calendar.SECOND, Integer.parseInt(splits[2]));
if(cal.get(Calendar.DAY_OF_MONTH)+15 > cal.getActualMaximum(Calendar.DAY_OF_MONTH)){
cal.set(Calendar.DAY_OF_MONTH, (cal.get(Calendar.DAY_OF_MONTH)+15) - cal.getActualMaximum(Calendar.DAY_OF_MONTH));
if(cal.get(Calendar.MONTH) + 1 > cal.getActualMaximum(Calendar.MONTH)+1){
cal.set(Calendar.MONTH, (cal.get(Calendar.MONTH) + 1) - (cal.getActualMaximum(Calendar.MONTH)+1));
cal.set(Calendar.YEAR, cal.get(Calendar.YEAR) + 1);
}else{
cal.set(Calendar.MONTH, cal.get(Calendar.MONTH) + 1);
}
}else{
cal.set(Calendar.DAY_OF_MONTH, Calendar.DAY_OF_MONTH+15);
cal.set(Calendar.MONTH, cal.get(Calendar.MONTH) + 1);
}
}
if(name1.equals("MONTHLY")){
cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(splits[0]));
cal.set(Calendar.MINUTE, Integer.parseInt(splits[1]));
cal.set(Calendar.SECOND, Integer.parseInt(splits[2]));
if(cal.get(Calendar.DAY_OF_MONTH) + cal.getActualMaximum(Calendar.DAY_OF_MONTH) > cal.getActualMaximum(Calendar.DAY_OF_MONTH)){
cal.set(Calendar.DAY_OF_MONTH, (cal.get(Calendar.DAY_OF_MONTH) + cal.getActualMaximum(Calendar.DAY_OF_MONTH)) - cal.getActualMaximum(Calendar.DAY_OF_MONTH));
if(cal.get(Calendar.MONTH) + 1 > cal.getActualMaximum(Calendar.MONTH)+1){
cal.set(Calendar.MONTH, (cal.get(Calendar.MONTH) + 1) - (cal.getActualMaximum(Calendar.MONTH)+1));
cal.set(Calendar.YEAR, cal.get(Calendar.YEAR) + 1);
}else{
cal.set(Calendar.MONTH, cal.get(Calendar.MONTH) + 1);
}
}
}
am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), sender);
}
itemCursor.close();
mDbH.cerrar();
}
}
Как видите, я установил несколько будильников в зависимости от значения из таблицы моей базы данных, и в связи с этим будильники различаются друг от друга (ежедневно, еженедельно и т. Д.). И мой класс AlarmReceiver выглядит следующим образом:
public class AlarmReceiver extends BroadcastReceiver {
private ProgressDialog pDialog1;
private static DataBaseHelper mDbH;
Context context0;
@Override
public void onReceive(Context context, Intent intent) {
try {
context0 = context;
Bundle bundle = intent.getExtras();
int idU = bundle.getInt("ID_USER");
asyncForm af2 = new asyncForm();
af2.execute(idU, mDbH);
} catch (Exception e) {
Toast.makeText(context, "Error", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
class asyncForm extends AsyncTask<Object,String,String>{
int idU;
DataBaseHelper db;
sendData sd;
protected void onPreExecute(){
pDialog1 = new ProgressDialog(contexto);
pDialog1.setMessage("Sending...");
pDialog1.setIndeterminate(false);
pDialog1.setCancelable(true);
pDialog1.show();
}
@Override
protected String doInBackground(Object... params) {
idU = Integer.parseInt(params[0].toString());
db = (DataBaseHelper) params[1];
sd = new sendData(idU,mDbH);
if(sd.send(idU) == true){
return "ok";
}else{
return "err";
}
}
protected void onPostExecute(String result){
if(result == "ok"){
pDialog1.dismiss();
Toast.makeText(contexto, "Success", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(contexto, "Error", Toast.LENGTH_SHORT).show();
}
}
}
}
Как видите, в целом я пытаюсь автоматически отправлять данные на мой сервер (ответы форм хранятся в базе данных). Но по какой-то причине, когда приходит время (скажем, в 12:00), ничего не происходит. В LogCat нет ошибки, поэтому я не знаю, что я делаю неправильно! Помогите, пожалуйста, я не знаю, в чем проблема при работе с Календарем или нет, на самом деле это не способ установки будильников...
Привет!
1 ответ
Я не прочитал весь код, но для установки более одного аварийного сигнала вы должны указать другой PendingIntent, в противном случае каждый аварийный сигнал перезаписывает предыдущий. Вы можете сделать это, установив другой код запроса:
PendingIntent sender = PendingIntent.getBroadcast(context, SOMEVALUE, intent, 0);
Например, вы могли бы написать
ArrayList<PendingIntent> array;
private void setAlarms(){
//your stuff
array = new ArrayList<PendingIntent>();
for(int i=0;i<something;i++){
PendingIntent sender = PendingIntent.getBroadcast(context, i, intent, 0);
array.add(sender)
//here you can set alarm
}
}
Помните, что если вы хотите позже отменить эти сигналы, вы должны сохранить все PendingIntents! (в списке например)
Отменить
void cancelAllAlarms(){
if(!array.isEmpty()){
for(int i=0; i<array.size(); i++){
alarmManager.cancel(array.get(i));
}
array.clear();
}
}