ReceiverCallNotAllowedException in BroadcastReceiver using application context - android

I am getting the following error on Android versions 4.1.2:
Fatal Exception: java.lang.RuntimeException: Unable to start receiver com.example.PluggedInBroadcastReceiver:
android.content.ReceiverCallNotAllowedException: IntentReceiver components are not allowed to register to receive intents
at android.app.ActivityThread.handleReceiver(ActivityThread.java:2287)
at android.app.ActivityThread.access$1600(ActivityThread.java:143)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1317)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4961)
at java.lang.reflect.Method.invokeNative(Method.java)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1004)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:771)
at dalvik.system.NativeStart.main(NativeStart.java)
Caused by android.content.ReceiverCallNotAllowedException: IntentReceiver components are not allowed to register to receive intents
at android.app.ReceiverRestrictedContext.registerReceiver(ContextImpl.java:152)
at android.app.ReceiverRestrictedContext.registerReceiver(ContextImpl.java:146)
at com.example.PluggedInBroadcastReceiver.getBatteryLevel(Unknown Source)
at com.example.PluggedInBroadcastReceiver.onReceive(Unknown Source)
at android.app.ActivityThread.handleReceiver(ActivityThread.java:2280)
at android.app.ActivityThread.access$1600(ActivityThread.java:143)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1317)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4961)
at java.lang.reflect.Method.invokeNative(Method.java)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1004)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:771)
at dalvik.system.NativeStart.main(NativeStart.java)
Here is the code that is causing the error. This receiver is being registered statically (in the AndroidManifest.xml) rather than dynamically:
public class PluggedInBroadcastReceiver extends WakefulBroadcastReceiver {
public static final String LOG_TAG = PluggedInBroadcastReceiver.class.getSimpleName();
private IntentFilter iFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
#Override
public void onReceive(Context context, Intent intent) {
if (intent != null) {
String action = intent.getAction();
if (action != null && action.equals(Intent.ACTION_POWER_CONNECTED)) {
try {
Intent batteryStatusIntent = context.getApplicationContext().registerReceiver(null, iFilter);
double battPercentage = BatteryUtils.getBatteryLevel(batteryStatusIntent);
//Do something with the battery percentage value...
} catch (Exception e) {
Log.e(LOG_TAG, "Battery status intent was null");
}
}
}
}
}
I ran into this error in the past and found that my problems were being caused by the fact that the context that is passed to a Broadcast Receiver does not have the ability have registerReceiver() called on it.
I found some resources that suggest that you can convert the context passed to the Broadcast Receiver to an application context and then call registerReceiver() on the application context. This works for Android versions 4.2 and up, but fails on 4.1.2 (and possibly lower, but haven't tested explicitly). It seems like converting to the application context should allow registerReceiver() to be called, but that doesn't seem to work for all versions of Android.
Does anyone have an explanation for this behavior?
EDIT:
The plot thickens... I've now learned that this crash has occurred on android versions 4.1.1, 4.1.2, 4.3.0 and 5.1.1 over 93% of the crashes occurred on 4.1.2. I'm not sure we're going to find a solution for this, but my fix going forward is to never call registerReceiver() from a BroadcastReceiver. The behavior seems to be undefined and unpredictable even when using the application context which is apparently supposed to allow this.

Related

NullPointerException while retrieving Extras from Intent

I'm working on building a Location_Service for my Android App.I have a Service say , T_Service that starts on phone boot and checks for few conditions in its onStartCommand() to start my Location_Service. I want to send these conditions as an intent from a broadcast receiver associated to with the T_Service.
I do the following:
In the Broadcast Receiver
public class T_BroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent(context,T_Service.class);
i.putExtra("PARENT_ACTIVITY_NAME","com.example.helloworld");
context.startService(i);
}
}
In the T_Service class:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("APP","The intent has parent activity : "+intent.getExtras().getString("PARENT_ACTIVITY_NAME"));
}
I get a NullPointerException when my code reaches the above point that tries to print the value associated with the key that was set in the Intent.
Kindly advise me on how to go about the case of adding extras to an intent of a Service like T_Service that starts on phone boot.
The Stack trace for the Exception :
FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start service org.abc.def.services.TService#41593b58 with null: java.lang.NullPointerException
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2387)
at android.app.ActivityThread.access$1900(ActivityThread.java:127)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1221)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4511)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:980)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:747)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at org.abc.def.services.TrackerService.onStartCommand(TrackerService.java:140)
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2370)
            at android.app.ActivityThread.access$1900(ActivityThread.java:127)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1221)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:4511)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:980)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:747)
            at dalvik.system.NativeStart.main(Native Method)
