I have declared the launch mode of my activity to be singleTask. If I
launch my application, press the home button, go to an email client
(gmail in this case) & preview an attachment using my application, I
am experiencing a security exception on Android versions 2.3 & later,
which says that I do not have the permissions to access gmail
attachments. The exception does not occur on prior versions & if I do
not use singleTask as the launchMode.
The exception occurs on this line-
mContext.getContentResolver().openInputStream(intent.getData());
where mContext is the activity context.
Is this a known issue?
Any help will be really appreciated.
Thanks,
Akshay
I had posted this on Android-developers and got this response from Dianne Hackborn-
"Sorry, this is probably a bug in 2.3 with trying to grant a URI permission to an activity instance that is already running. I'll look in to this. In the mean-time, the only solution may be to not use singleTask for the activity being launched to a preview an attachment. This is actually the preferred thing to do, since your preview activity should be running as its own instance as part of the gmail task."
The problem might happen because the called intent's activity in the 2.3 implementation does not fit the launchMode:"standard" or launchMode:"singleTop" requirement stated in the android:launchMode description.
But it would be also useful to take a look at this issue: Behaviour of launchMode=“singleTask” not as described. It is scary, hopefully your problem isn't rooted there, and can be solved within the current versions.
Related
I get Crash Analytics from Google for my Android app and I have been seeing this popup once in a while:
java.lang.NoClassDefFoundError
with regards to trying to open an Intent.
The scenario is, user clicks on button, they my code in the app is:
Intent intent = new Intent(nameOfCurrentActivity.this, nameOfNewActivity.class);
startActivity(intent);
Pretty straightforward stuff. It works fine on nearly all devices, including all the ones I own and have tested on. This new class being started isn't unique in that it requires any weird hardware (IE, not a camera activity), but it does access the internet via an Http request.
I have already researched the following links without gaining a hint towards a solution:
Why am I getting a NoClassDefFoundError in Java?
How to solve java.lang.NoClassDefFoundError?
My question is, how is it possible that this exception is being thrown on some devices (IE, a Samsung tablet), but not other devices? Shouldn't a new intent work on all devices if it works on one?
Thanks!
A lot of times this can be caused by classes running code that is dependent upon it being a certain API level, IE Marshmallow, but the device using it is on a previous API and the check for permissions is either ignored or not included; Like when you click disable inspection.
An example would be, say you are running something like a View.OnScrollChangeListener for a recyclerview. If you are coding and set it:
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {
myRecyclerview.setOnScrollChangeListener(this);
}
But don't include the build if check, it will throw the error. Another example would be if you are using the class itself as the context (this) for setting the scroll listener. If you use the class itself as the context for extending the Scroll listener but are on a device Pre-API 21, it will throw the error when the class loads. The error it throws is, as you probably guessed, NoClassDefError.
This happens because the Class mentioned in the 'future' API doesn't exist yet in the old phone and so it cannot find the class defined.
Check your code to see if anything in the class is requiring a certain API level to function and if it is, check to confirm you included the if checks for build version. Many times before I have disabled inspection because the red lines were bugging me and forgot to go back and add the checks.
I just wanted to add my own experience today. Apparently Supplier<T> exists in Java 8, however implementation of it and running it on Marshmallow generates NoClassDefFoundError. I was able to solve the problem by declaring custom MySupplier<T>. I tried to add as a comment but failed. Thanks for the explanation given by user7293284 above.
I have a problem that firebase dynamic link is relaunched when the android app is restarted. The following sequence produces the problem:
click the deep link URL
the app is opened at the view pointed by the deep link (as expected)
close the app (completely)
open the app from the icon
the app is opened at the view pointed by the deep link (even though it should not)
after that it works fine
I am using the latest (9.0.2) libraries. The code is pretty much as in the examples (e.g. here: https://firebase.google.com/docs/dynamic-links/android#add-an-intent-filter-for-deep-links), autoLaunchDeepLink being false.
I noticed that there has been a bug causing this, but it should be fixed in the current release:
https://github.com/googlesamples/google-services/issues/141
I tried a workaround by calling AppInvite.AppInviteApi.getInvitation twice, as instructed in github error report. No success.
In onCreate I am checking that savedInstance is null and checking deep link only if it is.
I am checking deep link also in onNewIntent in order to handle it while the app is running, however this is not called when the problem occurs.
In my manifest, the intent-filter with the specific protocol and host are included only in the main activity. The protocol is used also in other filters in other activities, but I tried also using different protocol in those with no effect. Only the main activity uses AppInvite.AppInviteApi.getInvitation to get the intent. The problem occurs even if I remove other intent filters from all activities.
Any ideas what could be wrong or what I should still check?
You need to call getInvitation() both in your launcher activity, and in the activity which you declared to handle the dynamic link.
But in the activity which handles the dynamic link, you need to pass null instead of passing the activity as second parameter of getInvitation(),
like this AppInvite.AppInviteApi.getInvitation(mGoogleApiClient, null, autoLaunchDeepLink).
Anybody have any idea why
Intent pairIntent = new Intent(android.provider.Settings.ACTION_BLUETOOTH_SETTINGS);
startActivityForResult(pairIntent, 0);
Crashes on all Samsung devices, but works fine on emulator, HTC, Sony, LG etc.
EDITED -----------------------------------
Turns out Samsung also requires BLUETOOTH_ADMIN in the manifest
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
If you have an app in production, you need to have something that will allow you to get crash logs. That could be the default stuff that you get from shipping through the Play Store, or an open source solution like ACRA, or any number of service providers.
With regards to your crash, there is no guarantee that this activity is available. Quoting the documentation:
In some cases, a matching Activity may not exist, so ensure you safeguard against this.
The "safeguard" could be wrapping your startActivity() call in an exception handler, watching for ActivityNotFoundException.
Also, please note that you use startActivity(), not startActivityForResult(), with this Intent action. Again, quoting the documentation:
Output: Nothing.
This means that there is no result, and using startActivityForResult() is a waste of time.
Several of my Android applications show the following type message in the logcat output:
I/UsageStats( 59): Unexpected resume of com.totsp.test while already resumed in com.totsp.test
In this case I created the default Hello World app by letting the ADT tool generate it, and it still gets this message. I am not doing anything special in onCreate and don't even have any other methods defined.
I realize this is an INFO level message, and it doesn't appear to hurt anything, but I was curious what was going on so I made a test application that keeps track of the onResume invocations. It is indeed re-resuming when this occurs. I'm wondering why this this occurs? While I haven't noticed a problem (other than these annoying log messages), it seems like it could be using more resources than necessary to do all this stuff an extra time.
I have searched and read a similar question here on SO, and the answer there seems dubious to me: Unexpected resume of "package name" while already resumed in ''package name" Error in Android. Specifically, no, you don't want to use android:configChanges="orientation" because that is just subverting the orientation tear down/resume, rather than fixing it. Even the documentation notes "this attribute should be avoided and used only as a last-resort" (http://developer.android.com/intl/de/guide/topics/manifest/activity-element.html#config).
Also I have seen thread in the Android dev group where Mr. Murphy says the "unexpected resume" is "benign": http://groups.google.com/group/android-developers/browse_thread/thread/567410dbfcc163c2.
I'll dig into the source when I get a chance, but I figured I would first just ask the all-knowing hivemind and see if someone already knows: why does this occur, and is it truly benign?
Don't worry about it, it is just a message from some internal state tracking that is not really a problem (hence it being INFO level). I'll make sure it is removed in the next platform version.
My whole Activity flow changes every time this error comes,
but i have handled this by adding android:configChanges="orientation" in the activity in Manifest File.
<activity android:name=".YourActivity" android:label="#string/app_name" android:configChanges="orientation" android:screenOrientation="nosensor">
Hope this helps you
I am interested in activating another application's activity. I know from reading the Android SDK that it's probably better to do this with an implicit intent. However, this activity doesn't reside in an application I own, so I don't know the action and category and data flags on the intent-filter.
How can I examine an Android applications metadata like the activity classes and the intent-filters for those activities (if declared in the manifest)?
Thanks!
I would try this.
Check on openintents
Contact the developer.
Use android-apktool too see the app's manifest.
It might be illegal to use android-apktool. Use it under your own risk.
There is one more solution: you could run this app and look into logcat. All intents are logged, so you could see what is called up. You won't see extra data though.