2015-06-05 14 views
11

Sprawdzam, czy alarm został już ustawiony przez menedżer alarmów przy użyciu this answer.Nie można sprawdzić, czy alarm został ustawiony przez menedżer alarmów

Poniżej znajduje się mój fragment kodu.

boolean alarmUp = (PendingIntent.getBroadcast(MainActivity.this, 0, 
    new Intent(MainActivity.this, AlarmReceiver.class), PendingIntent.FLAG_NO_CREATE) != null); 
if (alarmUp) { 
    // alarm is set; do some stuff 
} 

Intent alarmIntent = new Intent(MainActivity.this, AlarmReceiver.class); 
final PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT); 

AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); 
manager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 10 * 1000, pendingIntent); 

Jednak alarmUp jest zawsze ustawiony jako prawdziwy. To znaczy, czy ustawiam alarm, czy nie, po ponownym uruchomieniu aplikacji jest to prawdą (sprawdzam ją, wykonując Toast).

Pomóżcie, gdzie idę źle.

+1

Nie znalazłem techniki "zobacz, jeśli chcesz", aby była niezawodna. – CommonsWare

+0

Czy mógłbyś rozwinąć, a może podać link do tego, jak to zrobić? –

+0

Mam na myśli kod w pytaniu. Nie znalazłem triku "FLAG_NO_CREATE", aby było niezawodne. – CommonsWare

Odpowiedz

17

Aby ta kontrola działała, musisz mieć absolutną pewność, że PendingIntent istnieje tylko po ustawieniu alarmu. Są dwie rzeczy, które możesz zrobić, aby to zapewnić:

1) Podczas testowania swojego kodu upewnij się, że odinstalowałeś aplikację, a następnie zainstalowałeś ją ponownie przed testowaniem.Odinstalowanie aplikacji spowoduje usunięcie wszystkich utworzonych przez Ciebie aplikacji, które wciąż czekają na realizację.

2) Gdy anulujesz alarm, upewnij się, że anulujesz także PendingIntent. Możesz to zrobić za pomocą

Intent alarmIntent = new Intent(MainActivity.this, AlarmReceiver.class); 
final PendingIntent pendingIntent = 
      PendingIntent.getBroadcast(MainActivity.this, 0, alarmIntent, 
      PendingIntent.FLAG_NO_CREATE); 
if (pendingIntent != null) { 
    pendingIntent.cancel(); 
} 
0

Ponieważ API 21 można użyć

public AlarmManager.AlarmClockInfo getNextAlarmClock() 

http://developer.android.com/reference/android/app/AlarmManager.html#getNextAlarmClock()


Teraz kod, który próbujesz użyć:

(PendingIntent.getBroadcast(MainActivity.this, 0, 
    new Intent(MainActivity.this, AlarmReceiver.class), PendingIntent.FLAG_NO_CREATE) != null); 

Bassically prosicie o poprzednim i istniejąca intencja zwana AlarmReceiver. Ale jego AlarmReceiver odnosi się do twojego własnego BroadcastReceiver.

Jak widać w tej linii na odpowiedź, że pisał wcześniej:

boolean alarmUp = (PendingIntent.getBroadcast(context, 0, 
    new Intent("com.my.package.MY_UNIQUE_ACTION"), 
    PendingIntent.FLAG_NO_CREATE) != null); 

Używają „MY_UNIQUE_ACTION”, aby zobaczyć, czy intencją istnieje.

Również w tym miejscu można zobaczyć tutorial z użyciem że:

http://justcallmebrian.com/2010/04/27/using-alarmmanager-to-schedule-activities-on-android/


Jeśli nie jesteś w stanie uzyskać dostęp do Android systemu AlarmReceiver i zobaczyć, czy intencją istnieje, nie będzie może poprosić o "ogólny" zaplanowany alarm. Czy to właśnie próbujesz zrobić? Jeśli tak, to czy jesteś pewien, że w przypadku, gdy nie masz zaplanowanego alarmu, system alarmowy systemu Android nie został stworzony przez system? Wygląda na to, że nie mamy kontroli nad tymi komponentami, które lubimy.


Przykładem pracy: manifest.xml:

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
package="com.blablabla.testa" > 
<uses-permission android:name="android.permission.WAKE_LOCK" /> 

<application 
    android:allowBackup="true" 
    android:icon="@mipmap/ic_launcher" 
    android:label="@string/app_name" 
    android:theme="@style/AppTheme" > 
    <activity 
     android:name=".MainActivity" 
     android:label="@string/app_name" > 
     <intent-filter> 
      <action android:name="android.intent.action.MAIN" /> 

      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 

     <receiver 
      android:name=".MySuperReceiver" 
      android:label="MySuperReceiverName" /> 

    </activity> 
