Hi i asked a question before related to Broadcast here
they suggest me to add broadcast receiver class in Manifest file and then register its instances in Activity's onCreate method
so here is code of my manifest file
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.riteshmapsapplicationdemo"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
<uses-permission android:name="android.permission.VIBRATE" />
<application
android:icon="#drawable/app_icon"
android:label="Tring On Train"
android:theme="#style/AppTheme" >
<uses-library android:required="true"
android:name="com.google.android.maps"/>
<activity
android:name=".MainActivity"
android:label="Tring On Train" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".AlarmActivity"
android:label="Alarm" />
<activity
android:name=".Address_List_Activity"
android:label="Saved Locations" />
<receiver android:name=".ProximityAlertReceiver" >
</receiver>
</application>
</manifest>
and here is code segment of onCreate's method where i am registering instances of BroadCast Receiver class.
String s=System.currentTimeMillis()+"";
PendingIntent proximityIntent = PendingIntent.getBroadcast(getApplicationContext(), i, intent, PendingIntent.FLAG_UPDATE_CURRENT);
locationManager.addProximityAlert(
latitude, // the latitude of the central point of the alert region
longitude, // the longitude of the central point of the alert region
1000, // the radius of the central point of the alert region, in meters
-1, // time for this proximity alert, in milliseconds, or -1 to indicate no expiration
proximityIntent // will be used to generate an Intent to fire when entry to or exit from the alert region is detected
);
IntentFilter filter = new IntentFilter(PROX_ALERT_INTENT+s);
registerReceiver(new ProximityAlertReceiver(), filter);
and code of My ProximityAlert class is
public class ProximityAlertReceiver extends BroadcastReceiver {
private static final int NOTIFICATION_ID = 1000;
public static final String PREFS_NAME = "MyPrefsFile";
#Override
public void onReceive(Context context, Intent intent) {
String key = LocationManager.KEY_PROXIMITY_ENTERING;
SharedPreferences shared=context.getSharedPreferences(MainActivity.PREFS_NAME,0);
Boolean entering = intent.getBooleanExtra(key, false);
Double longitude=intent.getDoubleExtra("longitude", 0.0);
Double latitude=intent.getDoubleExtra("latitude",0.0);
Intent in = new Intent(context,AlarmActivity.class);
in.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
in.putExtra("longitude", longitude);
in.putExtra("latitude", latitude);
Log.i("cont1", shared.getInt("count", 0)+"");
in.putExtra("count",shared.getInt("count", 0));
context.startActivity(in);
}
}
now last time Broadcast receiver working when activity is in foreground but this time Broadcast receiver is not working in any situation can any one please notify me where i am wrong??
Your not defined what type of broadcast receiver you want to receive..try to add intent-filter in the manifest receiver tag. The the android will send you.
You want to receive broadcasts when not running Activity in foreground. For that you need to add valid intent-filter to your receiver in AndroidManifest.xml
For example:
<receiver android:name=".ProximityAlertReceiver" >
<intent-filter>
<action android:name="com.your.app.example_filter_1" />
<action android:name="com.your.app.example_filter_2" />
<!-- etc -->
</intent-filter>
</receiver>
Related
My goal is to have a daily reminder that sends a notification to the user, and I implemented this using an AlarmManager. However, I should've looked more closely at the docs, since they stated in the Android 10 changes that Receivers in Android no longer continue to broadcast after the app is killed, so save and optimize battery life. So my app works if it is in the foreground, but when it is paused or killed (home button or swiped away), then it no longer sends the notification.
So I looked into alternatives, but JobScheduler seems to be inexact and unable to be set to a specific time daily. WorkManager solves the battery optimizer issue but again, cannot be set to a specific time daily. So my question is can AlarmManager still accomplish what I need it to, or did I miss something about the other two options?
I have looked through a few threads with no success, and a common solution seems to be to register your receiver in the main acitivity, which I have done:
#Override
protected void onPause() {
if (mIsReceiverRegistered) {
this.unregisterReceiver(mReceiver);
mReceiver = null;
mIsReceiverRegistered = false;
}
super.onPause();
MainActivity.activityPaused();
}
#Override
protected void onResume() {
super.onResume();
Uri uri = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.rain);
video.setVideoURI(uri);
video.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mediaPlayer) {
mediaPlayer.setLooping(true);
}
});
video.start();
if (!mIsReceiverRegistered) {
if (mReceiver == null)
mReceiver = new AlarmReceiver();
this.registerReceiver(mReceiver, new IntentFilter("AlarmReceiver"));
mIsReceiverRegistered = true;
}
MainActivity.activityResumed();
}
but no dice.
Here is how I set the alarm in the main activity:
Intent intent = new Intent(this,AlarmReceiver.class);
alarmIntent = PendingIntent.getBroadcast(MainActivity.this, 0, intent, 0);
alarmMgr = (AlarmManager)MainActivity.this.getSystemService(Context.ALARM_SERVICE);
//alarm interval and trigger times are set for testing purposes
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 10000,65000, alarmIntent);
And my manifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.umbrellareminder">
<uses-sdk tools:overrideLibrary="com.ajts.androidmads.fontutils" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application
android:allowBackup="true"
android:icon="#mipmap/icon"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme"
android:usesCleartextTraffic="true"
tools:ignore="GoogleAppIndexingWarning">
<receiver android:name=".AlarmReceiver"/>
<receiver android:name=".BootCompletedIntentReceiver" android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data
android:name="preloaded_fonts"
android:resource="#array/preloaded_fonts" />
</application>
</manifest>
Can you spot any reason as to why BroadcastReceiver is not being called when the Alarm goes off? If I have the alarm launch an explicit intent, it works just fine and my activity opens. If I set the intent to open my BroadCastReceiver then nothing happens so I think there may be something wrong with my receiver class or the Manifest. Here's how I setup the alarm:
Intent intent = new Intent(this, AlarmBroadcastReceiver.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 324, intent, PendingIntent.FLAG_UPDATE_CURRENT);
mAlarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
mAlarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
Here's my broadcast receiver:
public class AlarmBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.e("MJH", "Alarm called...");
Toast.makeText(context, "Alarm...", Toast.LENGTH_LONG).show();
}
}
And here is my manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest package="mjh.com.apod"
xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Required to act as a custom watch face. -->
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.SET_WALLPAPER"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<application
android:name="android.support.multidex.MultiDexApplication"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
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=".AlarmBroadcastReceiver"
android:enabled="true"
android:exported="true"
android:process=":remote">
</receiver>
</application>
Thank you so very much for your time.
I think you should be using PendingIntent.getBroadcast( instead of PendingIntent.getActivity(.
I had to call getBroadcast rather than getActivity to create the PendingIntent. That fixed it.
In my App, I'm using AlarmManager for transmitting keep-alive every day once a day.
I'm using the following code for starting athe AlaramManager
Calendar calendar = DateUtils
.getNextKeepAliveTime(keepAliveHours, keepAliveMinutes);
Intent intent = new Intent(this, AlarmReceiver.class);
PendingIntent sender = PendingIntent.getBroadcast(getApplicationContext(),
ALARM_REQUEST_CODE, intent, 0); // PendingIntent.FLAG_UPDATE_CURRENT);
// Get the AlarmManager service
Log.d(TAG, "cal: " + calendar.toString());
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
long diff = calendar.getTimeInMillis() - System.currentTimeMillis();
if(diff < 0) diff = AlarmManager.INTERVAL_FIFTEEN_MINUTES;
am.setInexactRepeating(AlarmManager.RTC_WAKEUP, diff, AlarmManager.INTERVAL_DAY, sender);
When activity goes background, the receiver, AlarmReceiver, does not get any event. But it working successfully when activity in foreground.
Ther receiver declaration in my manifest is -
<receiver android:name="MainActivity$AlarmReceiver" android:enabled="true" />
The manifest is
<?xml version="1.0" encoding="utf-8"?>
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="8" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.yachtdroid.ba.MainActivity"
android:label="#string/app_name"
android:launchMode="singleInstance" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.yachtdroid.ba.ui.Settings" >
</activity>
<receiver android:name="MainActivity$ChargingOnReceiver" android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
<action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" />
</intent-filter>
</receiver>
<service android:name="com.yachtdroid.ba.services.MailSenderService" />
<service android:name="com.yachtdroid.ba.services.SmsSender" />
<activity android:name="com.yachtdroid.ba.ui.YDSiteView" />
<activity
android:name="com.yachtdroid.ba.ui.BatteryAlertDialog"
android:theme="#style/NoTitleDialog" />
<activity
android:name="com.yachtdroid.ba.ui.ActivityLog"
android:theme="#style/NoTitleDialog" />
<receiver android:name="MainActivity$AlarmReceiver" android:enabled="true" />
<!-- intent-filter>
<action android:name="alarm_action"/>
</intent-filter>
</receiver -->
</application>
The receiver code is
public static class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, intent.getExtras().toString());
if (!inForeground) {
Log.d(TAG, "*** Move app to front!");
Intent it = new Intent("intent.my.action");
it.setComponent(new ComponentName(context.getPackageName(),
MainActivity.class.getName()));
it.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_CLEAR_TOP);
context.getApplicationContext().startActivity(it);
}
try {
Toast.makeText(context, "alarm message", Toast.LENGTH_SHORT).show();
MainActivity.instance.sendKeepALive();
} catch (Exception e) {
Toast.makeText(
context,
"There was an error somewhere, but we still received an alarm",
Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
}
How it can be solved?
Thanks,
Eyal.
Try to remove the code for the broadcast receiver from the Activity ,make another java file and put it there and also modify your manifest as per that
<receiver android:name=".AlarmReceiver" />
instead of
<receiver android:name="MainActivity$AlarmReceiver" android:enabled="true" />
I've a class MyBroadcastReceiver that is registered to start at boot up. The manifest is below. I am running this via eclipse on a Android Motorola Xoom wifi only tablet - which is Android 3.2, API level 13 (from the dev.android site).
I have googled for this and tried a few things:
put android:exported="true"
used android:installLocation="internalOnly" to make sure it doesn't install on the SD card
after installing on the device, I ran the app a couple of times before testing the bootup (as some links said Android 3.x onwards won't immediately start sending boot events to the app unless user has manually initiated it at least once)
However even now the broadcast receiver doesn't seem to run when the device boots up (based on logcat).
Here is my manifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mypack"
android:versionCode="1"
android:versionName="1.0"
android:installLocation="internalOnly">
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-sdk android:minSdkVersion="8" />
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name=".MainCamApp" android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".UploaderService" />
<receiver android:name=".MyBroadcastReceiver" android:enabled="true" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
</application>
</manifest>
Code for broadcast receiver -
import java.util.Calendar;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class MyBroadcastReceiverX extends BroadcastReceiver {
private String TAG = "Broadcast Receiver:";
AlarmManager alarm;
#Override
public void onReceive(Context arg0, Intent arg1) {
Log.i(TAG, "Entered onReceive.");
alarm = (AlarmManager) arg0.getSystemService(Context.ALARM_SERVICE);
Intent intentUploadService = new Intent (arg0, UploaderService.class);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.SECOND, 10);
PendingIntent pi = PendingIntent.getBroadcast(arg0, 0, intentUploadService , 0);
alarm.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 5000, pi);
Log.i(TAG, "Alarm set. Exiting onReceive.");
Intent myIntent = new Intent(arg0, UploaderService.class);
arg0.startService(myIntent);
}
}
Seems to be working now.. final manifest below if it helps -
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example"
android:versionCode="1"
android:versionName="1.0"
android:installLocation="internalOnly"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-sdk android:minSdkVersion="8" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name=".MainCamApp" android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".UploaderService" />
<receiver android:name=".MyBroadcastReceiverX" android:enabled="true" android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED">
<category android:name="android.intent.category.DEFAULT"/>
</action>
</intent-filter>
</receiver>
</application>
</manifest>
Try the following:
<receiver android:name=".MyBroadcastReceiverX" android:enabled="true" android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED">
<category android:name="android.intent.category.DEFAULT"/>
</action>
</intent-filter>
</receiver>
You also have incorrect class name specified in manifest - it should be MyBroadcastReceiverX rather then MyBroadcastReceiver
You need to write code after receiving the android.intent.action.BOOT_COMPLETED intent.
try this.
#Override
public void onReceive(Context context, Intent intent) {
Log.d("TEST", intent.getAction());
if (intent.getAction().equalsIgnoreCase(
"android.intent.action.BOOT_COMPLETED")) {
Log.i(TAG, "Entered onReceive.");
alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intentUploadService = new Intent (context, UploaderService.class);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.SECOND, 10);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, intentUploadService , 0);
alarm.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 5000, pi);
Log.i(TAG, "Alarm set. Exiting onReceive.");
//no need to initialize intent twice
// Intent myIntent = new Intent(context, UploaderService.class);
context.startService(intentUploadService );
}
}
I'm doing something I thought would be simple as have done a broadcast receiver in the past on 2.3.4 droid. I'm using 4.x now in this little program.
Here is the main architecture/flow. I want/have a receiver to be listening for a custom broadcast/intent. I created this as a stand along project/apk
public class FileIntegrityMonitor extends BroadcastReceiver
{
public String CLASS_NAME = "FileIntegrityMonitor";
#Override
public void onReceive(Context context, Intent intent)
{
Log.d(CLASS_NAME, "Entered onReceive: got broadcast from startFIM");
String actionReceived = intent.getAction();
Log.d(CLASS_NAME, "Action received=" + actionReceived);
if (actionReceived.equals(StartFIMActivity.CUSTOM_INTENT))
{
//start service to perform the file integrity check
Log.d(CLASS_NAME, "start service to perform file integrity check");
}
}
Then I created a activity as a separate project/app as a driver for now to kick the broadcast receiver off. Will probably replace with something else later but wanted to get the mechanics/comms down now.
public class StartFIMActivity extends Activity
{
/** Called when the activity is first created. */
public static final String CUSTOM_INTENT = "com.kdms2.StartFIM.intent.action.start";
public String CLASS_NAME = "StartFIMActivity";
#Override
public void onCreate(Bundle savedInstanceState)
{
Log.d(CLASS_NAME, "Entered onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Intent i = new Intent();
i.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); //api 3.1+
i.setAction(CUSTOM_INTENT);
Log.d(CLASS_NAME, "send brodcast to monitor");
this.sendBroadcast(i);
}
}
Now in the trace I do get the intent in FileIntegrityMonitor but a strange message that it's trying to run some method and I don't know why. Error is:
E/AndroidRuntime(979): java.lang.RuntimeException: Unable to instantiate receiver com.kdms2.FileIntegrityMonitor.StartFIMActivity: java.lang.ClassNotFoundException: com.kdms2.FileIntegrityMonitor.StartFIMActivity
why did it add the class name of the activity that broadcast the action to the broadcast receiver?
Is it something in the manifest (receiver)?
<uses-sdk android:minSdkVersion="10" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<receiver android:name=".StartFIMActivity" android:enabled="true">
<intent-filter android:priority="99999999999">
<action android:name="com.kdms2.StartFIM.intent.action.start"/>
</intent-filter>
</receiver>
</application>
<uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
</manifest>
activity manifest
<uses-sdk android:minSdkVersion="10" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:name=".StartFIMActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
</application>
</manifest>
v/r,
Frank
Your receiver's name is FileIntegrityMonitor, but in the manifest you try to register StartFIMActivity as both the <activity> and <receiver> elements. Probably oughta be:
<receiver android:name=".FileIntegrityMonitor" android:enabled="true">
<intent-filter android:priority="99999999999">
<action android:name="com.kdms2.StartFIM.intent.action.start"/>
</intent-filter>
</receiver>
Or something of the like.
HTH