From the documentation (onStartCommand):
Parameter "intent": The Intent supplied to startService(Intent), as given.
This may be null if the service is being restarted after its process has gone
away, and it had previously returned anything except
START_STICKY_COMPATIBILITY.
If you're running this on phone boot is likely that you will get null on the intent because the process that started it has gone away.
To receive the the same intent you would need to return START_REDELIVER_INTENT in the onStartCommand method, as follows:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("APP","The intent has parent activity : "+intent.getExtras().getString("PARENT_ACTIVITY_NAME"));
return Service.START_REDELIVER_INTENT;
}
Returning START_REDELIVER_INTENT will make the intent parameter to be passed again to the onStartCommand method whenever the service get restarted (e.g on phone boot).
For more details check the documentation.
START_REDELIVER_INTENT
Constant to return from onStartCommand(Intent, int, int): if this
service's process is killed while it is started (after returning from
onStartCommand(Intent, int, int)), then it will be scheduled for a
restart and the last delivered Intent re-delivered to it again via
onStartCommand(Intent, int, int)
Please read the javadoc for onStartService. It says that the intent parameter can be null, so you should always check it for null before calling methods on it.
My experience is that even when you think that an IntentSevice will never receive a null there, it is actually still possible in extremely rare circumstances. So you should still check it for null even if you don't think it will happen.
replace this
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("APP","The intent has parent activity : "+intent.getExtras().getString("PARENT_ACTIVITY_NAME"));
}
with this
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
Bundle b = getIntent().getExtras();
if (b != null){
Log.d("APP","The intent has parent activity :"+b.getString("PARENT_ACTIVITY_NAME")); }
Per the Intent API documentation, you must include a package name in the extra's name.
public Intent putExtra (String name, String value)
Added in API level 1
Add extended data to the intent. The name must include a package prefix, for example the app com.android.contacts would use names like "com.android.contacts.ShowAll".
Parameters
name The name of the extra data, with package prefix.
value The String data value.
Returns
Returns the same Intent object, for chaining multiple calls into a single statement.
See Also
putExtras(Intent)
removeExtra(String)
getStringExtra(String)
Please check your intent and extra string before accessing. May be it is null
if(intent.getExtras()!=null && intent.hasExtra("PARENT_ACTIVITY_NAME")){
Log.d("APP","The intent has parent activity : "+intent.getExtras().getString("PARENT_ACTIVITY_NAME"));
}
To pass an intent, please refer older thread.
Pass data from Activity to Service using an Intent

Service has leaked ServiceConnection that was originally bound here

I am using a BraodCastReceiver that starts an IntentService. Everythings look working good, but I get this error which I don't know its source:
android.app.ServiceConnectionLeaked: Service com.merchantech.app.smartdiscount.MyIntentService has leaked ServiceConnection com.clover.sdk.v3.order.OrderConnector#535008f4 that was originally bound here
at android.app.LoadedApk$ServiceDispatcher.<init>(LoadedApk.java:969)
at android.app.LoadedApk.getServiceDispatcher(LoadedApk.java:863)
at android.app.ContextImpl.bindService(ContextImpl.java:1426)
at android.app.ContextImpl.bindService(ContextImpl.java:1415)
at android.content.ContextWrapper.bindService(ContextWrapper.java:473)
at com.clover.sdk.v1.ServiceConnector.connect(ServiceConnector.java:119)
at com.clover.sdk.v1.ServiceConnector.waitForConnection(ServiceConnector.java:148)
at com.clover.sdk.v1.ServiceConnector.execute(ServiceConnector.java:209)
at com.clover.sdk.v3.order.OrderConnector.getOrder(OrderConnector.java:153)
at com.merchantech.app.smartdiscount.MyIntentService.onHandleIntent(MyIntentService.java:41)
at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.os.HandlerThread.run(HandlerThread.java:60)
Here's my BrodcastReceiver class:
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals("com.test.intent.action.LINE_ITEM_ADDED")) {
Intent i = new Intent(context, MyIntentService.class);
context.startService(i);
}
}
}
And here's my IntentService class:
public class MyIntentService extends IntentService {
public MyIntentService() {
super("MyIntentService");
}
#Override
protected void onHandleIntent(Intent intent) {
orderItem.addLineItem(orderId, lineItemId, var);
}
}
The error message basically means that some component created a binding to a Service and did not unbind from the service before the component was destroyed.
You will need to provide more information about your app's structure to get a better answer to your question. I'll make some guesses, and maybe give you some ideas about things to explore.
I'm guessing that you are using a library from Clover and maybe also Merchantech. Or maybe the Clover library uses a Merchantech library. I'm also guessing that orderItem is an instance of a class defined by Clover, not you.
The Android runtime destroys an IntentService after onHandleIntent() completes and there are no more Intent requests queued. You can confirm this by adding the onDestroy() method to your MyIntentService with a Log command to show when it is called. That means that in the code you posted for onHandleIntent(), your IntentService will be destroyed soon after the call to addLineItem() completes.
The stack trace suggests that the processing triggered by the call to orderItem.addLineItem() causes a binding to another service. Somewhere, that binding is not being managed properly--maybe not unbound when it should be. Is there something the Clover subsystem expects you do to "close" it or "release" resources when your component (Service or Activity) is being destroyed?
Solved:
The problem is due to the Clover SDK. They have not unbind a service that was bounded somewhere in the com.clover.sdk.v3.order.OrderConnector Class. So the problem is not relevant to the code snippet above.

