2016-06-14 103 views
0

我创建了一个应用程序来发送消息使用报警管理器,但如果我长时间的报警应用程序被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); 

如果答案是唤醒锁,请告诉我在哪里使用它。

+0

你在主线程中使用了这段代码吗? –

+0

我不知道主线程,但是这个代码是在时间选取器活动中,并且它被称为在发射器活动中按下了设置的定时器按钮。 – Pritesh

+0

如果您的代码在活动中,那意味着它在主UI线程中。 –

回答

0

广播接收机应该触发报警。

如果它执行长时间运行,则应该使用线程或服务。它们都可以从接收器启动。

编辑

作为一个简单的例子,我用一个按钮的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回拨方法)。

+0

所以,你的意思是这段代码应该在服务?因此,当用户输入时间消息和电话号码时,此活动应调用设置闹钟的服务。 – Pritesh

+0

如果Broadcast Receiver首先适合您的需求,并且在需要时使用其他选项,您应该尝试。 –

+0

好的,谢谢你看看它。 – Pritesh

0

好吧,您的应用程序已完成,因为它正在主线程中运行,所以您需要在应用程序关闭时未杀死的其他线程中创建此进程。从官方页面检查这个documentation。如果你决定开始使用asyncTask类,请检查这个reference

+0

因此,在异步任务中添加警报管理器代码会对我有帮助吗? – Pritesh

+0

是的,因为当关闭应用程序时,任务在后台继续工作,同时创建了一些条件,这个类的唯一问题是当设备旋转时停止。所以我的提示是,你需要阅读文档并决定哪一个最适合你的应用 –

+0

好吧我试着包括异步任务 – Pritesh

2

你可以使用一个服务来做到这一点,这也将在设备重新启动后工作。您还必须提供服务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:我知道答案被接受,但希望这可以帮助你或其他人。

+0

非常感谢您尝试这个 – Pritesh

+0

兄弟,因为我使用多个报警管理器类,所以这种方法可能不适合我,因为这只有一个服务。 – Pritesh

相关问题