Permission denial: writing to settings requires android.permission.WRITE_SETTINGS - android

For a very limited number of users, my app is crashing with the following:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.cloud3squared.meteogram.pro/com.cloud3squared.meteogram.MeteogramWidgetConfigureActivity}:
java.lang.SecurityException: Permission denial: writing to settings requires android.permission.WRITE_SETTINGS
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2693)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2758)
at android.app.ActivityThread.access$900(ActivityThread.java:177)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1448)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:5942)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1388)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1183)
Caused by: java.lang.SecurityException: Permission denial: writing to settings requires android.permission.WRITE_SETTINGS
at android.os.Parcel.readException(Parcel.java:1540)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:185)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:137)
at android.content.ContentProviderProxy.call(ContentProviderNative.java:643)
at android.provider.Settings$NameValueCache.putStringForUser(Settings.java:1204)
at android.provider.Settings$System.putStringForUser(Settings.java:1505)
at android.provider.Settings$System.putIntForUser(Settings.java:1616)
at android.provider.Settings$System.putInt(Settings.java:1607)
at android.app.WallpaperManager$Globals.getDefaultWallpaperLocked(WallpaperManager.java:483)
at android.app.WallpaperManager$Globals.peekWallpaperBitmap(WallpaperManager.java:303)
at android.app.WallpaperManager.getDrawable(WallpaperManager.java:550)
at com.cloud3squared.meteogram.ax.c(Unknown Source)
at com.cloud3squared.meteogram.MeteogramWidgetConfigureActivity.a(Unknown Source)
at com.cloud3squared.meteogram.MeteogramWidgetConfigureActivity.c(Unknown Source)
at com.cloud3squared.meteogram.MeteogramWidgetConfigureActivity.onCreate(Unknown Source)
at android.app.Activity.performCreate(Activity.java:6288)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2646)
... 10 more
Whilst a solution to the issue is given in the crash report (just add android.permission.WRITE_SETTINGS to the Manifest), it troubles me that I need to, because my app doesn't knowingly write to settings, and the vast majority of users don't have any issue without the permission.
It is particularly troubling because the docs say that:
There are a couple of permissions that don't behave like normal and
dangerous permissions. SYSTEM_ALERT_WINDOW and WRITE_SETTINGS are
particularly sensitive, so most apps should not use them. If an app
needs one of these permissions, it must declare the permission in the
manifest, and send an intent requesting the user's authorization. The
system responds to the intent by showing a detailed management screen
to the user.
I want to do everything I can to avoid having this permission in my app, given that it's apparently "dangerous", and having to request this permission at runtime is enough to scare off even non-tin-hatted users. I really don't need to write to settings... I write to SharedPreferences and that's about it.
So is there any way of avoiding this problem without requiring the permission?
EDIT to add code as per comment below (this function is called from my Activity):
static String getAverageWallpaperColour(Context context) {
final WallpaperManager wallpaperManager = WallpaperManager.getInstance(context);
final Drawable wallpaperDrawable = wallpaperManager.getDrawable();
Bitmap bmp = ((BitmapDrawable)wallpaperDrawable).getBitmap();
int color = getAverageColour(bmp); // details of function not relevant... just reads the bmp to work out an average colour
return colorToHexString(color); // details of function not relevant... just converts into color to String in particular format
}

I have now determined that the problem lies in the code snippet I added to the Question in an edit:
static String getAverageWallpaperColour(Context context) {
final WallpaperManager wallpaperManager = WallpaperManager.getInstance(context);
final Drawable wallpaperDrawable = wallpaperManager.getDrawable();
Bitmap bmp = ((BitmapDrawable)wallpaperDrawable).getBitmap();
int color = getAverageColour(bmp); // details of function not relevant... just reads the bmp to work out an average colour
return colorToHexString(color); // details of function not relevant... just converts into color to String in particular format
}
Basically, a user for whom the app was crashing has told me that they have a live wallpaper active on their device, rather than a conventional static wallpaper.
So, for some reason I still don't understand, either in trying to get the drawable, or get a bitmap from the drawable, this somehow leads to the Settings$System.putInt and Settings$System.putIntForUser and Settings$System.putStringForUser log entries, which in turn leads to the SecurityException: Permission denial error (attempting to write to Settings without permission).
This post is along similar lines, reporting that the error seemed to be associated with a situation in which the "system wallpaper was null". Quite why there isn't just a NullPointerException when I try to do something unspeakable with null, and instead there is a dire permissions error after apparently attempting to tamper with the Settings, I don't know.