Parse.com runtime crash - android

i am getting a lot of reports from users about my app crashing. The constant error appears to be associated with my parse.com initialisation, however, i have set it up as outlined in the parse tutorial.
here is the Stack Trace:
java.lang.RuntimeException: Unable to start receiver com.parse.ParseBroadcastReceiver: java.lang.RuntimeException: applicationContext is null. You must call Parse.initialize(context, applicationId, clientKey) before using the Parse library.
at android.app.ActivityThread.handleReceiver(ActivityThread.java:2580)
at android.app.ActivityThread.access$1700(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1397)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:5292)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:824)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:640)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.RuntimeException: applicationContext is null. You must call Parse.initialize(context, applicationId, clientKey) before using the Parse library.
at com.parse.Parse.checkContext(Parse.java:606)
at com.parse.Parse.getApplicationContext(Parse.java:214)
at com.parse.ManifestInfo.getContext(ManifestInfo.java:322)
at com.parse.ManifestInfo.getPackageManager(ManifestInfo.java:330)
at com.parse.ManifestInfo.getPackageInfo(ManifestInfo.java:356)
at com.parse.ManifestInfo.deviceSupportsGcm(ManifestInfo.java:441)
at com.parse.ManifestInfo.getPushType(ManifestInfo.java:210)
at com.parse.PushService.startServiceIfRequired(PushService.java:168)
at com.parse.ParseBroadcastReceiver.onReceive(ParseBroadcastReceiver.java:19)
at android.app.ActivityThread.handleReceiver(ActivityThread.java:2573)
... 10 more
and here is my initialisation code:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home_screen);
Parse.initialize(this, "hGG5RdgNVdI7eCeZynV32lWYXywQRHkpp5zLdY7Q", "TwmNbpBYEt4u3euE3lzNIgwyroSl8RPGF2dJFsPv");
ParseInstallation.getCurrentInstallation().saveInBackground();
Can anybody see what is causing this error, and how to fix it?
below is my receiver code:
public static class Receiver extends ParsePushBroadcastReceiver {
private String notificationText;
private Boolean notificationreceived = false;
public Receiver(){
}
private static final String TAG = "MyNotificationsReceiver";
#Override
public void onPushOpen(Context context, Intent intent) {
Log.e("Push", "Clicked");
Intent i = new Intent(context, HomeScreen.class);
notificationreceived = true;
i.putExtra("alert",notificationText);
i.putExtra("alertreceived", notificationreceived);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
Scb998.scb988b=true;
try {
JSONObject json = new JSONObject(intent.getExtras().getString("com.parse.Data"));
Scb998.msg = json.getString("alert");
} catch (JSONException e) {
Log.d(TAG, "JSONException: " + e.getMessage());
}
}
}
Move you Parse initialization into your App class (extended from Application)
public class App extends Application {
#Override
public void onCreate() {
super.onCreate();
Parse.initialize(this, "hGG5RdgNVdI7eCeZynV32lWYXywQRHkpp5zLdY7Q", "TwmNbpBYEt4u3euE3lzNIgwyroSl8RPGF2dJFsPv");
ParseInstallation.getCurrentInstallation().saveInBackground();
}
}
And of course refer to it your AndroidManifest.xml
<application
android:name=".app.App"
....
</application>
Reason of crash is next. When your app is at background, it can be killed by system. From Google guide
A process holding an activity that's not currently visible to the user (the activity's onStop() method has been called). These processes have no direct impact on the user experience, and the system can kill them at any time to reclaim memory for a foreground, visible, or service process. Usually there are many background processes running, so they are kept in an LRU (least recently used) list to ensure that the process with the activity that was most recently seen by the user is the last to be killed. If an activity implements its lifecycle methods correctly, and saves its current state, killing its process will not have a visible effect on the user experience, because when the user navigates back to the activity, the activity restores all of its visible state. See the Activities document for information about saving and restoring state.
When you app receives push notification, then parse will not be initialized, because you initialize it at activity onCreate method, which won't be called.

Service onStartCommand throwing NullPointerException

