2016-06-14 9 views
0

アラームマネージャーを使用してメッセージを送信するアプリを作成しましたが、アラームを長時間放置するとアプリが自動的にアンドロイドによって殺されるため、アプリが殺されるのを防ぐ必要があります。私はどうすればそれをすることができます。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

メインスレッドについてはわかりませんが、このコードはTime Pickerアクティビティにあり、ランチャアクティビティでタイマー設定ボタンが押されたときに呼び出されます。 – Pritesh

+0

あなたのコードがアクティビティにある場合、それはメインのUIスレッドにあることを意味します。 –

答えて

0

ブロードキャスト受信機でアラームを発生させる必要があります。

長寿命の操作を実行する場合は、スレッドまたはサービスを使用する必要があります。どちらも受信機から起動することができます。

EDIT

短い例として、私は活動のボタンの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(); 
     } 

    } 

} 

あなたはクライアントのことを気にする必要はありません。ちょうど私がアラームを予定通りに..

私の操作は、を送信する短命のものです。長寿命のオペレーションを計画する場合は、受信者からサービスまたはスレッドを開始する必要があります(受信時、受信コールバックメソッド)。

+0

奉仕していますか?したがって、ユーザが時刻msgと電話番号を入力すると、このアクティビティはアラームを設定するサービスを呼び出す必要があります。 – Pritesh

+0

ブロードキャストレシーバが必要に応じて最初に試してから、必要に応じて他のオプションを使用してみてください。 –

+0

okありがとうございました。 – Pritesh

0

あなたのアプリはメインスレッドで実行されているので終了します。そのため、アプリが終了しても終了しない別のスレッドでこの処理を行う必要があります。公式ページからdocumentationを確認してください。 asyncTaskクラスを使用して起動を開始する場合は、これを確認してください。reference

+0

アラームマネージャーコードを非同期タスクに追加すると、私に役立ちますか? – Pritesh

+0

はい、アプリケーションを閉じると、一部の条件が成立している間にタスクがバックグラウンドで作業を続けるため、このクラスの唯一の問題はデバイスが回転するときに停止することです。だから私のヒントは、あなたは、ドキュメントを読んで、あなたのアプリケーションに最適なものを決定する必要があります –

+0

ok il非同期タスクを含めるようにします – Pritesh

2

サービスを使用すると、デバイスを再起動した後でも動作します。また、システムが殺されるのを防ぐために、サービスforegroundを作成する必要があります。これは、進行中の通知を追加することによって行うことができます。以下のサービスコードを参照してください。

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"); 
    } 
} 

あなたが必要なすべてをあなたのマニフェストに

は、次のように続いて新しいクラスを作成するには、次の

<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" /> 

を追加しますあなたがメッセージを送る必要があるときはいつでもcall the serviceです。 PS:回答は受け入れられますが、これがあなたや他の人に役立つことを願っています。

+0

このメソッドは複数のアラームマネージャクラスを使用していますので、これは1つのサービスしかないため、このメソッドが機能しない可能性がありますので、これを必ず試してください。 – Pritesh

+0

Bro。 – Pritesh

関連する問題