Related

SecurityException: <<other_package>> from uid xxx not allowed to perform READ_CLIPBOARD when calling setPrimaryClip

I've been getting reports of the following crash
SecurityException: <<other_package>> from uid xxx not allowed to perform READ_CLIPBOARD
The crash occurred when a user clicks on a button that copies a text into clipboard as shown below.
val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
val clip = ClipData.newPlainText("label", shareUrl)
clipboard.setPrimaryClip(clip)
So my app doesn't try to read anything from clipboard. Really confusing why this error could happen.
Does anyone know how this crash happen and how can I fix this?
Additional Information
This crash only happens in Android 9 and Android 10 and not happens easily (only 6 users from 200k monthly active users)
I only saw two <<other_package>> in Crashlytics (one is a Bank app and another is a Music app).
I tried to read the source code of ClipboardService.java and AppOpsManager.java and found that the crash might came from noteOp in AppOpsManager.
Here is the stack trace of the crash:
Fatal Exception: java.lang.SecurityException: <<other_package>> from uid xxx not allowed to perform READ_CLIPBOARD
at android.os.Parcel.createException(Parcel.java:2087)
at android.os.Parcel.readException(Parcel.java:2055)
at android.os.Parcel.readException(Parcel.java:2003)
at android.content.IClipboard$Stub$Proxy.setPrimaryClip(IClipboard.java:293)
at android.content.ClipboardManager.setPrimaryClip(ClipboardManager.java:106)
at my.package.MyClass.copyToClipboard(MyClass.java:63)
at android.view.View.performClick(View.java:7375)
at android.view.View.performClickInternal(View.java:7336)
at android.view.View.access$3900(View.java:822)
at android.view.View$PerformClick.run(View.java:28214)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:238)
at android.app.ActivityThread.main(ActivityThread.java:7829)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:986)
Caused by android.os.RemoteException: Remote stack trace:
at android.app.AppOpsManager.noteOp(AppOpsManager.java:2568)
at com.android.server.clipboard.ClipboardService.clipboardAccessAllowed(ClipboardService.java:933)
at com.android.server.clipboard.ClipboardService.setPrimaryClipInternal(ClipboardService.java:775)
at com.android.server.clipboard.ClipboardService.setPrimaryClipInternal(ClipboardService.java:710)
at com.android.server.clipboard.ClipboardService$ClipboardImpl.setPrimaryClip(ClipboardService.java:358)
I can finally reproduce the crash in Android 9. This is what I found...
Root cause: When foreground app calls setPrimaryClipboard, the ClipboardService will broadcast the event to PrimaryClipChangedListener (if any) and will also make a call to AppOpsManager.noteOp to inform about READ_CLIPBOARD operation.
If the listener is not allowed to READ_CLIPBOARD (user can disallow by using adb shell command: cmd appops set <package> READ_CLIPBOARD deny), AppOpsManager.noteOp will throw a SecurityException and will crash the foreground app.
Now I'm sure that my code doesn't do anything wrong, but unfortunately I think I have to put try/catch around setPrimaryClip

Passing a Camera Image as Bitmap Returns TransactionTooLarge Exception

