Recently I just transferred all my code from a Xamarin.Forms Project which had local notifications representing alarms to a Android project in Android studio. The flow of scheduling this alarm is as follows and worked just fine in the Xamarin project but won't fire in the Android project:
Create Alarm Here using a Controller class
//Get the time in string format with the meridian
SimpleDateFormat timeFormatter = new SimpleDateFormat("hh:mm");
String timeString = timeFormatter.format(new Date(oneTimeAlarm.getTime()));
SimpleDateFormat meridianFormatter = new SimpleDateFormat("a");
String meridianString = meridianFormatter.format(new Date(oneTimeAlarm.getTime()));
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmReceiver.class);
//Provide Settings
intent.putExtra("Vibrate", alarm.getVibrateOn());
intent.putExtra("Id", alarm.getId());
intent.putExtra("Snooze", alarm.getSnoozeLength());
intent.putExtra("Time",timeString);
intent.putExtra("Meridian",meridianString);
intent.putExtra("Uri", alarm.getRingtoneURI());
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,0,intent,PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.setExact(AlarmManager.RTC_WAKEUP, alarm.getTime(),pendingIntent);
Toast.makeText(context,"Alarm Scheduled!",Toast.LENGTH_SHORT).show();
The Controller successfully schedules the alarm with the proper settings and uses the AlarmManager to set the proper trigger time.
AlarmerReceiver which is a custom BroadcastReceiver
public class AlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent){
//Get values for alarm
Boolean vibrate = intent.getBooleanExtra("Vibrate",false);
String ringtoneURI = intent.getStringExtra("Uri");
int id = intent.getIntExtra("Id",0);
int snoozeLength = intent.getIntExtra("Snooze",5);
String displayTime = intent.getStringExtra("Time");
String displayMeridian = intent.getStringExtra("Meridian");
//If this is an update cancel the original
Intent cancel = new Intent("Dismiss");
PendingIntent cancelPending = PendingIntent.getBroadcast(context,id,cancel,PendingIntent.FLAG_CANCEL_CURRENT);
//Pass parameters to AlarmActivity so it can have same settings for snooze refire.
Intent alarmIntent = new Intent(context,AlarmActivity.class);
alarmIntent.putExtra("SNOOZE",snoozeLength);
alarmIntent.putExtra("VIBRATE",vibrate);
alarmIntent.putExtra("URI",ringtoneURI);
alarmIntent.putExtra("ID",id);
alarmIntent.putExtra("TIME",displayTime);
alarmIntent.putExtra("MERIDIAN",displayMeridian);
PendingIntent pendingAlarmIntent = PendingIntent.getActivity(context,id,alarmIntent,PendingIntent.FLAG_ONE_SHOT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
//Build Notification
builder.setCategory(Notification.CATEGORY_ALARM)
.setSmallIcon(R.drawable.ic_home_black_24dp)
.setFullScreenIntent(pendingAlarmIntent,true)
.setContentIntent(pendingAlarmIntent)
.setContentTitle("NapChat Alarm")
.setContentText("Open Alarm")
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setPriority(Notification.PRIORITY_MAX)
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM))
.setDefaults(Notification.DEFAULT_VIBRATE | Notification.DEFAULT_LIGHTS);
NotificationManager manager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
manager.notify(id,builder.build());
Activity shown when alarm fires
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Window window = this.getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
//window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
window.addFlags(WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON);
setContentView(R.layout.activity_alarm);
initialize();
...
Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.alarmsproject.alarmsprojectandroid">
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.SET_ALARM"/>
<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/AppTheme">
<activity android:name=".Activities.LoginActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".Activities.SignUpActivity" />
<activity
android:name=".Activities.HomeActivity"
android:label="@string/title_activity_home" />
<activity android:name=".Activities.OptionsActivity" />
<activity
android:name=".Activities.AlarmActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="@string/title_activity_alarm"
android:theme="@style/FullscreenTheme" />
<activity android:name=".Activities.CreateAlarmActivity"></activity>
</application>
</manifest>
Can anyone discern where I am going wrong here and why it won't fire. I am targeting API level 25 to avoid using the NotificationsChannel that came out for API 26. Why won't my notifications show? Especially since the exact code worked months before.
You need to register the receiver in the manifest.
<application ...>
<receiver android:name=".AlarmReceiver"></receiver>
</application>
You probably had this decorator in your Xamarin project and removed it when you transferred it? Which might explain how it worked in Xamarin.
[BroadcastReceiver(Enabled = true)]