2011-01-10 61 views
20

我有AlarmManager的問題,我設置了用於安排重複報警的代碼,在運行應用程序後,報警運行良好。即使我點擊主頁按鈕(並且應用程序已暫停),警報仍會按其間隔運行。關閉應用程序後Android報警被取消

問題是如果我打開任務管理器並強制關閉應用程序,則警報停止運行。

這是一個正常的行爲,有沒有什麼辦法可以避免這種情況,關閉應用程序後保持警報運行?

代碼如下 - 該方法由ApplicationContext類onCreate()調用。

private void scheduleAlarm() { 
    if (alarmScheduled == true) { return; } // we only need to schedule once. 

    int alarmInterval = Def.pref(getApplicationContext()).getInt("alarmInterval", 30); 

    final Intent intent = new Intent(getApplicationContext(), CollectorAlarmReceiver.class); 
    final PendingIntent pending = PendingIntent.getBroadcast(getApplicationContext(), 0, intent, 0); 

    AlarmManager alarmMgr = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE); 

    alarmMgr.cancel(pending); // cancel others. 

    alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+1000, 
    alarmInterval*1000, pending); 

    Def.log(TAG,"scheduleAlarm(): alarm scheduled, interval: "+alarmInterval+" seconds"); 
    alarmScheduled = true; 
} 

接收器代碼:

public void onReceive(Context context, Intent intent) { 
    Log.i(TAG, "CollectorAlarmReceiver invoked, starting CollectorService in background"); 

    context.startService(new Intent(context, CollectorService.class)); 

    Intent collectorService = new Intent(context,CollectorService.class); 
    collectorService.putExtra("action", CollectorService.ACTION_BACKGROUND_REQUEST_MESSAGES); 

    context.sendBroadcast(collectorService); 
} 

謝謝!

+0

你可以發佈你的接收器代碼和一個alarmInterval的例子嗎? – ninjasense 2011-01-10 06:20:45

+0

我發佈了Receiver的代碼。 alarmInterval是30秒。你可以看到onReceive中有一個Log,所以我可以跟蹤Receiver被調用的時間。在運行應用程序時,它可以正常工作,問題在於它關閉時。 – 2011-01-10 06:54:43

+0

爲什麼不在系統默認時鐘中設置鬧鐘?然後通過任務管理器殺死它,看看它是否像你的應用程序一樣。如果它也不能警告你。我認爲你的應用程序可以,你不需要做任何事情。 – 2013-08-21 22:02:11

回答

6

這是正常行爲。如果用戶自願強制停止應用,則應停止。否則,您正在創建一個類似於應用程序的病毒。

如果您真的想要,您可以編寫另一個服務,監視您的其他服務是否正在運行,並在服務未運行時運行該服務。但這將是另一個應用程序和(你希望)用戶不會殺死這個應用程序使用任務管理器。

個人而言,我不會擔心。如果用戶停止了它,他們想停止它。不要惹惱用戶。

+18

我不同意,因爲有許多應用程序會在考慮到良好意圖的情況下執行此操作,例如簡單的鬧鐘。另外Android並不意味着通過任務殺手來殺死任務。 – ninjasense 2011-01-10 06:28:45

+0

是的,就我而言,我想重現Foursquare「ping」服務的行爲,即使在關閉Foursquare應用程序後,您仍然可以收到通知。 Facebook應用程序也是如此,但我認爲它使用C2DM。 C2DM是唯一能夠在內存中保留服務的方式嗎? – 2011-01-10 06:49:18

+0

你說得很好。但是使用TaskKiller的人會發生什麼。他們不知道這樣做意味着警報不會熄滅。我寧願不做第二個應用程序來監視實際應用程序以確保設置警報。有任何想法嗎? (我知道它是一箇舊帖子)。 – Andy 2012-07-07 03:58:53

1

強制關閉應用程序不是關閉應用程序的正確方法,可能會給您不正確的行爲。

question也可能有一定的幫助。

0

我已經能夠做到你所需要的。即使您通過應用程序管理器工具中的運行選項卡停止應用程序,該服務也會重新啓動。殺死它的唯一方法是通過應用程序管理器中unistall選項旁邊的強制停止按鈕。基本上你直接致電服務。這裏是我的代碼:

public class TestService extends Service { 

@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 
     Toast.makeText(this, "Ejecutando Servicio ...", Toast.LENGTH_SHORT).show(); 
    return Service.START_NOT_STICKY;  
    } 

@Override 
    public void onCreate() { 
     super.onCreate(); 
     Toast.makeText(this, "Iniciando Servicio ...", Toast.LENGTH_SHORT).show(); 
} 

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
     Toast.makeText(this, "Deteniendo Servicio ...", Toast.LENGTH_SHORT).show(); 
} 

在客戶端活動寫入以下代碼:

  Calendar cal = Calendar.getInstance(); 
     Intent intent = new Intent(this,TestService.class); 
     PendingIntent pIntent = PendingIntent.getService(this.getApplicationContext(), 0, intent, 0); 
     alarm= (AlarmManager) getSystemService(Context.ALARM_SERVICE); 
     alarm.setRepeating(AlarmManager.RTC_WAKEUP,cal.getTimeInMillis(), 3*1000, pIntent); 

而且在艙單申報服務:

 <service 
     android:name="TestService" 
     android:icon="@drawable/ic_launcher" 
     android:label="TestService" 
     > 
    </service>   
7

我相信@GSree是錯誤的。有一個簡單的方法來實現這一點。只需使用自定義操作即可。具體方法如下:

首先,定義自定義動作的名稱,如:

public static final String MY_ACTION = "com.sample.myaction" 

然後創建一個BroadcastReceiver:

public class MyAlarmReceiver extends BroadcastReceiver { 
    @Override 
    public void onReceive(Context context, Intent intent) { 
     if (intent.getAction().equals(MY_ACTION)) { 
      // Do something here 
     } 
    }  
} 

註冊的接收器上的AndroidManifest。XML:

<receiver android:name="com.sample.MyAlarmReceiver"> 
    <intent-filter> 
     <action android:name="com.sample.myaction"/> 
    </intent-filter> 
</receiver> 

然後,設置鬧鐘,請使用以下的PendingIntent:

Intent i = new Intent(MY_ACTION); 
PendingIntent pi = PendingIntent.getBroadcast(getApplicationContext(), 0, i, 0); 

可能有其他的方式來做到這一點,但我想這個解決方案和廣播接收器被調用,即使我強制退出我的應用程序從殼。

請注意此解決方案不需要您創建服務。

1

我已經做了幾次,但不知道爲什麼你們將分配requestCode爲0;我認爲給你的報警一個唯一的號碼會有很大的幫助。

1

清單文件添加

<receiver android:name=".AlarmReceiver" android:process=":remote" />

。 即使應用程序被殺,鬧鐘也能正常工作。

3

這是一個正常的行爲!當您的應用轉到onDestroy()時,鬧鐘將停止工作。