I am using camera kit library for my app. When I get the picture call back, I convert the byte array to bitmap and try to pass it to the next activity like this:
ab_capture.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
cameraView.captureImage(new CameraKitEventCallback<CameraKitImage>() {
#Override
public void callback(CameraKitImage cameraKitImage) {
byte[] jpeg = cameraKitImage.getJpeg();
Bitmap bitmap = BitmapFactory.decodeByteArray(jpeg, 0, jpeg.length);
Intent previewIntent = new Intent(ImageActivity.this, PreviewActivity.class);
previewIntent.putExtra("cam_image", bitmap);
startActivity(previewIntent); // implicit
finish();
}
});
}
});
but after clicking the button, app crashes and I get this error message:
E/JavaBinder: !!! FAILED BINDER TRANSACTION !!! (parcel size = 3686928)
02-28 01:03:06.183 9579-9999/base.android.com.thumbsapp E/AndroidRuntime: FATAL EXCEPTION: CameraViewWorker
Process: base.android.com.thumbsapp, PID: 9579
java.lang.RuntimeException: Failure from system
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1525)
at android.app.Activity.startActivityForResult(Activity.java:4226)
at android.support.v4.app.BaseFragmentActivityApi16.startActivityForResult(BaseFragmentActivityApi16.java:54)
at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:67)
at android.app.Activity.startActivityForResult(Activity.java:4185)
at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:732)
at android.app.Activity.startActivity(Activity.java:4509)
at android.app.Activity.startActivity(Activity.java:4477)
at base.android.com.thumbsapp.UI.Activities.ImageActivity$1$1.callback(ImageActivity.java:83)
at base.android.com.thumbsapp.UI.Activities.ImageActivity$1$1.callback(ImageActivity.java:75)
at com.wonderkiln.camerakit.CameraView$4.imageCaptured(CameraView.java:471)
at com.wonderkiln.camerakit.Camera1$5.onPictureTaken(Camera1.java:427)
at android.hardware.Camera$EventHandler.handleMessage(Camera.java:1361)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:203)
at android.os.HandlerThread.run(HandlerThread.java:61)
Caused by: android.os.TransactionTooLargeException: data parcel size 3686928 bytes
at android.os.BinderProxy.transactNative(Native Method)
at android.os.BinderProxy.transact(Binder.java:622)
at android.app.ActivityManagerProxy.startActivity(ActivityManagerNative.java:3197)
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1518)
at android.app.Activity.startActivityForResult(Activity.java:4226) 
at android.support.v4.app.BaseFragmentActivityApi16.startActivityForResult(BaseFragmentActivityApi16.java:54) 
at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:67) 
at android.app.Activity.startActivityForResult(Activity.java:4185) 
at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:732) 
at android.app.Activity.startActivity(Activity.java:4509) 
at android.app.Activity.startActivity(Activity.java:4477) 
at base.android.com.thumbsapp.UI.Activities.ImageActivity$1$1.callback(ImageActivity.java:83) 
at base.android.com.thumbsapp.UI.Activities.ImageActivity$1$1.callback(ImageActivity.java:75) 
at com.wonderkiln.camerakit.CameraView$4.imageCaptured(CameraView.java:471) 
at com.wonderkiln.camerakit.Camera1$5.onPictureTaken(Camera1.java:427) 
at android.hardware.Camera$EventHandler.handleMessage(Camera.java:1361) 
at android.os.Handler.dispatchMessage(Handler.java:110) 
at android.os.Looper.loop(Looper.java:203) 
at android.os.HandlerThread.run(HandlerThread.java:61) 
This error only occurs on a Nougat device. When I run on Lollipop, there is no error but it doesn't start the preview activity.
I need help understanding and resolving this error and also the problem with going to the next activity. Thanks.
You should never pass this big data using intents. It will crash on most devices and is not well designed.
First store file to disk then put its path to intent
This error only occurs on a Nougat device
It will happen on the vast majority of Android devices.
I need help understanding and resolving this error
Your Intent is too large, due to the large Bitmap extra.
The best solution is to not have two activities here. Have one activity with a changing UI, such as via the use of fragments.
Alternatively, carefully pass the Bitmap via a static field, making sure to set that field to null ASAP, so you do not have a long-term memory leak.

