In my Application Class I'm registering a BroadcastReceiver to listen for application Locale changes and it's working fine as I change the locale it works well but I want to close the my Application from where it was created. I have tried to play with context but no success.
public class MyApp extends MultiDexApplication {
....
private BroadcastReceiver myReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String locale = Locale.getDefault().getCountry();
// Toast.makeText(context, "LOCALE CHANGED to " + locale,
// Toast.LENGTH_LONG).show();
/* Destroy Here */
}
};
#Override
public void onCreate() {
super.onCreate();
.........
..........
IntentFilter filter = new IntentFilter(Intent.ACTION_LOCALE_CHANGED);
registerReceiver(myReceiver, filter);
}
}
Related
I'm writing a service that must accept and react on ACTION_BATTERY_LOW broadcast. I'm using next code:
public class MyService extends Service {
...
private final BroadcastReceiver batteryBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.d(LOG_TAG, "batteryBroadcastReceiver.onReceive()->intent="+intent.toString());
if(intent.getAction().equals(Intent.ACTION_BATTERY_LOW))
Log.d(LOG_TAG, "intent.getAction() == Intent.ACTION_BATTERY_LOW!");
}
};
public void onCreate() {
super.onCreate();
final IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_BATTERY_LOW);
registerReceiver(batteryBroadcastReceiver,intentFilter);
}
public void onDestroy() {
super.onDestroy();
unregisterReceiver(batteryBroadcastReceiver);
}
}
When battery charge level goes to low (~15%) Android sends an intent with action ACTION_BATTERY_LOW and then sends it again every 10 seconds which I'm receiving in MyServive. Why does it happen? What can I do or what I'm doing wrong? Tested on real device.
The period to send Intent.ACTION_BATTERY_LOW is up to the OS and the manufacturer. It's informed periodically so you have updated information through time and you can make better decisions.
I don't know what do you want to accomplish but if you are getting the action repeated you can monitor also Intent.ACTION_BATTERY_OKAY and have a flag indicating whether the action for the low battery has been made. That flag changes its value depending on the action the broadcastReceiver receives, e.g.
public class MyService extends Service {
...
private final BroadcastReceiver batteryBroadcastReceiver = new BroadcastReceiver() {
private bool mBatteryLowActionHasBeenMade = false;
#Override
public void onReceive(Context context, Intent intent) {
Log.d(LOG_TAG, "batteryBroadcastReceiver.onReceive()->intent="+intent.toString());
if(intent.getAction().equals(Intent.ACTION_BATTERY_LOW) && !this.mBatteryLowActionHasBeenMade ) {
Log.d(LOG_TAG, "intent.getAction() == Intent.ACTION_BATTERY_LOW!");
this.mBatteryLowActionHasBeenMade = true;
}
if(intent.getAction().equals(Intent.ACTION_BATTERY_OKAY)) {
this.mBatteryLowActionHasBeenMade = false;
}
}
};
public void onCreate() {
super.onCreate();
final IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_BATTERY_LOW);
intentFilter.addAction(Intent.ACTION_BATTERY_OKAY);
registerReceiver(batteryBroadcastReceiver,intentFilter);
}
public void onDestroy() {
super.onDestroy();
unregisterReceiver(batteryBroadcastReceiver);
}
}
If that doesn't fit your requirements try monitoring the battery level with Intent.ACTION_BATTERY_CHANGED
I'm trying to add to my broadcast receiver an if, so I will start a different activity if a call has been answered, to the regular activity I start usually, if the screen has just been turned on.
Now as you can see down here I have the class screenJump starting when the user wakes up phone.
I would like to start a phoneActivity I wrote when the user wakes up phone, but only when a call has been answered.
This is my service now.
public class MyService extends Service {
BroadcastReceiver bd;
public MyService() {
}
class ScreenReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent startupIntent = new Intent(context, ScreenJump.class);
startupIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(startupIntent);
}
public ScreenReceiver()
{
}
}
#Override
public void onCreate()
{
super.onCreate();
IntentFilter filter = new IntentFilter(Intent.ACTION_USER_PRESENT);
bd = new ScreenReceiver();
registerReceiver(bd, filter);
}
}
I want my app to be aware anytime the user changes the locale. So in my Application class, I create a receiver to listen to the system intent ACTION_LOCALE_CHANGED:
public final class MyApp extends Application {
private BroadcastReceiver myReceiver = new BroadcastReceiver() {
#Override public void onReceive(Context context, Intent intent) {
String locale = Locale.getDefault().getCountry();
Toast.makeText(context, "LOCALE CHANGED to " + locale, Toast.LENGTH_LONG).show();
}
};
#Override public void onCreate() {
IntentFilter filter = new IntentFilter(Intent.ACTION_LOCALE_CHANGED);
LocalBroadcastManager.getInstance(this).registerReceiver(myReceiver, filter);
}
}
When I press home and go to the settings app to change my locale, the Toast is not shown. Setting the breakpoint inside onReceive shows it never gets hit.
Why do you want the BroadcastReceiver in Application class. My suggestion is to have a separate class for BroadcastRecevier.
public class LocaleChangedReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction (). compareTo (Intent.ACTION_LOCALE_CHANGED) == 0)
{
Log.v("LocaleChangedRecevier", "received ACTION_LOCALE_CHANGED");
}
}
}
and register your Brodcast receiver in Manifest file.
<receiver
android:name=".LocaleChangedReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.LOCALE_CHANGED" />
</intent-filter>
</receiver>
Intent.ACTION_LOCALE_CHANGED is not a local broadcast, so it won't work when you register it with LocalBroadcastManager. LocalBroadcastManager is used for the broadcast used inside your app.
public class MyApp extends Application {
private BroadcastReceiver myReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String locale = Locale.getDefault().getCountry();
Toast.makeText(context, "LOCALE CHANGED to " + locale,
Toast.LENGTH_LONG).show();
}
};
#Override
public void onCreate() {
super.onCreate();
IntentFilter filter = new IntentFilter(Intent.ACTION_LOCALE_CHANGED);
registerReceiver(myReceiver, filter);
}
}
There are lots of posts out there on using BroadcastReceiver for receiving messages in an Activity that are broadcast from a Service. I've been through dozens and haven't found one that puts it all together. Bottom line is I can't get my Activity to receive broadcasts. Here's what I've done to date:
Service class broadcast:
Context context = this.getApplicationContext();
Intent intentB2 = new Intent(context, StationActivity.AudioReceiver.class);
intentB2.putExtra("Track", mSongTitle);
this.sendBroadcast(intentB2);
Log.i(TAG, "Broadcast2: " + mSongTitle);
Activity class declaration:
public String INCOMING_CALL_ACTION = "com.example.android.musicplayer.action.BROADCAST";
Activity class inline BroadcastReceiver:
public class AudioReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent) {
// Handle receiver
Log.i(TAG, "Inner BroadcastReceiver onReceive()");
String mAction = intent.getAction();
if(mAction.equals(INCOMING_CALL_ACTION)) {
Log.i(TAG, "Inner BroadcastReceiver onReceive() INCOMING_CALL_ACTION");
}
}
};
Android manifest receiver declaration:
<receiver android:name=".StationActivity.AudioReceiver">
<intent-filter>
<action android:name="com.example.android.musicplayer.action.BROADCAST" />
</intent-filter>
</receiver>
What am I missing? Thanks in advance.
In your service:
Intent intentB2 = new Intent("some_action_string_id");
intentB2.putExtra("Track", mSongTitle);
sendBroadcast(intentB2);
Then in your activity:
public class MyActivity extends Activity {
private BroadcastReceiver myReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(getApplicationContext(), "Woot! Broadcast received!", Toast.LENGTH_SHORT);
}
};
#Override
protected void onResume() {
super.onResume();
IntentFilter filter = new IntentFilter("some_action_string_id"); // NOTE this is the same string as in the service
registerReceiver(myReceiver, filter);
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(myReceiver);
}
}
This is the common approach to receive broadcast events in activities. Note that we are registering the receiver when the activity is in the foreground and unregistering it when the activity is no longer visible.
replace your service code with below code and add String INCOMING_CALL_ACTION in your service or directly use it from activity class.
Context context = this.getApplicationContext();
Intent intentB2 = new Intent();
intentB2.setAction(INCOMING_CALL_ACTION);
intentB2.putExtra("Track", mSongTitle);
this.sendBroadcast(intentB2);
Log.i(TAG, "Broadcast2: " + mSongTitle);
When my Android application needs to register a receiver, I've been registering in Activity.onCreate() and unregistering in Activity.onDestroy() (I think I'm supposed to be using onPause() and onResume() instead, but that's not really the point):
public class Foo extends Activity {
private Receiver bar = null;
#Override public void onCreate(Bundle bundle) {
this.registerReceiver(this.bar = new Receiver(), new IntentFilter());
}
#Override public void onDestroy(Bundle bundle) {
this.unregisterReceiver(this.bar);
}
}
Is unregistering the receiver actually necessary, or will the framework handle it when my application exits?
You can handle receiver in onCreate and unregister receiver automatically on exit if using Android Lifecycle-aware component, for example
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getLifecycle().addObserver(new ReceiverLifecycleObserver(this, new IntentFilter(Intent.ACTION_BATTERY_CHANGED), new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "onReceive: intent=" + intent);
}
}));
}
static class ReceiverLifecycleObserver implements LifecycleObserver {
private final Context context;
private final IntentFilter filter;
private final BroadcastReceiver receiver;
public ReceiverLifecycleObserver(Context context, IntentFilter filter, BroadcastReceiver receiver) {
this.context = context;
this.filter = filter;
this.receiver = receiver;
}
#OnLifecycleEvent(Lifecycle.Event.ON_START)
public void onStart(LifecycleOwner owner) {
context.registerReceiver(receiver, filter);
}
#OnLifecycleEvent(Lifecycle.Event.ON_STOP)
public void onStop(LifecycleOwner owner) {
context.unregisterReceiver(receiver);
}
}
If registering a receiver in your Activity.onResume() implementation, you should unregister it in Activity.onPause(). (You won't receive intents when paused, and this will cut down on unnecessary system overhead)