</application> 

MySuperReceiver.java

package com.blablabla.testa; 
import android.content.BroadcastReceiver; 
import android.content.Context; 
import android.content.Intent; 
import android.util.Log; 

import java.util.Calendar; 

public class MySuperReceiver extends BroadcastReceiver { 
    public static final String TAG = MySuperReceiver.class.getSimpleName(); 
    public static final String ACTION_ALARM_RECEIVER = "ACTION_ALARM_RECEIVER"; 
    private Calendar c = Calendar.getInstance(); 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     if (intent != null) 
      if (ACTION_ALARM_RECEIVER.equals(intent.getAction())) { 
       Log.d(TAG, new Exception().getStackTrace()[0].getMethodName() + " " + c.getTime()); 
       //do something here 
      } 
    } 
} 

I MainActivity.java:

package com.blablabla.testa; 

import android.app.AlarmManager; 
import android.app.PendingIntent; 
import android.content.Context; 
import android.content.Intent; 
import android.support.v7.app.ActionBarActivity; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.Menu; 
import android.view.MenuItem; 


public class MainActivity extends ActionBarActivity { 

    public static final String TAG = "TEST APP:"; 

    AlarmManager alarmManager; 


    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     GetAlarmService(); 
     CreateAlarm(); 
     CheckForAlarm(); 
     CancelAlarms(); 
     CheckForAlarm(); 
    } 

    private void GetAlarmService() 
    { 
     alarmManager = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE); 
     Log.d(TAG, " GET Alarm Service ! "); 
    } 
    private void CreateAlarm() 
    { 
     long aroundInterval = 1*60*1000; 

     Intent intent = new Intent(getApplicationContext(), MySuperReceiver.class); 
     intent.setAction(MySuperReceiver.ACTION_ALARM_RECEIVER);//my custom string action name 

     PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 1001, intent, PendingIntent.FLAG_CANCEL_CURRENT);//used unique ID as 1001 
     alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), aroundInterval, pendingIntent);//first start will start asap 

     Log.d(TAG, " CREATE Alarm ! "); 
    } 

    private void CancelAlarms() 
    { 
     Intent intent = new Intent(getApplicationContext(), MySuperReceiver.class);//the same as up 
     intent.setAction(MySuperReceiver.ACTION_ALARM_RECEIVER);//the same as up 
     PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 1001, intent, PendingIntent.FLAG_CANCEL_CURRENT);//the same as up 
     alarmManager.cancel(pendingIntent);//important 
     pendingIntent.cancel();//important 

     Log.d(TAG, " Cancel Alarm ! "); 
    } 

    private void CheckForAlarm() 
    { 
     //checking if alarm is working with pendingIntent #3 
     Intent intent = new Intent(getApplicationContext() , MySuperReceiver.class);//the same as up 
     intent.setAction(MySuperReceiver.ACTION_ALARM_RECEIVER);//the same as up 
     boolean isWorking = (PendingIntent.getBroadcast(getApplicationContext() , 1001, intent, PendingIntent.FLAG_NO_CREATE) != null);//just changed the flag 
     Log.d("TAG: TEST APP: ", "alarm is " + (isWorking ? "" : "not") + " working..."); 

    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.menu_main, menu); 
     return true; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     // Handle action bar item clicks here. The action bar will 
     // automatically handle clicks on the Home/Up button, so long 
     // as you specify a parent activity in AndroidManifest.xml. 
     int id = item.getItemId(); 

     //noinspection SimplifiableIfStatement 
     if (id == R.id.action_settings) { 
      return true; 
     } 

     return super.onOptionsItemSelected(item); 
    } 
} 
+0

Czy nie ma sposobu, aby zadziałało API przed 21? Chcę tylko wiedzieć, czy moja aplikacja już ustawiła alarm. –

+0

mmm, więc jeśli ustawisz alarm za pomocą własnego BroadcastReceiver, powinieneś być w stanie odczytać ten rejestr. Oto inny link z innym przykładem: http://blog.mokrzycki.io/2015/01/working-example-of-setting-alarm-with-repeating-stuff-checking-if-alarm-was-set-with- pendingintent/ – mayo

+0

Zrobiłem to samo, co wspomniałem w # 2 w twoim linku. I właśnie to nie działa, jak wspomniano w moim pytaniu. –

Powiązane problemy