简体   繁体   中英

Alarm Manager BroadcastReceiver, setRepeating isn't working when called from inside a Fragment

Hello everybody this is my first post here and I must say I really like this site it helped me fix a lot of things. But now I have this problem when useing Alarm Manager in android from inside a Fragment.

Here is my code (snippet from stackoverflow), it used to work I tried to set the minutes to random and then it suddenly stopped working. When I removed it the error was still there..

Alarm.java :

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.PowerManager;
import android.widget.Toast;

public class Alarm extends BroadcastReceiver 
{    
     @Override
     public void onReceive(Context context, Intent intent) 
     {   
         PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
         PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "");
         wl.acquire();

         // Put here YOUR code.
         Toast.makeText(context, "Alarm !!!!!!!!!!", Toast.LENGTH_LONG).show(); // For example

         wl.release();
     }

 public void SetAlarm(Context context)
 {
     AlarmManager am=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
     Intent i = new Intent(context, Alarm.class);
     PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
     am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000 * 60 * 10, pi); // Millisec * Second * Minute
 }

 public void CancelAlarm(Context context)
 {
     Intent intent = new Intent(context, Alarm.class);
     PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
     AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
     alarmManager.cancel(sender);
 }
}

RealityCheck.java

import com.actionbarsherlock.app.SherlockFragment;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.*;
import android.widget.CheckBox;
import android.widget.Toast;

public class RealityCheck extends SherlockFragment implements View.OnClickListener {

    CheckBox EnabledBox;
    Alarm alarm = new Alarm();
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
        //Moet inflater gebruiken om findViewById in een Fragment te gebruiken en op het einde returnen
        View rootView = inflater.inflate(R.layout.activity_reality_check, container, false);
        EnabledBox = (CheckBox)rootView.findViewById(R.id.check_box_enabled);
        EnabledBox.setOnClickListener(this);
        return rootView;

    }
    @Override
    public void onClick(View v) {
        CheckBox EnabledBox = (CheckBox) v;
        if(EnabledBox.isChecked())
        {
            //Moet this.getActivity gebruiken in Fragment
            Toast.makeText(RealityCheck.this.getActivity(), "Reality check alarm activated", Toast.LENGTH_SHORT).show();
            //Alarm starten (in fragment weer getActivity() ipv Context)
            alarm.SetAlarm(getActivity());
            }
        else
        {
            Toast.makeText(RealityCheck.this.getActivity(), "Reality check alarm disabled", Toast.LENGTH_SHORT).show();
            alarm.CancelAlarm(getActivity());
        }   

    }   
}

manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.dreamincubation"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-permission android:name="android.permission.WAKE_LOCK"></uses-permission>

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="18" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/Theme.Sherlock" >

        <receiver  
            android:process=":remote" android:name="Alarm"></receiver>

        <activity
            android:name="com.example.dreamincubation.IntroWindow"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name="com.example.dreamincubation.MainActivity"
            android:label="@string/title_activity_main_menu" >
        </activity>
        <activity
            android:name="com.example.dreamincubation.RealityCheck"
            android:label="@string/title_activity_reality_check" >
        </activity>
        <activity
            android:name="com.example.dreamincubation.IncubationInfo"
            android:label="@string/title_activity_incubation_info" >
        </activity>
        <activity
            android:name="com.example.dreamincubation.Incubation"
            android:label="@string/title_activity_incubation" >
        </activity>
        <activity
            android:name="com.example.dreamincubation.AlarmService"
            android:label="@string/title_activity_alarm_service" >
        </activity>
         <receiver android:name="Alarm" >
        </receiver>
    </application>
</manifest>

I've tried it without the wake-lock. Didn't work either.

If anybody can help me out it would be greatly appreciated..

You are telling to the AlarmManager to trigger immediatly by doing this :

 am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000 * 60 * 10, pi); 

And it should repeat the alarm every 10 minutes.

but if you want the first event to be in 10min and to repeat every 10 min you have to do this :

 long tenMin = 1000 * 60 * 10;
 am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + tenMin, tenMin, pi); 

I recommend to deal with the AlarmManager in a Service, a great tutorial explain it :

http://blog.blundell-apps.com/notification-for-a-user-chosen-time

If you don't need an exact time alarm, you should definitly use the method :

setInexactRepeating

http://developer.android.com/reference/android/app/AlarmManager.html#setInexactRepeating(int , long, long, android.app.PendingIntent)

I order to preserve battery.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM