Note: Beginning with API 19 (KITKAT) alarm delivery is inexact: the OS will shift alarms in order to minimize wakeups and battery use. There are new APIs to support applications which need strict delivery guarantees; see setWindow(int, long, long, PendingIntent) and setExact(int, long, PendingIntent). Applications whose targetSdkVersion is earlier than API 19 will continue to see the previous behavior in which all alarms are delivered exactly when requested.
reference: http://developer.android.com/reference/android/app/AlarmManager.html
This example also show how to determine calling set() or setExact() depends on Build.VERSION.SDK_INT. But no demo how in-exact with calling set(), because alarms scheduled in the near future will not be deferred as long as alarms scheduled far in the future.
AlarmReceiver.java
package com.example.androidalarm;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class AlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,
"AlarmReceiver.onReceive()",
Toast.LENGTH_LONG).show();
}
}
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.androidalarm.MainActivity" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:autoLink="web"
android:text="http://android-er.blogspot.com/"
android:textStyle="bold" />
<Chronometer
android:id="@+id/chronometer"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" />
<Button
android:id="@+id/setnocheck"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Set Alarm 10 sec later - alarmManager.set()" />
<Button
android:id="@+id/setwithversioncheck"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Set Alarm 10 sec later - with SDK Version check" />
</LinearLayout>
MainActivity.java
package com.example.androidalarm;
import java.util.Calendar;
import android.support.v7.app.ActionBarActivity;
import android.annotation.SuppressLint;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.SystemClock;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Chronometer;
import android.widget.Toast;
public class MainActivity extends ActionBarActivity {
Chronometer chronometer;
Button btnSetNoCheck, btnSetWithVerCheck;
final static int RQS_1 = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
chronometer = (Chronometer)findViewById(R.id.chronometer);
btnSetNoCheck = (Button)findViewById(R.id.setnocheck);
btnSetNoCheck.setOnClickListener(onClickListener);
btnSetWithVerCheck = (Button)findViewById(R.id.setwithversioncheck);
btnSetWithVerCheck.setOnClickListener(onClickListener);
}
@SuppressLint("NewApi")
OnClickListener onClickListener = new OnClickListener(){
@Override
public void onClick(View v) {
chronometer.setBase(SystemClock.elapsedRealtime());
chronometer.start();
//10 seconds later
Calendar cal = Calendar.getInstance();
cal.add(Calendar.SECOND, 10);
Intent intent = new Intent(getBaseContext(), AlarmReceiver.class);
PendingIntent pendingIntent =
PendingIntent.getBroadcast(getBaseContext(),
RQS_1, intent, PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmManager =
(AlarmManager)getSystemService(Context.ALARM_SERVICE);
if(v==btnSetNoCheck){
alarmManager.set(AlarmManager.RTC_WAKEUP,
cal.getTimeInMillis(), pendingIntent);
Toast.makeText(getBaseContext(),
"call alarmManager.set()",
Toast.LENGTH_LONG).show();
}else{
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT)
{
alarmManager.set(AlarmManager.RTC_WAKEUP,
cal.getTimeInMillis(), pendingIntent);
Toast.makeText(getBaseContext(),
"call alarmManager.set()",
Toast.LENGTH_LONG).show();
}else{
alarmManager.setExact(AlarmManager.RTC_WAKEUP,
cal.getTimeInMillis(), pendingIntent);
Toast.makeText(getBaseContext(),
"call alarmManager.setExact()",
Toast.LENGTH_LONG).show();
}
}
}
};
}
Need to modify AndroidManifest.xml to add <receiver android:name=".AlarmReceiver" android:process=":remote" />
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.androidalarm"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="22" />
<application
android:allowBackup="true"
android:icon="@drawable/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>
</activity>
<receiver android:name=".AlarmReceiver" android:process=":remote" />
</application>
</manifest>
Download the files.
Thankyou for your tutorial, it is very usefull for me and it works..
ReplyDeleteI want to ask. in this tutorial you set the time for 10 seconds.
how about if i want the time for 1 hour or 1 week?
I'm already try for 1 hour, i add the code like this:
cal.add(Calendar.HOUR, 1):
but the results is strange, the notification sometimes didn't out, even it is come but then dissappear very fast..
can you help me?
Regards,