In my app I have a fragment and an imageButton inside of this fragment. When I run the app in my device (Android 8 - API 26) and click imageButton, the app crashes and throws a runtime error which I didn't see before.
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.mustafa.diyetisyenadmin, PID: 26366
java.lang.SecurityException: Permission Denial: null asks to run as user 1 but is calling from user 0; this requires android.permission.INTERACT_ACROSS_USERS_FULL or android.permission.INTERACT_ACROSS_USERS
at android.os.Parcel.readException(Parcel.java:1945)
at android.os.Parcel.readException(Parcel.java:1891)
at android.view.autofill.IAutoFillManager$Stub$Proxy.addClient(IAutoFillManager.java:326)
at android.view.autofill.AutofillManager.ensureServiceClientAddedIfNeededLocked(AutofillManager.java:903)
at android.view.autofill.AutofillManager.notifyViewExited(AutofillManager.java:487)
at android.view.View.notifyEnterOrExitForAutoFillIfNeeded(View.java:6983)
at android.view.View.dispatchAttachedToWindow(View.java:17594)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3332)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3339)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3339)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3339)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3339)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3339)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3339)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1792)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1515)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7266)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:981)
at android.view.Choreographer.doCallbacks(Choreographer.java:790)
at android.view.Choreographer.doFrame(Choreographer.java:721)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:967)
at android.os.Handler.handleCallback(Handler.java:808)
at android.os.Handler.dispatchMessage(Handler.java:101)
at android.os.Looper.loop(Looper.java:166)
at android.app.ActivityThread.main(ActivityThread.java:7425)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921)
So I added the required permissions in Manifest.xml and also tried every codes in the topic Android permission.INTERACT_ACROSS_USERS_FULL but I get the same error. I have solved Autofill problem with this topic but in that fragment error occurs just only I clicked ImageButton. What should I do to solve this problem?
Finally I found out the solution. Problem occurs since I had a method in my activity named getUserId() that returns String user_id and send data to fragments. I changed it's name and now everything works fine.
You have to add runtime permission. To do that follow
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!checkIfAlreadyhavePermission()) {
requestForSpecificPermission();
}
}
Module checkIfAlreadyhavePermission() is implemented as :
private boolean checkIfAlreadyhavePermission() {
int result = ContextCompat.checkSelfPermission(this, Manifest.permission.INTERACT_ACROSS_USERS_FULL);
return result == PackageManager.PERMISSION_GRANTED;
}
Module requestForSpecificPermission() is implemented as :
private void requestForSpecificPermission() {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.INTERACT_ACROSS_USERS_FULL}, 101);
}
and Override in Activity :
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case 101:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//DO WHATEVER YOU WANTED TO DO
} else {
//not granted
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
Related
My android app needs some permissions, so I used the following code according to the developer's Guide.But it went wrong.
ActivityResultLauncher launcher = registerForActivityResult(new ActivityResultContracts.RequestPermission(), result -> {
if(result){
Log.d(TAG, "onActivityResult: Permission Granted");
}
else{
Log.d(TAG, "onActivityResult: No Permission");
}
});
launcher.launch(Manifest.permission.ACCESS_FINE_LOCATION);
Exception:
Caused by: java.lang.IllegalArgumentException: Can only use lower 16 bits for requestCode
Why is the "recommended" method wrong?
The problem is not in THIS code. RequestCode is valid from 0 up to 32766 but when your code (or a 3rd library) calls "...requestPermissions(.., .., requestCode)" (maybe in your "launch(...)" method) the "requestCode" goes outside that range.
I've tried to implement a preview for CameraX, but I've got two errors in my code, that I cannot solve:
CameraSelector is not public in androidx.camera.core.CameraSelector. Cannot be accessed from outside package.
Cannot resolve symbol 'previewView'
EDIT: I solved the problems, but I still don't get the preview. I did not mentioned before, but I inserted the permissions in the Android Manifest.
Here's my code:
MainActivity.java
public class MainActivity extends AppCompatActivity {
private ListenableFuture<ProcessCameraProvider> cameraProviderFuture;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
PreviewView previewView = (PreviewView) findViewById(R.id.previewView);
cameraProviderFuture = ProcessCameraProvider.getInstance(this);
cameraProviderFuture.addListener(() -> {
try {
ProcessCameraProvider cameraProvider = cameraProviderFuture.get();
Preview preview = new Preview.Builder().build();
CameraSelector cameraSelector = new CameraSelector.Builder().requireLensFacing(CameraSelector.LENS_FACING_BACK).build();
preview.setSurfaceProvider(previewView.createSurfaceProvider());
cameraProvider.unbindAll();
cameraProvider.bindToLifecycle((LifecycleOwner)this, cameraSelector, preview);
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
}
}, ContextCompat.getMainExecutor(this));
}
}
Build.gradle (Module: app), inside dependencies section
def camerax_version = "1.0.0-beta07"
implementation "androidx.camera:camera-core:$camerax_version"
implementation "androidx.camera:camera-camera2:$camerax_version"
implementation "androidx.camera:camera-lifecycle:$camerax_version"
implementation "androidx.camera:camera-view:1.0.0-alpha14"
activity_main.xml
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.camera.view.PreviewView
android:id="#+id/previewView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
I know that createSurfaceProvider() has been renamed to getSurfaceProvider() since Camera-View Version 1.0.0-alpha16, but when I try to call the last method Android Studio does not solve it.
And here's the logs (error)
2020-11-22 20:59:01.944 10830-10830/? E/Zygote: isWhitelistProcess - Process is Whitelisted
2020-11-22 20:59:01.945 10830-10830/? E/Zygote: accessInfo : 1
2020-11-22 20:59:03.214 10830-10885/com.android.unipi.camerademo E/Camera_APM :: [APM]APM's Thread is started
2020-11-22 20:59:03.216 10830-10885/com.android.unipi.camerademo E/Camera_APM :: [APM] This app is forground app
2020-11-22 20:59:03.223 10830-10872/com.android.unipi.camerademo E/SequentialExecutor: Exception while executing runnable androidx.camera.camera2.internal.-$$Lambda$Camera2CameraImpl$_NFNV64YCFFY0Tn3VRiyE3Ss3S0#5d0b8a
java.lang.SecurityException: validateClientPermissionsLocked:1145: Caller "com.android.unipi.camerademo" (PID 10188, UID 10830) cannot open camera "0" without camera permission
at android.hardware.camera2.CameraManager.throwAsPublicException(CameraManager.java:855)
at android.hardware.camera2.CameraManager.openCameraDeviceUserAsync(CameraManager.java:499)
at android.hardware.camera2.CameraManager.openCameraForUid(CameraManager.java:670)
at android.hardware.camera2.CameraManager.openCamera(CameraManager.java:638)
at androidx.camera.camera2.internal.compat.CameraManagerCompatApi28Impl.openCamera(CameraManagerCompatApi28Impl.java:70)
at androidx.camera.camera2.internal.compat.CameraManagerCompat.openCamera(CameraManagerCompat.java:185)
at androidx.camera.camera2.internal.Camera2CameraImpl.openCameraDevice(Camera2CameraImpl.java:871)
at androidx.camera.camera2.internal.Camera2CameraImpl.openInternal(Camera2CameraImpl.java:236)
at androidx.camera.camera2.internal.Camera2CameraImpl.tryAttachUseCases(Camera2CameraImpl.java:691)
at androidx.camera.camera2.internal.Camera2CameraImpl.lambda$attachUseCases$10$Camera2CameraImpl(Camera2CameraImpl.java:649)
at androidx.camera.camera2.internal.-$$Lambda$Camera2CameraImpl$_NFNV64YCFFY0Tn3VRiyE3Ss3S0.run(Unknown Source:4)
at androidx.camera.core.impl.utils.executor.SequentialExecutor$QueueWorker.workOnQueue(SequentialExecutor.java:230)
at androidx.camera.core.impl.utils.executor.SequentialExecutor$QueueWorker.run(SequentialExecutor.java:172)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:764)
Caused by: android.os.ServiceSpecificException: validateClientPermissionsLocked:1145: Caller "com.android.unipi.camerademo" (PID 10188, UID 10830) cannot open camera "0" without camera permission (code 1)
at android.os.Parcel.createException(Parcel.java:1980)
at android.os.Parcel.readException(Parcel.java:1934)
at android.os.Parcel.readException(Parcel.java:1884)
at android.hardware.ICameraService$Stub$Proxy.connectDevice(ICameraService.java:359)
at android.hardware.camera2.CameraManager.openCameraDeviceUserAsync(CameraManager.java:463)
at android.hardware.camera2.CameraManager.openCameraForUid(CameraManager.java:670)
at android.hardware.camera2.CameraManager.openCamera(CameraManager.java:638)
at androidx.camera.camera2.internal.compat.CameraManagerCompatApi28Impl.openCamera(CameraManagerCompatApi28Impl.java:70)
at androidx.camera.camera2.internal.compat.CameraManagerCompat.openCamera(CameraManagerCompat.java:185)
at androidx.camera.camera2.internal.Camera2CameraImpl.openCameraDevice(Camera2CameraImpl.java:871)
at androidx.camera.camera2.internal.Camera2CameraImpl.openInternal(Camera2CameraImpl.java:236)
at androidx.camera.camera2.internal.Camera2CameraImpl.tryAttachUseCases(Camera2CameraImpl.java:691)
at androidx.camera.camera2.internal.Camera2CameraImpl.lambda$attachUseCases$10$Camera2CameraImpl(Camera2CameraImpl.java:649)
at androidx.camera.camera2.internal.-$$Lambda$Camera2CameraImpl$_NFNV64YCFFY0Tn3VRiyE3Ss3S0.run(Unknown Source:4)
at androidx.camera.core.impl.utils.executor.SequentialExecutor$QueueWorker.workOnQueue(SequentialExecutor.java:230)
at androidx.camera.core.impl.utils.executor.SequentialExecutor$QueueWorker.run(SequentialExecutor.java:172)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:764)
According to the logs, I don't insert camera permission, but I do that. Maybe I miss other permissions?
With the suggestions of Husayn and Shark I've solved the problem. Any device with Android 6 or higher version (API 23+) requires a runtime permission.
Check if the user has granted the camera permission. Otherwise, request that permission. Insert the following code inside the onCreate() method before calling CameraX code:
if (checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.CAMERA}, CAMERA_REQUEST);
}
where CAMERA_REQUEST is a constant. Here's an example:
private static final int CAMERA_REQUEST = 100;
Then, it will appear a dialog, in which the user can allow or deny the permission. We can see the result with the following method:
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == CAMERA_REQUEST) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "CameraX permission granted", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "CameraX permission denied", Toast.LENGTH_SHORT).show();
}
}
}
As you can see this is my code, I built several applications in which I used several permission methods without any problem. In this case, I only have just one activity but it gives me an error while it wants to return the request permission result.
Code:
public class ActivityStartUp extends AppCompatActivity implements ActivityCompat.OnRequestPermissionsResultCallback {
private static final String[] PERMISSIONS = { "android.permission.CAMERA",
"android.hardware.camera", "android.hardware.camera.autofocus",
"android.hardware.camera.flash",
"android.permission.ACCESS_COARSE_LOCATION",
"android.permission.WRITE_EXTERNAL_STORAGE",
"android.permission.READ_EXTERNAL_STORAGE" ,
"android.permission.READ_PHONE_STATE"};
private static final int PERMISSION_CODE = 0xBAB0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_startup);
if (Utilities.hasMarshmallowApi()) {
requestPermissions(PERMISSIONS, PERMISSION_CODE);
}else{
//Open an activity
}
}
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case PERMISSION_CODE: {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
G.permissionGrantStatus = true;
Log.i("Log", "Permission Status:" + true);
if(Utilities.hasMarshmallowApi()){
// Do something
}
// Do task
} else {
G.permissionGrantStatus = false;
Log.i("Log", "Permission Status:" + false);
// permission denied, boo! Disable the
// functionality that depends on this permission.
}
return;
}
}
}
}
Error:
java.lang.RuntimeException: Failure delivering result
ResultInfo{who=#android:requestPermissions:, request=47792, result=-1,
data=Intent { act=android.content.pm.action.REQUEST_PERMISSIONS (has extras) }}
to activity {com.bvapp.sh.uni.watermanagement/com.bvapp.sh.uni.watermanagement.ActivityStartUp}:
java.lang.ArrayIndexOutOfBoundsException: length=0; index=0
As you can see in error "grantResults" has 0 length. I tried to find a good solution but unfortunately I couldn't fine a right one. why it's happening and how should I solve it?
Thanks in advance.
Maybe this is you'r problem (from: OnRequestPermissionsResultCallback() - Android Developer)
Note: It is possible that the permissions request interaction with the user is interrupted. In this case you will receive empty
permissions and results arrays which should be treated as a
cancellation.
I have a VideoCallPageRenderer like below
VideoCallPageRenderer : PageRenderer, Android.Support.V4.App.ActivityCompat.IOnRequestPermissionsResultCallback
{
public const int REQUEST_MIC = 0;
protected override void OnElementChanged(ElementChangedEventArgs<Page> e)
{
// Other codes
RequestMicPermission();
}
public void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Permission[] grantResults)
{
if (requestCode == REQUEST_MIC)
{
if (grantResults.Length == 1 && grantResults[0] == Permission.Granted)
{
}
}
}
private void RequestMicPermission()
{
Android.Support.V4.App.ActivityCompat.RequestPermissions((Activity)Xamarin.Forms.Forms.Context, new string[] { Android.Manifest.Permission.RecordAudio }, REQUEST_MIC);
}
}
Here RequestMicPermission works fine because I can see the pop up coming on screen asking for permission. But after I allow or deny OnRequestPermissionsResult is not called.
Any help? It would be very hard to try to override it in the Activity.
For anyone else having an issue here, I was not seeing the OnRequestPermissionsResult being called either. But I had the debugger attached, the handler wasn't doing anything, and even though the breakpoint was valid, it was never hit.
I finally did a clean and rebuild and voila, the breakpoint was hit.
Just in case someone else was tearing their hair out like myself :).
For future readers that encountered this problem too, a good approach is abstract the permissions features in a service and register it with Xamarin Form´s Dependencyservice.
You can resolve this service in your renderer, or any non-activity class, to use it. Also resolve it in MainActivity, override OnRequestPermissionsResult, and call yourService.OnPermissionResult to communicate the result.
As Koushik says ActivityCompat.IOnRequestPermissionsResultCallback doesnt work because we call RequestPermissions with reference to MainActivity, so the result is obtained in this activity.
You can see an implementation example in my Github:
GpsService
MainActivity
I have an app that stores it's images on the external storage. This have been working great up until I tried the new M preview.
I use picasso (I even tried Ion) to load the images and I get the images with the "file:///mnt/sdcard/appname/image1.jpg" URI.
I don't get any errors at all, but I'm guessing that M has changed the permissions to read from external storage. I have tried googling but I come up empty.
Writing the images to the external storage works just as normal by the way.
Although siris_cac answer was very well explained it wasn't what caused my problem.
Turns out I can't use "file:///mnt/sdcard/appname/image1.jpg" to load the file from external storage in M.
I guess it might have something to to with http://www.androidpolice.com/2015/05/28/android-m-feature-spotlight-external-storage-can-be-adopted-as-true-internal-storage-or-accessed-normally-with-no-additional-apps/
I guess I was wrong from the begining not using the Enviroment.getExternalStorageDirectory() when loading images, only when saving them.
So now to load images I use:
"file:///" + Environment.getExternalStorageDirectory().getPath() + "/appname/image1.jpg";
You could try checking if the permission is granted by :
checkCallingOrSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE);
And try requesting permissions on Runtime like this using requestPermissions().
int EXT_PERMISSION = 1;
requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 0);
And,
Handle the Permission Granted result
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case EXT_PERMISSION: {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//permission granted
} else {
//permission denied
}
break;
}
}
}