I have a BroadcastReceiver:
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// show will check date and return 0 or 1.
if(show == 1) {
//notify
Intent intent2 = new Intent(context, MainActivity.class);
showNotification(context, "title", "description", intent2);
}
AlarmManager alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intentn = new Intent(context, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intentn, 0);
Calendar time = Calendar.getInstance();
time.setTimeInMillis(System.currentTimeMillis());
// set next alarm, I also have this in my MainActivity to run it first time every 15 min (900 sec):
if(android.os.Build.VERSION.SDK_INT>=23) {
alarmMgr.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP,System.currentTimeMillis() + (1000*900), pendingIntent);
}
else{
alarmMgr.setExact(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (1000*900), pendingIntent);
}
}
In manifest I have this:
<receiver
android:name=".AlarmReceiver"
android:enabled="true"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON"/>
<action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
The problem is sometimes it plays, sometimes not. Sometimes when I close the app it continue to play, sometimes not. Any ideas why?
I'm testing in android 8.
Remove:
android:permission="android.permission.RECEIVE_BOOT_COMPLETED"
With that, you are saying that the sender of the broadcast has to hold this permission, and that is incorrect.
Your app needs a <uses-permission> element for android.permission.RECEIVE_BOOT_COMPLETED, though.
Related
I am trying set set an alarm using pending intent from the activity,
Below code works fine when the application is running in foreground or background,
But the activity is not launching from OnReceive when the application is not running.
Creating pending intent and setting alarm in activity,
intent = new Intent(getApplicationContext(), AlaramReceiver.class);
alarmManager = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 1001, intent, PendingIntent.FLAG_CANCEL_CURRENT);
alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+10000, pendingIntent);
Handling OnReceive event
public class AlaramReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent)
Intent intent1 = new Intent(context.getApplicationContext(), AlaramActivity.class);
intent1.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
intent1.setClassName("mad.todo","mad.todo.notify.AlaramActivity");
context.startActivity(intent1);
}
}
receiver in AndroidManifest.xml
<receiver
android:name=".notify.AlaramReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
<action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" />
</intent-filter>
</receiver>
I'm trying to send a notification at a particular time, this part works perfectly but after I reboot the phone, the service doesn't get started unless the app is opened which then starts the service. I've tried multiple solutions online but still can't fix the issue.
Activity:
private void startNotificationAlarm() {
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, ReminderBroadcastReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, (int) ((new Date().getTime() / 1000L) % Integer.MAX_VALUE), intent, 0);
Objects.requireNonNull(alarmManager).setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
BroadcastReceiver:
public class ReminderBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
Intent serviceIntent = new Intent(context, BootService.class);
intent.setAction("<package>.Receiver");
context.startService(serviceIntent);
} else {
scheduleNotification(context, intent);
}
}
private void scheduleNotification(Context context, Intent intent) {
Notification notification = new NotificationCompat.Builder(context, BaseApp.CHANNEL_ID)
.setSmallIcon(R.drawable.ic_calendar_alert)
.setContentTitle(title)
.setContentText(message)
.setColor(color)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setCategory(NotificationCompat.CATEGORY_REMINDER)
.setAutoCancel(true)
.setOnlyAlertOnce(false)
.setStyle(new NotificationCompat.BigTextStyle().bigText(message))
.build();
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Objects.requireNonNull(notificationManager).notify((int) ((new Date().getTime() / 1000L) % Integer.MAX_VALUE), notification);
}
IntentService:
public class BootService extends IntentService {
public BootService() {
super("BootService");
}
#Override
protected void onHandleIntent(Intent intent) {
if (intent != null) {
try {
Thread.sleep(5000);
startNotification();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Manifest
<receiver
android:name=".Receiver.ReminderBroadcastReceiver" android:enabled="true" android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
</intent-filter>
</receiver>
<service android:name=".Service.BootService"/>
You have to provide below permission in manifest:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
Also you have to make android:exported as true
as per android docs:
android:exported
Whether or not the broadcast receiver can receive messages from sources outside its application — "true" if it can, and
"false" if not. If "false", the only messages the broadcast receiver
can receive are those sent by components of the same application or
applications with the same user ID.
sample code
<receiver android:name=".sample.BootReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
Test: sdk 19
My manifest
<receiver android:name=".pushnotification.TimeAlarm"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
I set up alarm manager
private void setAlarm(String portionName, String orderId, int time, int requestCode) {
Intent intent = new Intent(this, TimeAlarm.class);
intent.putExtra(TimeAlarm.PORTION_NAME, portionName);
intent.putExtra(MainScreenActivity.ORDER_ID, orderId);
intent.putExtra(ALARM_REQUEST_KEY, requestCode);
int id = (int) System.currentTimeMillis();
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, id, intent, FLAG_ONE_SHOT);
AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + time, pendingIntent);
}
This is my receiver
public class TimeAlarm extends BroadcastReceiver {
public static final String PORTION_NAME = "portionName";
private NotificationManager mNotifyMgr;
#Override
public void onReceive(Context context, Intent intent) {
int notificationId = (int) System.currentTimeMillis();
//Do something here
}
}
I have tried a lot of solutions and I can see nothing wrong with my code. But the receiver cannot receive alarm broadcast when the app is closed. When the app is paused, it works ok
You should also register for this intent
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
I have been trying to slowly learn the Android API over the past month. I have read documentation, viewed examples and can't seem to figure out what I'm doing incorrectly. Basically the app sets an alarm 1 minute exactly after the app was started.
The issue I am currently having is after setting an alarm, it isn't being received. Here's what I have:
SetAlarmActivity.java
public class SetAlarmActivity extends AppCompatActivity {
private final String TAG = "AlarmTest";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_set_alarm);
Calendar c = Calendar.getInstance();
c.add(Calendar.MINUTE, 1);
Log.d(TAG, "Alarm time is " + c.getTime());
// set the intent to launch our SetAlarmActivity
Intent alarmIntent = new Intent(SetAlarmActivity.this, SetAlarmActivity.class);
// retrieve a PendingIntent to perform a Broadcast
PendingIntent pendingAlarmIntent = PendingIntent.getBroadcast(SetAlarmActivity.this, 0, alarmIntent, 0);
// grab the Alarm Service and tell it to call our Intent at the set time
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pendingAlarmIntent);
}else{
alarmManager.set(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pendingAlarmIntent);
}
}
}
AlarmReceiver.java
public class AlarmReceiver extends WakefulBroadcastReceiver {
private final String TAG = "AlarmTest";
#Override
public void onReceive(Context context, Intent intent){
Log.d(TAG, "Received broadcast!");
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="bz.bdu.alarmtest" >
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme" >
<activity android:name=".SetAlarmActivity" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".AlarmReceiver" />
</application>
</manifest>
You have to create the intent between the Current activity and receiver class. change your code like this.
Intent intent = new Intent(SetAlarmActivity.this, AlarmReceiver.class);
change
Intent alarmIntent = new Intent(SetAlarmActivity.this,
SetAlarmActivity.class);
to
Intent alarmIntent = new Intent(SetAlarmActivity.this,
AlarmReceiver.class);
then its works fine
I have a receiver that works well, but I can't seem to show a proper UI, although the toast appears correctly. As far as I can tell, this is caused by Android requiring the class to extend Activity, however, the class already extends BroadcastReceiver, so I can't do this.
So, I tried to do an Intent, but this failed too. There are no errors, but the screen doesn't show. Source code is below.
Broadcast (Method in AndyRoidAlarm)
public void setAlarm(){
Intent intent = new Intent(AndyRoidAlarm.this, Reciever.class);
PendingIntent sender = PendingIntent.getBroadcast(AndyRoidAlarm.this,
0, intent, 0);
// We want the alarm to go off 30 seconds from now.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.SECOND, 10);
// Schedule the alarm!
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), sender);
// Tell the user about what we did.
if (mToast != null) {
mToast.cancel();
}
mToast = Toast.makeText(AndyRoidAlarm.this, "Alarm Scheduled for 30secs", Toast.LENGTH_LONG);
mToast.show();
}
Reciever
public class Reciever extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
Toast.makeText(context, "Alarm Received", Toast.LENGTH_LONG).show();
Intent i = new Intent();
i.setClass(context, AlarmRing.class);
}
}
Reciever V2
#Override
public void onReceive(Context context, Intent intent)
{
Toast.makeText(context, "Alarm Received", Toast.LENGTH_LONG).show();
Intent foo = new Intent(context, AlarmRing.class);
//foo.putExtra("id", "id");//example, if you wish to pass custom variables
context.startActivity(foo);
}
AlarmRing
public class AlarmRing extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.alarm);
MediaPlayer mp = MediaPlayer.create(getBaseContext(), R.raw.sweetchild);
mp.start();
}
Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.comaad.andyroidalarm"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name=".AndyRoidAlarm"
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="com.comaad.andyroidalarm.Reciever" android:enabled="true">
<intent-filter>
<action android:name="com.comaad.andyroidalarm.Reciever"></action>
</intent-filter>
</receiver>
<activity android:name=".AlarmRing"></activity>
</application>
</manifest>
}
In a BroadcastReceiver onReceive() method, if you need a Context (e.g., to create an Intent), use the Context that is passed to you as a parameter of onReceive(). You even have this code in your onReceive() -- you're just not doing anything with the resulting Intent (e.g., calling startActivity()).
Intent foo = new Intent(this, AlarmRing.class);
foo.putExtra("id", id);//example, if you wish to pass custom variables
this.startActivity(foo);
Edit
Check out this example to use BroadcastReciever within an Activity. http://almondmendoza.com/2009/01/04/getting-battery-information-on-android/