React-Native (Android) : ArrayIndexOutOfBoundsException thrown when requesting for permissions

Recently I have encountered a very strange issue while working with a React-Native app. Here's my environement:
Rect-Native 0.42.3
Samsung Galaxy Note 5
Android 6.0
As you may know, the Android permission model has changed since Marshmallow, but some days ago, I got his exception:
java.lang.RuntimeException:
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4156)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4250)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1839)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:7229)
at java.lang.reflect.Method.invoke(Native Method:0)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
Caused by: java.lang.ArrayIndexOutOfBoundsException:
at com.facebook.react.modules.permissions.PermissionsModule$1.invoke(PermissionsModule.java:119)
at com.facebook.react.modules.permissions.PermissionsModule.onRequestPermissionsResult(PermissionsModule.java:207)
at com.facebook.react.ReactActivityDelegate$1.invoke(ReactActivityDelegate.java:211)
at com.facebook.react.ReactActivityDelegate.onResume(ReactActivityDelegate.java:131)
at com.facebook.react.ReactActivity.onResume(ReactActivity.java:66)
at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1286)
at android.app.Activity.performResume(Activity.java:6987)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4145)
First, I thought I was missing a check in the code, as explained here but this is not the case as otherwise I would have a message like this instead:
java.lang.SecurityException: Permission Denial: opening provider com.android.providers.contacts.ContactsProvider2 from ProcessRecord{fac49ea 4674:com.gospacesmobile/u0a65} (pid=4674, uid=10065) requires android.permission.READ_CONTACTS or android.permission.WRITE_CONTACTS
I looked at React-Native's code and found this:
// com.facebook.react.modules.permissions.PermissionsModule.java
int[] results = (int[]) args[0];
if (results[0] == PackageManager.PERMISSION_GRANTED) { // <- the exception happens when results is empty
promise.resolve(GRANTED);
} else {
PermissionAwareActivity activity = (PermissionAwareActivity) args[1];
if (activity.shouldShowRequestPermissionRationale(permission)) {
promise.resolve(DENIED);
} else {
promise.resolve(NEVER_ASK_AGAIN);
}
}
According the documentation, the grantResults variable may be empty whenever the permission request has been canceled:
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// contacts-related task you need to do.
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
}
return;
}
// other 'case' lines to check for other
// permissions this app might request
}
}
Unfortunately, I do not have the client code (as the crash report in the google console dev does not mention it). In any case, shouldn't React-Native check for empty grantResults? Is this a bug? If yes, how could this be reproduced? I don't see any way this could be done, except by canceling the promise responsible for ensuring if a permission has been enabled or not (which is impossible considering react-native permissions API).
Any thought is very welcome. Thank you in advance.
So I finally found the problem. Whenever the permission request dialog appear, if the user minimizes the app, and then goes back to it by clicking on the app's icon in from the home menu, the results is empty which makes the app crashing.
This seems to be quiet a simple issue, and I've decided to monkey patch React-Native in order to prevent an unstable upgrade (Now I check if the results array is empty or not, and if it is, then deny the request). I still don't know if this is a common issue or something that comes from my app.

Sporadic IllegalArgumentException: Unknown URL content://

