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();
}
}
}
Related
(See UPDATE below)
I have a Xamarin Forms app on Android which uses the Xamarin.Essentials library.
The app requires to run in the background to be fed location data (not particularly relevant to the question in hand, but included for context), and so must not be put to sleep by any battery optimisations that the OS might attempt.
I know that the user can manually opt out specific apps from Battery Optimizations, but as it is so crucial to the successful operation of the app, I would like the app to be able to :
check the Battery Optimization Opt-out permission status to ensure it is appropriately set,
and/or
force Android to opt the app of any battery optimizations.
I have added an entry into AndroidManifest.xml, but it doesn't seem to help, with the newly-installed app defaulting to being Battery Optimized.
AndroidManifest.xml
The manifest contains the following entry:
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
Xamarin.Essentials
This library gives access to a number of permission-related info on the device, but Battery Optimizations doesn't seem to be one of them.
Device being used
I don't know if it's relevant, but I am testing on a Samsung Galaxy S20 Ultra.
Can anyone offer any advice?
UPDATE Aug 28 2021
Following the advice from contributors and with reference to the docs at https://learn.microsoft.com/en-us/xamarin/essentials/permissions?tabs=android#extending-permissions ...
In My Shared Code
public interface IRequestIgnoreBatteryOptimizationPermission
{
Task<PermissionStatus> CheckStatusAsync();
Task<PermissionStatus> RequestAsync();
}
In My Android Project
[assembly: Xamarin.Forms.Dependency(typeof(RequestIgnoreBatteryOptimizationPermission))]
namespace MyAndroidProject
{
public class RequestIgnoreBatteryOptimizationPermission : Permissions.BasePlatformPermission, IRequestIgnoreBatteryOptimizationPermission
{
public override (string androidPermission, bool isRuntime)[] RequiredPermissions => new List<(string androidPermission, bool isRuntime)>
{
(Android.Manifest.Permission.RequestIgnoreBatteryOptimizations, true)
}.ToArray();
}
}
On Shared App Initialization
// Ensure Required Permissions have been granted
var requestIgnoreBatteryOptimizationPermission = DependencyService.Get<IRequestIgnoreBatteryOptimizationPermission>();
var status = requestIgnoreBatteryOptimizationPermission.CheckStatusAsync().Result;
if (status != PermissionStatus.Granted)
{
status = requestIgnoreBatteryOptimizationPermission.RequestAsync().Result;
}
Result...
On calling CheckStatusAsync, the result comes back as Granted.
But the app settings still say otherwise...
I've tried it on both a physical device (Samsung Galaxy S20 Ultra) and on an Android Emulator (Pixel 2 API 28), with same result on both.
From this document, there are two ways to set Battery Optimization
An app can fire the ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS intent to take the user directly to the Battery Optimization, where they can add the app.
An app holding the REQUEST_IGNORE_BATTERY_OPTIMIZATIONS permission can trigger a system dialog to let the user add the app to the exemption list directly, without going to settings. The app fires a ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS Intent to trigger the dialog.
I use PowserManager.isIgnoringBatteryOptimizations to check Battery Optimization.
Firstly, add RequestIgnoreBatteryOptimizations in AndroidManifest.xml
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
Then creating Interface in Shared code.
public interface IBattery
{
void getbattery();
}
Implementing this interface in Android platform.
[assembly: Dependency(typeof(ImplementBattery))]
namespace FormsSample.Droid
{
public class ImplementBattery : IBattery
{
public void getbattery()
{
Intent intent = new Intent();
String packageName = MainActivity.mac.PackageName;
PowerManager pm = (PowerManager)MainActivity.mac.GetSystemService(Context.PowerService);
if (pm.IsIgnoringBatteryOptimizations(packageName))
intent.SetAction(Android.Provider.Settings.ActionIgnoreBatteryOptimizationSettings);
else
{
intent.SetAction(Android.Provider.Settings.ActionRequestIgnoreBatteryOptimizations);
intent.SetData(Android.Net.Uri.Parse("package:" + packageName));
}
MainActivity.mac.StartActivity(intent);
}
}
}
Creating static Mainactivity field in Mainactivity.cs.
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
public static MainActivity mac;
protected override void OnCreate(Bundle savedInstanceState)
{
initFontScale();
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(savedInstanceState);
mac = this;
Now, using DependencyService to fire.
private void Button_Clicked(object sender, EventArgs e)
{
DependencyService.Get<IBattery>().getbattery();
}
In your MainActivity add two properties:
private const int RequestPermissionsId = 0
and
private readonly string[] ManifestPermissions =
{
Manifest.Permission.RequestIgnoreBatteryOptimizations
// Add here other permissions you want to check
}
Then override the OnStart method and force permission check there:
public override void OnStart()
{
base.OnStart();
if ((int)Build.VERSION.SdkInt >= 23)
{
if (CheckSelfPermission(Manifest.Permission.RequestIgnoreBatteryOptimizations != Permission.Granted)
RequestPermissions(ManifestPermissions, RequestPermissionsId);
}
}
And of course, remember that you must have the OnRequestPermissionsResult method implemented:
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
Well, I am guessing you are trying to check it directly through shared code
The easiest way to do it would be to extend the needed permission in native using essentials.
Check the status and request permission through an interface:
public interface IRequestIgnoreBatteryOptimizations
{
Task<PermissionStatus> CheckStatusAsync();
Task<PermissionStatus> RequestAsync();
}
Implement the native part for the same:
public class IgnoreBatteryOptimizationsPlatformPermission : Xamarin.Essentials.Permissions.BasePlatformPermission, IRequestIgnoreBatteryOptimizations
{
public override (string androidPermission, bool isRuntime)[] RequiredPermissions =>
new (string, bool)[] { (Manifest.Permission.RequestIgnoreBatteryOptimizations, true) };
}
Then register it in your Native XF caller class(MainActivity, Appdelegate(for some other permission))
DependencyService.Register<IRequestIgnoreBatteryOptimizations, IgnoreBatteryOptimizationsPlatformPermission>();
And then in your XF class use this method:
public static async Task<PermissionStatus> CheckAndRequestBatteryOptimizations()
{
var batteryOptimizationsPermission = DependencyService.Get<IRequestIgnoreBatteryOptimizations>();
var status = await batteryOptimizationsPermission.CheckStatusAsync();
if (status != PermissionStatus.Granted)
{
status = await batteryOptimizationsPermission.RequestAsync();
}
return status;
}
And then request for it whenever you like:
var status= await CheckAndRequestBatteryOptimizations();
More information here: https://learn.microsoft.com/en-us/xamarin/essentials/permissions?tabs=android#extending-permissions
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.
The application runs but when i try to use the camera only a disturbed grey screen appears and the logs tab gives me two errors:
E/libc: Access denied finding property "vendor.camera.aux.packagelist"
Access denied finding property "vendor.camera.aux.packagelist2"
AndroidManifest.xml
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
build.gradle (Module:app)
apply plugin: 'com.android.application'
android {
compileSdkVersion 28
defaultConfig {
minSdkVersion 22
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:recyclerview-v7:28.0.0'
}
build.gradle(Project:camera)
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.4.0'
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
First, check your Android version. If it is running on Android 6.0 and higher (API level 23+), then you need to :
Declare a permission in the app manifest. Make sure to insert the permission above the application tag.
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<application ...>
...
</application>
Then, request that the user approve each permission at runtime
if (ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA) !=
PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.CAMERA},
50); }
I had this in my android manifest that prevented the app from using the camera.
android:hardwareAccelerated="false"
Removing it helped me.
Firstly, to check if it is a permission problem, go to the application manager of your phone, find your programme's name, and check the permission list. See if it is allowed to use the camera.
Secondly, open the XML of the layout where your "SurfaceView" resides, check if the "SurfaceView" node has the property "android:background". You must remove it if it is there. No idea why this is never mentioned.
<SurfaceView
android:layout_width="0dp"
android:layout_height="300dp" android:id="#+id/cameraPreview"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" android:background="#3F51B5"/>
Pay attention to the "android:background" in the above snippet. Remove it if you see it.
Thirdly, make sure you start the camera in the "surfaceCreated" event handler rather than anywhere else. You can't directly start the camera in "onViewCreated"!
Sample code just in case:
public void onViewCreated(#NonNull final View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
final CameraSource cameraSource = new CameraSource.Builder(getContext(), barcodeDetector)
.setRequestedPreviewSize(640, 480)
.setRequestedFps(10)
.setAutoFocusEnabled(true).build();
((SurfaceView) view.findViewById(R.id.cameraPreview)).getHolder().addCallback(new SurfaceHolder.Callback() {
#Override
public void surfaceCreated(SurfaceHolder holder) {
if(ContextCompat.checkSelfPermission(getContext(), Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.CAMERA}, 1);
}
try {
cameraSource.start(holder);
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
cameraSource.stop();
}
});
}
Reason: FileNotFoundException open failed: XXXXXXX EPERM (Operation not permitted)
Adding all the permissions still reports an error, mainly because the permissions requirements of the Android system are very strict.
It is recommended to change to:
ContextWrapper cw = new ContextWrapper(getApplicationContext());
File directory = cw.getExternalFilesDir(Environment.DIRECTORY_MUSIC);
File file = new File(directory, "something" + ".MP3");
public static String DIRECTORY_MUSIC = "Music";
public static String DIRECTORY_ALARMS = "Alarms";
public static String DIRECTORY_NOTIFICATIONS = "Notifications";
public static String DIRECTORY_PICTURES = "Pictures";
public static String DIRECTORY_MOVIES = "Movies";
public static String DIRECTORY_DOWNLOADS = "Download";
public static String DIRECTORY_DCIM = "DCIM";
public static String DIRECTORY_DOCUMENTS = "Documents";
If you are using a firebase plugin in your project, remove it. I was using the firebase crashlytics that camera prevents opening.
I am also seeing same error in my console when I am trying to open camera. However, it does not cause any other side effects.
I think it's best to ignore this error unless it stops app from running. or limits any functionality.
Found a post here that claims to resolve the issue by adding
<application>
<uses-library android:name="org.apache.http.legacy" android:required="false"/>
</application>
However, this did not work in my case. Testing on Mi Note 7
I too faced same error while implementing video capture option, this in my case due to missing Storage and Camera permissions.
Resolved using below code
if ((checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) || (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)) {
Log.d(TAG, "No camera and storage permission");
requestPermissions(new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}, MY_PERMISSIONS_REQUEST_CODE);
}
In my case, you must be following an android jetpack for a camera course in here [https://developer.android.com/codelabs/camerax-getting-started#0][1]
After that, change the companion object like this.
companion object {
private const val TAG = "CameraXBasic"
private const val FILENAME_FORMAT = "yyyy-MM-dd-HH-mm-ss-SSS"
private const val REQUEST_CODE_PERMISSIONS = 10
private val REQUIRED_PERMISSIONS = arrayOf(Manifest.permission.CAMERA)
}
Don't forget to add permission to access storage in the manifest.xml
In my case, the cause of the problem is that the surfaceTexture is available before the ui is not ready. To solve it, i add some delay (i don't know whether it is the correct solution or not, but it's working).
#Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int arg1, int arg2) {
mSurfaceTexture = surfaceTexture;
try {
Thread.sleep(200); // add some delay
} catch (InterruptedException e) {
e.printStackTrace();
}
cameraHelper.openCamera(mSurfaceTexture);
}
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);
}
}
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.