Broadcast Receiver null pointer Android - android

I keep getting the following error:
> java.lang.NullPointerException: Attempt to invoke virtual method 'void android.content.BroadcastReceiver.onReceive(android.content.Context, android.content.Intent)' on a null object reference
When I try to receive a broadcast from my service class.
Service:
#Override
public void onDestroy(){
super.onDestroy();
Intent intent = new Intent("UpdateLocation");
intent.putExtra("Location",journ);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
That is the code to send the broadcast sending a custom object(Journ) to my main activity.
Main:
#Override
protected void onCreate(Bundle savedInstanceState)
LocalBroadcastManager.getInstance(this).registerReceiver(
mReceiver, new IntentFilter("UpdateLocation"));
//Listen for service to send location data
mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
temp= intent.getExtras().getParcelable("Location");
}
};
}
#Override
public void onPause() {
if (!tracking) {
finish();
}
//Run service in background to keep track of location
startService(new Intent(this, locationService.class));
super.onPause();
}
#Override
public void onResume() {
if (!tracking) {
return;
}
if (mGoogleApiClient != null) {
//Reconnect to google maps
mGoogleApiClient.reconnect();
}
stopService(new Intent(this, locationService.class));
super.onResume();
}
I am not sure how to go about doing this, I am trying to pass the object from my service class which runs when my app is in the background and when it resumes the service should stop and sends the data it gathered to my main activity.
This, however, doesn't work, any ideas?
In case people were wondering my on create method does contain more code, but I didn't think it necessary to include.

In onCreate mReciever is a null object (if you didn't assign it earlier), so you should assign it before registering a receiver.
Change this part:
if (mReceiver == null) {
mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
temp= intent.getExtras().getParcelable("Location");
}
};
}
//Listen for service to send location data
LocalBroadcastManager.getInstance(this)
.registerReceiver(mReceiver, new IntentFilter("UpdateLocation"));

Related

Wrong when register two receiver in an activity Android

I have an activity. It will be receive two variable from an service. In the service, I will send two variable to the activity by
// Send first variable
sendBroadcast(new Intent("first_one"));
// Send second variable
sendBroadcast(new Intent("second_one"));
Now, In the activity, I used bellow code to receive the data. There are
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
registerReceiver(firstRec, new IntentFilter("first_one"));
registerReceiver(secondRec, new IntentFilter("second_one"));
}
#Override
protected void onPause() {
super.onPause();
if (firstRec != null) {
unregisterReceiver(firstRec);
firstRec = null;
}
if (secondRec != null) {
unregisterReceiver(secondRec);
secondRec = null;
}
}
private BroadcastReceiver firstRec = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("TAG","OK first");
}
};
private BroadcastReceiver secondRec = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("TAG","OK second");
}
};
However, I cannot print the log "OK second" when I called sendBroadcast(new Intent("second_one")); in the service. What is happen? How can I fix it? Thank you
UPDATE: my activity is an accept calling activity get from #notz
How can incoming calls be answered programmatically in Android 5.0 (Lollipop)?. Then I create an service as following
public class myService extends Service{
#Override
public void onCreate() {
super.onCreate();
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Intent answerCalintent = new Intent(getApplicationContext(), AcceptCallActivity.class);
answerCalintent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
answerCalintent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(answerCalintent);
//Send the second command after 10 second and make the calling in background
new CountDownTimer(10000, 100) {
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
sendBroadcast(new Intent("second_one"));
}
}.start();
return START_STICKY;
}
}
You should unregister your reсeiver in a method opposite to that in which you register it:
If you registered receiver in onCreate() - then you should unregister it in onDestroy().
But as i know, for most cases, the best practice is to register receiver in onResume() and unregister it in onPause().

OnReceive() method auto triggered