Very rarely getting:
Fatal Exception: java.lang.IllegalArgumentException: Unknown URL content://com.example.provider/info
at android.content.ContentResolver.insert(ContentResolver.java:1252)
Fatal Exception: java.lang.IllegalArgumentException: Unknown authority com.example.provider
at android.content.ContentResolver.applyBatch(ContentResolver.java:1247)
Emphasis on rarely. Generally work fine without issue, so the authorities is set up fine, but this is showing up every once in a while for no reason. Are there reasons why the ContentResolver may not be able to find a ContentProvider (i.e. if not set up yet)?
I've had the rare IllegalArgumentException with Unknown URIs issue when I was doing ContentResolver operations in the custom Application object.
For example, I was trying to delete items in my content provider in the application onCreate method which would very occasionally crash:
public class CustomApplication extends Application {
#Override
public void onCreate() {
//..
context.getContentResolver().delete(ReminderEntry.getContentURI(), null, null, null, null);
//..
}
}
Which would sometimes render the following crash:
Fatal Exception: java.lang.RuntimeException: Unable to create application com.myapp.CustomApplication: java.lang.IllegalArgumentException: Unknown URL content://com.myapp.db.CustomContentProvider/reminder
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6431)
at android.app.ActivityThread.access$1800(ActivityThread.java:229)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1887)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:7331)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
Caused by java.lang.IllegalArgumentException: Unknown URL content://com.myapp.db.CustomContentProvider/reminder
at android.content.ContentResolver.delete(ContentResolver.java:1376)
at com.myapp.ReminderEntryDao.delete(Unknown Source)
at com.myapp.CustomApplication.onCreate(Unknown Source)
at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1037)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6428)
at android.app.ActivityThread.access$1800(ActivityThread.java:229)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1887)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:7331)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
I also saw similar behaviour with a BOOT_COMPLETE receiver. I had about 70 reported crashes with this exception (mostly Infinix devices ~43%, hardly any Samsung Devices) of about 200 000 monthly active users.
I moved this into a background scheduled job and haven't seen the crash since. I was only ever able to reproduce this issue once on a Nexus device that I used but never again.
I suspect perhaps sometimes on some versions of Android on some devices the Application/BOOT_COMPLETE Receiver initializes before the ContentProvider is fully initialized and therefore when it tries to access it, it is not properly set up yet.
There are a couple of stackoverflow posts that do state exactly what is created first and how the OS should behave:
Is the Application class guaranteed to be instantiated before a defined boot receiver is called
But like I said, I've seen otherwise and moving operations out of the classes into background schedulers seems to fix the problem (perhaps it is just because it takes a bit longer to get setup). Hopefully my experience will help you.
Edit: I used the evernote job dispatcher and deferred my ContentResolver operations to the job if required. (but I would assume that deferring the content provider operation to any kind of background processing might fix it as it had a bit more time to get setup - these are just my suspicions of course).
class DeleteRemindersJob extends Job {
#NonNull
#Override
protected Result onRunJob(final Params params) {
cursor = getContext().getContentResolver().delete(ReminderEntry.getContentURI(), null, null, null, null);
//..
return Result.SUCCESS;
}
}

Android Camera2 API SecurityException

