I am writing a simple Android program that triggers an alarm 15 seconds after the application initialization (plays the default ringtone and pushes a notification) through AlarmManager
. Below is my code:
MainActivity.java :
package com.example.basicalarmsetter;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
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;
public class MainActivity extends AppCompatActivity {
private int uniqueId = 0;
// Schedules a notification in the future given the delay
@RequiresApi(api = Build.VERSION_CODES.O)
private void scheduleNotification(int matchId, long delay) {
// Construct the PendingIntent which will trigger our alarm to go off
Intent notificationIntent = new Intent();
notificationIntent.setAction("com.example.basicalarmsetter.MatchNotification");
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), matchId, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT) ;
long futureInMillis = SystemClock.elapsedRealtime() + delay;
// Set off our PendingIntent
AlarmManager alarmManager = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, futureInMillis, pendingIntent);
assert alarmManager != null;
alarmManager.setExact(AlarmManager. ELAPSED_REALTIME_WAKEUP, futureInMillis, pendingIntent);
}
// Sets an Alarm at a future specified date
@RequiresApi(api = Build.VERSION_CODES.O)
private void setAlarm(long notificationDelay) {
try {
System.out.println("Setting alarm at " + notificationDelay + " seconds");
// Sets off a notification after 5 seconds
scheduleNotification(uniqueId, notificationDelay);
uniqueId++;
} catch (Exception ex) {
System.out.println("Cannot print alarm!");
System.out.println("Exception: " + ex.toString());
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setAlarm(15000);
}
}
AndroidManifest.xml :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.basicalarmsetter">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver
android:name="com.example.basicalarmsetter.MatchNotification"
android:enabled="true"
android:exported="true">
<intent-filter>
...
<action android:name="com.example.notificationtest.MatchNotification" />
</intent-filter>
</receiver>
</application>
</manifest>
MatchNotification.kt :
package com.example.basicalarmsetter
import android.app.Notification
import android.app.NotificationManager
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.media.MediaPlayer
import android.media.RingtoneManager
import android.net.Uri
import androidx.core.app.NotificationCompat
class MatchNotification : BroadcastReceiver() {
var NOTIFICATION_ID = "notification-id"
var NOTIFICATION_CHANNEL_ID = "10001";
private lateinit var player: MediaPlayer;
private lateinit var context: Context;
// Construct the notification to push to the user given the teams in the match
private fun getNotification(
content: String
): Notification? {
val builder = NotificationCompat.Builder(
context,
"default"
)
builder.setContentTitle("NBA Alarm")
builder.setStyle(NotificationCompat.BigTextStyle().bigText(content))
builder.setContentText(content)
builder.setSmallIcon(R.drawable.ic_launcher_foreground)
builder.setAutoCancel(true)
builder.setChannelId(NOTIFICATION_CHANNEL_ID)
return builder.build()
}
override fun onReceive(context: Context, intent: Intent) {
System.out.println("Match Notification Activated.");
this.context = context
val notificationManager =
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val id = intent.getIntExtra(NOTIFICATION_ID, 0)
notificationManager.notify(id, getNotification("Trigger Notification!"))
// Retrieve the URI of the alarm the user has set
var ringtoneUri:Uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE)
player = MediaPlayer.create(context, ringtoneUri)
player.start()
}
}
This seems strange, consdering that I have specified my MatchNotification
class as a receiver
in my AndroidManifest.xml
file.
Devices Tested On :
Note: The solution should have the MainActivity code in Java
This part of your code seems wrong:
notificationIntent.setAction("com.example.basicalarmsetter.MatchNotification");
You're using the class name here. You need to use the action of the broadcast receiver, the one you put in your intent filter, aka:
notificationIntent.setAction("com.example.notificationtest.MatchNotification");
Another issue: You're creating two alarms, which is unnecessary, at here:
AlarmManager alarmManager = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, futureInMillis, pendingIntent);
assert alarmManager != null;
alarmManager.setExact(AlarmManager. ELAPSED_REALTIME_WAKEUP, futureInMillis, pendingIntent);
At this section, following lines are unnecessary:
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, futureInMillis, pendingIntent);
assert alarmManager != null;
The value RTC_WAKEUP is supposed to be used with System.currentTimeMillis()
, not SystemClock.elapsedRealtime()
.
The final of your MainActivity.java would look like this:
package com.example.basicalarmsetter;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
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;
public class MainActivity extends AppCompatActivity {
private int uniqueId = 0;
// Schedules a notification in the future given the delay
@RequiresApi(api = Build.VERSION_CODES.O)
private void scheduleNotification(int matchId, long delay) {
// Construct the PendingIntent which will trigger our alarm to go off
Intent notificationIntent = new Intent();
notificationIntent.setAction("com.example.notificationtest.MatchNotification");
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), matchId, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT) ;
long futureInMillis = SystemClock.elapsedRealtime() + delay;
// Set off our PendingIntent
AlarmManager alarmManager = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
alarmManager.setExact(AlarmManager. ELAPSED_REALTIME_WAKEUP, futureInMillis, pendingIntent);
}
// Sets an Alarm at a future specified date
@RequiresApi(api = Build.VERSION_CODES.O)
private void setAlarm(long notificationDelay) {
try {
System.out.println("Setting alarm at " + notificationDelay + " seconds");
// Sets off a notification after 5 seconds
scheduleNotification(uniqueId, notificationDelay);
uniqueId++;
} catch (Exception ex) {
System.out.println("Cannot print alarm!");
System.out.println("Exception: " + ex.toString());
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setAlarm(15000);
}
}
i have a solution that worked for me. Set alert as follow:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
long delayInMillis = 5000;//your delay in millisecond
Intent myIntent = new Intent(this, AlertReceiver.class);
//any data you want to pass to your receiver class
myIntent.putExtra(AlertReceiver.TITLE, "Scheduled Alert");
myIntent.putExtra(AlertReceiver.CONTENT, "You have scheduled alert. Tap here to view continue...");
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, myIntent, 0);
alarmManager.set(AlarmManager.RTC_WAKEUP, delayInMillis, pendingIntent);
}
}
add reveiver in your manifest
<receiver android:name=".utils.AlertReceiver" />//path to your receiver
your alert receiver class can be something like this
public class AlertReceiver extends BroadcastReceiver {
private static final String TAG = "AlertReceiver";
public static final String TITLE = "title";
public static final String CONTENT = "content";
@Override
public void onReceive(Context context, Intent receivedIntent) {
String title = receivedIntent.getStringExtra(TITLE);
String message = receivedIntent.getStringExtra(CONTENT);
Log.e(TAG, "onReceive: " + title + ":" + message);
//you can show your notification or anything you want to do once you receive your alert here...
}
}
hope this helps. Happy codding!!
class MyActivity : AppCompatActivity() {
private var alarmManager: AlarmManager? = null
private var broadcastReceiver: BroadcastReceiver? = null
private var pendingIntent: PendingIntent? = null
private val REQUEST_CODE = 45645
private var id: String? = "myname"
private var timeInMilliSeconds: Long = 15000
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
initAlarm()
}
private fun initAlarm() {
//creating intent
val intent = Intent(id)
val alarmRunning = PendingIntent.getBroadcast(
this,
REQUEST_CODE,
intent,
PendingIntent.FLAG_NO_CREATE
) != null
//setting broadcast
broadcastReceiver = getBroadcastReceiver()
registerReceiver(
broadcastReceiver,
IntentFilter(id)
)
//setting alarm
val ensurePositiveTime = Math.max(timeInMilliSeconds, 0L)
pendingIntent = PendingIntent.getBroadcast(
this,
REQUEST_CODE,
intent,
PendingIntent.FLAG_UPDATE_CURRENT
)
//Check if alarm is already running
if (!alarmRunning) {
alarmManager?.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + ensurePositiveTime, pendingIntent)
} else {
updateAlarm()
Log.e("Alarm", "Alarm already running.!")
}
}
private fun updateAlarm() {
//calculating alarm time and creating pending intent
val intent = Intent(id)
val ensurePositiveTime = Math.max(timeInMilliSeconds, 0L)
pendingIntent = PendingIntent.getBroadcast(
this,
REQUEST_CODE,
intent,
PendingIntent.FLAG_UPDATE_CURRENT
)
//removing previously running alarm
alarmManager?.cancel(pendingIntent)
unregisterReceiver(broadcastReceiver)
//setting broadcast
broadcastReceiver = getBroadcastReceiver()
registerReceiver(
broadcastReceiver,
IntentFilter(id)
)
//Check if alarm is already running
alarmManager?.set(
AlarmManager.RTC_WAKEUP,
System.currentTimeMillis() + ensurePositiveTime,
pendingIntent
)
Log.e("Alarm", "Alarm updated..!")
}
/**
* This will receive broadcast after completed seconds
*/
private fun getBroadcastReceiver(): BroadcastReceiver {
return object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
createNotification()
}
}
}
/***
* It creates notification
*/
private fun createNotification() {
val channelId = "fcm_default_channel"
val channelName = "notification"
val defaultSoundUri =
RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
val notificationBuilder = NotificationCompat.Builder(this@MyActivity, channelId)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentText("I am alarm from my activity")
.setContentTitle(getString(R.string.app_name))
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setDefaults(NotificationCompat.DEFAULT_ALL)
.setPriority(NotificationCompat.PRIORITY_HIGH)
val mNotificationManager =
getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel =
NotificationChannel(
channelId,
channelName,
NotificationManager.IMPORTANCE_HIGH
)
notificationBuilder.setChannelId(channelId)
mNotificationManager.createNotificationChannel(channel)
}
val notification = notificationBuilder.build()
mNotificationManager.notify(0, notification)
}
/**
* Use this to cancel alarm
*/
private fun cancelAlarm() {
if (pendingIntent != null) {
alarmManager?.cancel(pendingIntent)
}
if (broadcastReceiver != null) {
unregisterReceiver(broadcastReceiver)
broadcastReceiver = null
}
Log.e("Alarm", "Alarm has been canceled..!")
}
}
public class AlarmActivity extends AppCompatActivity {
private AlarmManager alarmManager;
private PendingIntent pendingIntent;
private int REQUEST_CODE = 45645;
private String id = "myname";
private long timeInMilliSeconds = 5000;
static String APP_TAG = "classname";
private BroadcastReceiver broadcastReceiver;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
initAlarm();
}
private void initAlarm() {
//creating intent
Intent intent = new Intent(id);
boolean alarmRunning = PendingIntent.getBroadcast(
this,
REQUEST_CODE,
intent,
PendingIntent.FLAG_NO_CREATE
) != null;
//setting broadcast
broadcastReceiver = new MyReceiver();
registerReceiver(
broadcastReceiver,
new IntentFilter(id)
);
//setting alarm
long ensurePositiveTime = Math.max(timeInMilliSeconds, 0L);
pendingIntent = PendingIntent.getBroadcast(
this,
REQUEST_CODE,
intent,
PendingIntent.FLAG_UPDATE_CURRENT
);
//Check if alarm is already running
if (!alarmRunning) {
alarmManager.set(
AlarmManager.RTC_WAKEUP,
System.currentTimeMillis() + ensurePositiveTime,
pendingIntent
);
} else {
updateAlarm();
Log.e("Alarm", "Alarm already running.!");
}
}
private void updateAlarm() {
//calculating alarm time and creating pending intent
Intent intent = new Intent(id);
long ensurePositiveTime = Math.max(timeInMilliSeconds, 0L);
pendingIntent = PendingIntent.getBroadcast(
this,
REQUEST_CODE,
intent,
PendingIntent.FLAG_UPDATE_CURRENT
);
//removing previously running alarm
alarmManager.cancel(pendingIntent);
unregisterReceiver(broadcastReceiver);
//setting broadcast
broadcastReceiver = new MyReceiver();
registerReceiver(
broadcastReceiver,
new IntentFilter(id)
);
//Check if alarm is already running
alarmManager.set(
AlarmManager.RTC_WAKEUP,
System.currentTimeMillis() + ensurePositiveTime,
pendingIntent
);
Log.e("Alarm", "Alarm updated..!");
}
/**
* Use this to cancel alarm
*/
private void cancelAlarm() {
if (pendingIntent != null) {
alarmManager.cancel(pendingIntent);
}
if (broadcastReceiver != null) {
unregisterReceiver(broadcastReceiver);
broadcastReceiver = null;
}
Log.e("Alarm", "Alarm has been canceled..!");
}
}
class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
WakeLocker.acquire(context);
createNotification(context);
WakeLocker.release();
}
/***
* It creates notification
* @param context
*/
private void createNotification(Context context) {
String channelId = "fcm_default_channel";
String channelName = "notification";
Uri defaultSoundUri =
RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context, channelId)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentText("I am alarm from my activity")
.setContentTitle(context.getString(R.string.app_name))
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setDefaults(NotificationCompat.DEFAULT_ALL)
.setPriority(NotificationCompat.PRIORITY_HIGH);
NotificationManager mNotificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel =
new NotificationChannel(
channelId,
channelName,
NotificationManager.IMPORTANCE_HIGH
);
notificationBuilder.setChannelId(channelId);
mNotificationManager.createNotificationChannel(channel);
}
Notification notification = notificationBuilder.build();
mNotificationManager.notify(0, notification);
}
}
public abstract class WakeLocker {
private static PowerManager.WakeLock wakeLock;
public static void acquire(Context c) {
if (wakeLock != null) wakeLock.release();
PowerManager pm = (PowerManager) c.getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK |
PowerManager.ACQUIRE_CAUSES_WAKEUP |
PowerManager.ON_AFTER_RELEASE, AlarmActivity.APP_TAG);
wakeLock.acquire();
}
public static void release() {
if (wakeLock != null){
wakeLock.release();
}
wakeLock = null;
}
}
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.VIBRATE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Alarmdemo">
<activity android:name=".AlarmActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name="com.example.alarmdemo.MyReceiver" />
</application>
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.