I have created the one receiver inside an Activity for when internet is connected auto calling web service.
Code like
//Create receiver for while network will come auto call webservice
private BroadcastReceiver mConnReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
boolean noConnectivity = intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
if (!noConnectivity) {
bar.setVisibility(View.VISIBLE);
callAuthorizeWebservice();
} else {
bar.setVisibility(View.INVISIBLE);
Toast.makeText(SplashScreenActivity.this, "Check Your Internet connection", Toast.LENGTH_LONG).show();
}
}
};
#Override
protected void onStop() {
super.onStop();
unregisterReceiver(mConnReceiver);
}
#Override
protected void onStart() {
super.onStart();
this.registerReceiver(this.mConnReceiver,
new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
}
When I open that Activity the onReceive() is method called everytime.
How to avoid calling it the first time (when opening that Activity)?
The broadcast is sent when you register for the first time(cf sticky broadcast), a solution is to use isInitialStickyBroadcast in the onReceive callback of your BroadcastReceiver to know if you are actually proceeding a sticky broadcast and act accordingly (BroadcastReceiver : isInitialStickyBroadcast)

BroadcastReveiver is not registering

I cannot figure out why I keep getting an error saying:
11-10 17:14:04.904: E/AndroidRuntime(8151): Caused by: java.lang.IllegalArgumentException: Receiver not registered: com.refect.served.fragment.activities.DrinkReleaseStation$PushBroadcastReceiver#541e0ce4
I clearly register my receiver on my onCreate() method. But when I try unregistering it, it crashes and gives me that error. Here's the rest of my code:
public class DrinkReleaseStation extends FragmentActivity {
private PushBroadcastReceiver receiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.admin_new_bar);
String barId = getIntent().getExtras().getString("BarId");
orders = new ArrayList<ParseObjectModel>();
saveInstallation(barId);
ordersListView = (ListView) findViewById(R.id.lv_bars);
adapter = new DrinkManagerAdapter(this, orders);
ordersListView.setAdapter(adapter);
fab = (Button) findViewById(R.id.btn_add_new_bar);
//fab.setDrawable(getResources().getDrawable(R.drawable.ic_navigation_accept));
registerReceiver();
} //end onCreate
#Override
public void onResume() {
super.onResume();
registerReceiver();
}
#Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(receiver);
unsubscribeInstallation();
}
#Override
public void onPause() {
super.onPause();
unregisterReceiver(receiver);
unsubscribeInstallation();
}
private void registerReceiver() {
receiver = new PushBroadcastReceiver();
IntentFilter filter = new IntentFilter();
// filter.addAction(Intent.ACTION_BOOT_COMPLETED);
// filter.addAction(Intent.ACTION_USER_PRESENT);
filter.addAction("com.google.android.c2dm.intent.RECEIVE");
registerReceiver(receiver, filter);
Log.d("ReleaseStation", "Receiver Registered");
}
/**
* BroadcastReceiver for receiving
* push messages from Parse
* #author Austin
*
*/
public class PushBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals("com.google.android.c2dm.intent.RECEIVE")) {
Log.d("Order", intent.getAction());
Toast.makeText(context, "New Order!.",
Toast.LENGTH_SHORT).show();
}
}
}
}
You are calling unregisterReceiver() in both onPause() and onDestroy(). It is guaranteed that by the time onDestroy() is called, onPause() will have been called. Hence, get rid of the onDestroy() call to unregisterReceiver(), and you should be in better shape.
Generally speaking, stick to the pairs:
if you initialize it in onCreate(), clean it up in onDestroy()
if you initialize it in onStart(), clean it up in onStop()
if you initialize it in onResume(), clean it up in onPause()

Dynamically register/unregister a broadcast receiver in android