I have an app that runs two separate services. One of them runs smoothly, and the other works without issue a majority of the time, but is throwing a NullPointerException within onStartCommand() intermittently on a significant number of newer devices (Samsung, HTC, LG) on varying Android versions between 4.1 and 4.4.2. I am unable to reproduce the error on any of my own devices, including two of the exact models which have experienced this issue. The stacktrace is as follows, indicating the problem is on line 145:
java.lang.RuntimeException: Unable to start service com.mycom.myapp.MyLocService#425ab718
with Intent { cmp=com.mycom.myapp/.MyLocService }: java.lang.NullPointerException
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2695)
at android.app.ActivityThread.access$1900(ActivityThread.java:146)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1337)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5168)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:564)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at com.mycom.myapp.MyLocService.onStartCommand(MyLocService.java:145)
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2678)
... 10 more
I am using a portion of the code linked within the answer provided here by blackcj to run a location service in the background of my app; here is the relevant snippet from MyLocService.java, with the offending line marked:
#Override
public void onCreate() {
super.onCreate();
mInProgress = false;
mLocationRequest = LocationRequest.create();
servicesAvailable = servicesConnected();
mLocationClient = new LocationClient(this, this, this);
locIntent = new Intent(MY_LOCATION);
}
public int onStartCommand (Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId); // <----- NPE AT LINE 145
setUpLocationClientIfNeeded();
if(!mLocationClient.isConnected() || !mLocationClient.isConnecting()) {
mLocationClient.connect();
}
return START_STICKY;
}
private void setUpLocationClientIfNeeded() {
if(mLocationClient == null) {
mLocationClient = new LocationClient(this, this, this);
}
}
The service is started by the following code within onCreate() in MyActivity.java:
Intent MyLocService = new Intent(this, MyLocService.class);
startService(MyLocService);
The service is declared within the <application> element in AndroidManifest.xml as follows:
<service
android:name=".MyLocService"
android:singleUser="true"
android:stopWithTask="false" >
<intent-filter>
<action android:name="com.mycom.myapp.MyLocService" />
</intent-filter>
</service>
I have been unable to determine what is causing this exception, as it does not happen consistently and I cannot reproduce it myself. What could be causing this intermittent problem?
It appears that returning START_REDELIVER_INTENT instead of START_STICKY has resolved this problem. Instead of continuing to figure out how to check for a null intent, I found a method that supposedly will not cause it in the first place.
I will update with any further conclusions I discover regarding this method as it becomes more widely implemented by my users.

Unable to start service [service name] with null

i recently coded a Android Widget and tested it on Emulator as well as my Galaxy S , it worked fine on both, after i posted the same to android market now i am getting some error reports.
i am stating a service in the onUpdate of Widget Class like this:
if (appWidgetIds != null) {
final int N = appWidgetIds.length;
// Perform this loop procedure for each App Widget that belongs to
// this
// provider
for (int i = 0; i < N; i++) {
// Start Service for each instance
int appWidgetId = appWidgetIds[i];
Intent active = new Intent(context, DialerService.class);
active.setAction("Start");
active.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
appWidgetId);
context.startService(active);
}
}
the error which some people are getting is:
java.lang.RuntimeException: Unable to start service dialer.impact.DialerService#45f926f0 with null: java.lang.NullPointerException
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3282)
at android.app.ActivityThread.access$3600(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2211)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:144)
at android.app.ActivityThread.main(ActivityThread.java:4937)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
**at dialer.impact.DialerService.onStart(DialerService.java:18)**
at android.app.Service.onStartCommand(Service.java:420)
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3267)
... 10 more
error states a NullPointerException on line 18 of the ServiceClass which is this:
#Override
public void onStart(Intent intent, int startId) {
//Line 18th
String command = intent.getAction();
int appWidgetId = intent.getExtras().getInt(
AppWidgetManager.EXTRA_APPWIDGET_ID);
RemoteViews remoteView = new RemoteViews(getApplicationContext()
.getPackageName(), R.layout.main);
AppWidgetManager appWidgetManager = AppWidgetManager
.getInstance(getApplicationContext());
}
Line 18 is the String command = intent.getAction();
what could be the reason for intent being null
please help
According to the documentation for onStart() (actually onStartCommand() but the parameters are the same):
intent The Intent supplied to startService(Intent), as given. This may be null if the service is being
restarted after its process has gone
away, and it had previously returned
anything except
START_STICKY_COMPATIBILITY.
Hi just to add on to this, so the workaround is just to add a if(intent!=null) before the getAction()? If I do this, will the service start up properly later on it's own? Meaning the OS actually helps me start the service properly in the case of a null intent. I'm afraid of ending up in a situation where the service doesn't get started at all.

Categories

Resources