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>
Related
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.
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 a widget that upon button press I send broadcast to service. But I am not receving any broadcast in my onReceive().
My intention is basically on widget button click, it tellls service to perform some action.
But I am unable to receive any broadcast from widget in service.
Here is my widget code -
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
RemoteViews remoteViews;
ComponentName componentName;
remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
componentName = new ComponentName(context, MyWidgetProvider.class);
remoteViews.setOnClickPendingIntent(R.id.play,getPendingSelfIntent(context, "PLAY",componentName));
appWidgetManager.updateAppWidget(componentName, remoteViews);
}
#Override
public void onReceive(Context context, Intent intent)
{
super.onReceive(context, intent);
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
RemoteViews remoteViews;
ComponentName componentName;
remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
componentName = new ComponentName(context, MyService.class);
if (intent.getAction().equals("PLAY")) {
Log.d("hi","PLAY0");
remoteViews.setOnClickPendingIntent(R.id.engine_lock_unlock,getPendingSelfIntent(context,"PLAY",componentName));
serviceIntent = new Intent(context,MyService.class);
serviceIntent.setAction("PLEASE_PLAY");
Log.d("hi","PLAY1");
context.sendBroadcast(serviceIntent);
}
appWidgetManager.updateAppWidget(componentName, remoteViews);
}
protected PendingIntent getPendingSelfIntent(Context context, String action, ComponentName componentName) {
Intent intent = new Intent(context, MyWidgetProvider.class);
intent.setAction(action);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, componentName);
return PendingIntent.getBroadcast(context, 0, intent, 0);
}
In MyService,
public class ServiceWidgetReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("hi","PLAY2");
if (intent.getAction().equals("PLEASE_PLAY")) {
}
}
}
My MAnifest looks like this -
<receiver android:name=".widget.MyWidgetProvider" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="#xml/homescreen_widget_preview" />
</receiver>
<receiver android:name=".service.MyService$ServiceWidgetReceiver" />
I only get the logs -
PLAY0
PLAY1
Why I dont get my broadcast???
Seams that your receiver has no intent-filter provided. Try to add this in your mainfest file:
<receiver android:name=".service.MyService$ServiceWidgetReceiver">
<intent-filter>
<action android:name="PLEASE_PLAY" />
</intent-filter>
</receiver>
I assume that you have implement the action in intent-filter like Myon said, but the still no broadcast to the onReceive. you may try this:
protected PendingIntent getPendingSelfIntent(Context context, String action, ComponentName componentName) {
Intent intent = new Intent(context, MyWidgetProvider.class);
intent.setAction(action);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, componentName);
//this line replace the original
return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
Actually, i have facing the similar problem yesterday that my widget work fine on my android 5.1 phone. However, I find it cannot perform click on android 7.0 sony phone. I still trying to find out whether is the sony phone os problem or android 7.0 or after problem because after the upgrade of the 7.0 or after, there is so many different issues appeared as they changed quite a lot in the API. Anyway, I used the PendingIntent.FLAG_UPDATE_CURRENT solved the problem I have on 7.0
I just think will directly register the receiver class to manifest like this be work. The service binded doesnt directly affect the receive, as the only thing affect the receiver is context. So, maybe just the receive class is enough.
<receiver android:name="packageName.ServiceWidgetReceiver">
<intent-filter>
<action android:name="PLEASE_PLAY" />
</intent-filter>
</receiver>
I found out the mistake I was doing. I had to registerreceiver and unregister it in Service itself rather in Manifest.
This worked for me.
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/