I want to dynamically register and unregister my receiver class with the broadcast:
"android.net.wifi.STATE_CHANGE"
This works very well if I do this in the manifest. But this makes it static. I want to do it dynamically in the activity class. What is its correspondent command in the activity class?
This is what my code is...
and I am getting a problem because of registering and unregistering(multiple times) my receiver(which is starting a service).
public class startScreen extends Activity {
/** Called when the activity is first created. */
private BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Intent serviceIntent = new Intent();
serviceIntent.setAction("com.example.MyService");
context.startService(serviceIntent);
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.initial);
final IntentFilter filter = new IntentFilter();
filter.addAction("android.net.wifi.STATE_CHANGE");
Button button = (Button) findViewById(R.id.button1);
final ToggleButton toggleButton = (ToggleButton) findViewById(R.id.toggleButton1);
try {
...some code...
if (bool == true) {
toggleButton.setChecked(true);
this.registerReceiver(receiver, filter);
} else
toggleButton.setChecked(false);
} catch (Exception e) {
Log.e("Error", "Database", e);
} finally {
...
}
toggleButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if ((toggleButton.isChecked())) {
getBaseContext().registerReceiver(receiver, filter);
} else {
if (receiver != null) {
getBaseContext().unregisterReceiver(receiver);
receiver = null;
}
}
}
});
}
#Override
protected void onResume() {
super.onResume();
if (bool == true) {
if (receiver == null)
this.registerReceiver(receiver, filter);
}
}
#Override
protected void onPause() {
super.onPause();
if (receiver != null) {
this.unregisterReceiver(receiver);
receiver = null;
}
}
}
The LocalBroadcastManager class is used to register for and send broadcasts of Intents to local objects within your process. This is faster and more secure as your events don't leave your application.
The following example shows an activity which registers for a customer event called my-event.
#Override
public void onResume() {
super.onResume();
// Register mMessageReceiver to receive messages.
LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
new IntentFilter("my-event"));
}
// handler for received Intents for the "my-event" event
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// Extract data included in the Intent
String message = intent.getStringExtra("message");
Log.d("receiver", "Got message: " + message);
}
};
#Override
protected void onPause() {
// Unregister since the activity is not visible
LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
super.onPause();
}
// This method is assigned to button in the layout
// via the onClick property
public void onClick(View view) {
sendMessage();
}
// Send an Intent with an action named "my-event".
private void sendMessage() {
Intent intent = new Intent("my-event");
// add data
intent.putExtra("message", "data");
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
use the below methods to register/unregister your receiver:
registerReceiver(BroadcastReceiver receiver, new IntentFilter("android.net.wifi.STATE_CHANGE"));
unregisterReceiver(BroadcastReceiver receiver);
For reference have a look at this
Don't add dynamic broadcast receiver in onReceive on broadcast file. Add it on first activity or main activity of your application. If you needed it only when your application is open. But if you need it always received response just added it on manifest file
Register dynamic broadcast receiver on main activity
MyReceiver reciver;
#Override
protected void onResume() {
super.onResume();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("android.net.wifi.WIFI_STATE_CHANGED");
intentFilter.addAction("android.net.wifi.STATE_CHANGE");
reciver = new MyReceiver();
registerReceiver(reciver, intentFilter);
}
Unregister that broadcast receiver on activity stop or closed
#Override
protected void onStop() {
super.onStop();
unregisterReceiver(reciver);
}
Perhaps I'm a bit too late, but the problem lies on the fact that you are setting the receiver = null in your onPause method, and then never setting it again. You are also trying to register it in your onResume method but only if it is null, which makes no sense too.
You should change the logic where you set/test the null value of the receiver, to instead just use a boolean variable to keep track of the receiver status (if it's registered or not).
public void registerBroadcastReceiver(View view) {
this.registerReceiver(broadCastReceiver, new IntentFilter(
"android.intent.action.TIME_TICK"));
}
public void unregisterBroadcastReceiver(View view) {
this.unregisterReceiver(broadCastReceiver);
}

Correct pattern for registering a receiver?

I need to register a receiver. I have been using the following pattern:
#Override
protected void onResume() {
super.onResume();
registerReceiver(myReceiver, new IntentFilter(...));
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(myReceiver);
}
private BroadcastReceiver myReceiver = new BroadcastReceiver() {
...
});
I'm getting crash reports from marketplace about my unregisterReceiver() call:
java.lang.IllegalArgumentException: Receiver not registered
I thought this could not be possible, but it seems this is the correct pattern instead:
private Intent mIntent;
#Override
protected void onResume() {
super.onResume();
if (mIntent == null) {
mIntent = registerReceiver(myReceiver, new IntentFilter(...));
}
}
#Override
protected void onPause() {
super.onPause();
if (mIntent != null) {
unregisterReceiver(myReceiver);
mIntent = null;
}
}
private BroadcastReceiver myReceiver = new BroadcastReceiver() {
...
});
Is the above the correct pattern? I guess it's possible for registration to fail, and we have to keep the result from registerReceiver(), and check it in onPause() before making the call to unregister()?
Thanks
I am basing the change off of this question:
Problem with BroadcastReceiver (Receiver not registered error)
I've only ever seen the first pattern above, never one where you check the intent response - any clarification would be great.
Is the above the correct pattern?
No, this isn't necessarily going to work. From the docs for registerReceiver(...)...
Returns The first sticky intent found that matches filter, or null if there are none.
In other words even if the call to register the receiver is successful, it may still return null if there are no sticky broadcasts for that intent filter.
My approach would be to simply use a boolean and a try/catch block...
private boolean isReceiverRegistered;
#Override
protected void onResume() {
super.onResume();
if (!isReceiverRegistered) {
registerReceiver(myReceiver, new IntentFilter(...));
isReceiverRegistered = true;
}
}
#Override
protected void onPause() {
super.onPause();
if (isReceiverRegistered) {
try {
unregisterReceiver(myReceiver);
} catch (IllegalArgumentException e) {
// Do nothing
}
isReceiverRegistered = false;
}
}

Categories

Resources