I'm trying to use the new Android camera2 api. I started with source from this tutorial : http://jylee-world.blogspot.com/2014/12/a-tutorial-of-androidhardwarecamera2.html . When I try to usb-debug-deploy it to any phone, I get a SecurityException from CameraManager.openCamera(...).
My AndroidManifest looks like this:
<uses-feature android:name="com.android.hardware.camera2.full"/>
<uses-permission android:name="android.permission.CAMERA"/>
This seems to be what every tutorial I've been able to find does. I'm able to get permission for other actions; for example, I can make the camera vibrate just fine. I'm also able to enumerate cameras with CameraManager.getCameraIdLists() just fine, but I'm not sure if that actually requires permission. But I can't openCamera.
Are there some additional permissions I need? Am I doing something wrong?
Thanks for the help!
This is my full stack trace:
SecurityException
java.lang.SecurityException: Lacking privileges to access camera serviceat android.hardware.camera2.utils.CameraBinderDecorator.throwOnError(CameraBinderDecorator.java:108)
at android.hardware.camera2.legacy.CameraDeviceUserShim.connectBinderShim(CameraDeviceUserShim.java:336)
at android.hardware.camera2.CameraManager.openCameraDeviceUserAsync(CameraManager.java:327)
at android.hardware.camera2.CameraManager.openCamera(CameraManager.java:457)
at com.example.quinnfreedman.camera2test.MainActivity$1.onSurfaceTextureAvailable(MainActivity.java:74)
at android.view.TextureView.getHardwareLayer(TextureView.java:368)
at android.view.View.updateDisplayListIfDirty(View.java:15167)
at android.view.View.draw(View.java:15964)
at android.view.ViewGroup.drawChild(ViewGroup.java:3612)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3402)
at android.view.View.updateDisplayListIfDirty(View.java:15185)
at android.view.View.draw(View.java:15964)
at android.view.ViewGroup.drawChild(ViewGroup.java:3612)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3402)
at android.view.View.updateDisplayListIfDirty(View.java:15185)
at android.view.View.draw(View.java:15964)
at android.view.ViewGroup.drawChild(ViewGroup.java:3612)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3402)
at android.view.View.updateDisplayListIfDirty(View.java:15185)
at android.view.View.draw(View.java:15964)
at android.view.ViewGroup.drawChild(ViewGroup.java:3612)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3402)
at android.view.View.draw(View.java:16197)
at com.android.internal.policy.PhoneWindow$DecorView.draw(PhoneWindow.java:2690)
at android.view.View.updateDisplayListIfDirty(View.java:15190)
at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:281)
at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:287)
at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:322)
at android.view.ViewRootImpl.draw(ViewRootImpl.java:2627)
at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2446)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2079)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1119)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6060)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858)
at android.view.Choreographer.doCallbacks(Choreographer.java:670)
at android.view.Choreographer.doFrame(Choreographer.java:606)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844)
at android.os.Handler.handleCallback(Handler.java:746)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5443)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
In Android M, run time permission check is required for dangerous permission. You can see dangerous permission here.
Check for permission :
// Assume thisActivity is the current activity
int permissionCheck = ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.CAMERA);
If the app has the permission, the method returns PackageManager.PERMISSION_GRANTED, and the app can proceed with the operation. If the app does not have the permission, the method returns PERMISSION_DENIED, and the app has to explicitly ask the user for permission.
For details: https://developer.android.com/training/permissions/requesting.html#perm-request
Just close your camera device in onSurfaceTextureDestroyed function
onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture){cameraDevice.close();cameraDevice = null;}
Security exception will get fix
When you are running your application on android 6+, you need to give the famous runtime permissions.
https://developer.android.com/training/permissions/requesting.html
The permission you are trying to give is considered a dangerous permissions android.
https://developer.android.com/guide/topics/security/permissions.html#normal-dangerous
Different of other responses about runtime permission, I suggest you to use this https://github.com/Karumi/Dexter
This lib makes the permission handling easily
Struggled with this off and on for weeks, thinking several times I'd solved the problem. In the end, none of the "fixes" I'd read about here worked. Then, after putting in ~100 Log.v statements in my Java, I realized it was a threading issue that might, or might not, kick off this error depending on events on the camera. Basically, I think, the main program was running on the main thread, but there was an extra thread kicked off by the following statement:
//this code seems to be the culprit ... commenting it out solve my problem
private void showToast(final String text) {
final Activity activity = MyStupidProgram.this;
if (activity != null) {
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(activity, text, Toast.LENGTH_SHORT).show();
}
});
}
}
So while there's nothing in this statement calling the camera, perhaps because of thread safety, Android 5.x and 6.x were throwing security errors when I called showToast('some crap');
Commenting that out and just using a Toast.makeText('blah blah'); statement, I was able to get rid of the security error.
Additionally, I added this to the code on the page's onCreate(); statement, to catch any issues on the main thread:
Thread.setDefaultUncaughtExceptionHandler(
new Thread.UncaughtExceptionHandler() {
#Override
public void uncaughtException(
Thread paramThread,
Throwable paramThrowable
) {
//Do your own error handling here
if (exceptionHandler != null)
exceptionHandler.uncaughtException(
paramThread,
paramThrowable
); //Delegates to Android's error handling
else
System.exit(2); //Prevents the service/app from freezing
}
});

Categories

Resources