8

In my app the user has the ability to take a photo or add a photo to the app. I'm getting crash reports of java.lang.SecurityException when the app tries to display the saved image in a ImageView

The line it errors on is

holder.imageV.setImageURI(uriParsed);

I've been unable to duplicate the error myself on either my device or on simulators, they all display the image fine.

The full code I'm using is

JoinProjectPicture projectPicture = mProjects.get(position);
Project current = projectPicture.getProject();
Picture picture = projectPicture.getPicture();

 holder.projectName.setText(current.getProjectName() + "(" + current.getWidth() + "x" + current.getHeight() + ")");
 holder.projectStatusTV.setText(current.getStatus());

 if(picture != null) {
      String pictureName = picture.getPictureName();
      Uri uriParsed = Uri.parse(pictureName);

      if(uriParsed != null) {
           Log.d("URIParsed", "Project: " + current.getProjectName() + " - Parsed: " + uriParsed);
           holder.imageV.setImageURI(uriParsed);
    }
}

The output from the logs showing on my device ( 3 projects, one without an image)

Project: Test - Parsed: file:///storage/emulated/0/Android/data/com.desbrina.diamondpaintinglogbook/files/Pictures/20191111_1408166491573472523237896.jpg

Project: Test 3 - Parsed: content://com.android.providers.media.documents/document/image%3A1891

The error

java.lang.SecurityException: 
  at android.os.Parcel.createException (Parcel.java:1966)
  at android.os.Parcel.readException (Parcel.java:1934)
  at android.os.Parcel.readException (Parcel.java:1884)
  at android.app.IActivityManager$Stub$Proxy.getContentProvider (IActivityManager.java:4039)
  at android.app.ActivityThread.acquireProvider (ActivityThread.java:6365)
  at android.app.ContextImpl$ApplicationContentResolver.acquireUnstableProvider (ContextImpl.java:2825)
  at android.content.ContentResolver.acquireUnstableProvider (ContentResolver.java:1835)
  at android.content.ContentResolver.openTypedAssetFileDescriptor (ContentResolver.java:1449)
  at android.content.ContentResolver.openAssetFileDescriptor (ContentResolver.java:1302)
  at android.content.ContentResolver.openAssetFileDescriptor (ContentResolver.java:1225)
  at android.graphics.ImageDecoder$ContentResolverSource.createImageDecoder (ImageDecoder.java:273)
  at android.graphics.ImageDecoder.decodeDrawableImpl (ImageDecoder.java:1652)
  at android.graphics.ImageDecoder.decodeDrawable (ImageDecoder.java:1645)
  at android.widget.ImageView.getDrawableFromUri (ImageView.java:952)
  at android.widget.ImageView.resolveUri (ImageView.java:921)
  at android.widget.ImageView.setImageURI (ImageView.java:532)
  at android.support.v7.widget.AppCompatImageView.setImageURI (AppCompatImageView.java:116)
  at com.desbrina.diamondpaintinglogbook.ui.main.Adapters.ProjectListAdapter.onBindViewHolder (ProjectListAdapter.java:88)
  at com.desbrina.diamondpaintinglogbook.ui.main.Adapters.ProjectListAdapter.onBindViewHolder (ProjectListAdapter.java:23)
  at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder (RecyclerView.java:6781)
  at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder (RecyclerView.java:6823)
  at android.support.v7.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline (RecyclerView.java:5752)
  at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline (RecyclerView.java:6019)
  at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition (RecyclerView.java:5858)
  at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition (RecyclerView.java:5854)
  at android.support.v7.widget.LinearLayoutManager$LayoutState.next (LinearLayoutManager.java:2230)
  at android.support.v7.widget.LinearLayoutManager.layoutChunk (LinearLayoutManager.java:1557)
  at android.support.v7.widget.LinearLayoutManager.fill (LinearLayoutManager.java:1517)
  at android.support.v7.widget.LinearLayoutManager.onLayoutChildren (LinearLayoutManager.java:612)
  at android.support.v7.widget.RecyclerView.dispatchLayoutStep2 (RecyclerView.java:3924)
  at android.support.v7.widget.RecyclerView.dispatchLayout (RecyclerView.java:3641)
  at android.support.v7.widget.RecyclerView.onLayout (RecyclerView.java:4194)
  at android.view.View.layout (View.java:22406)
  at android.view.ViewGroup.layout (ViewGroup.java:6594)
  at android.support.constraint.ConstraintLayout.onLayout (ConstraintLayout.java:1915)
  at android.view.View.layout (View.java:22406)
  at android.view.ViewGroup.layout (ViewGroup.java:6594)
  at android.support.v4.view.ViewPager.onLayout (ViewPager.java:1775)
  at android.view.View.layout (View.java:22406)
  at android.view.ViewGroup.layout (ViewGroup.java:6594)
  at android.widget.LinearLayout.setChildFrame (LinearLayout.java:1812)
  at android.widget.LinearLayout.layoutVertical (LinearLayout.java:1656)
  at android.widget.LinearLayout.onLayout (LinearLayout.java:1565)
  at android.view.View.layout (View.java:22406)
  at android.view.ViewGroup.layout (ViewGroup.java:6594)
  at android.widget.FrameLayout.layoutChildren (FrameLayout.java:323)
  at android.widget.FrameLayout.onLayout (FrameLayout.java:261)
  at android.view.View.layout (View.java:22406)
  at android.view.ViewGroup.layout (ViewGroup.java:6594)
  at android.widget.LinearLayout.setChildFrame (LinearLayout.java:1812)
  at android.widget.LinearLayout.layoutVertical (LinearLayout.java:1656)
  at android.widget.LinearLayout.onLayout (LinearLayout.java:1565)
  at android.view.View.layout (View.java:22406)
  at android.view.ViewGroup.layout (ViewGroup.java:6594)
  at android.widget.FrameLayout.layoutChildren (FrameLayout.java:323)
  at android.widget.FrameLayout.onLayout (FrameLayout.java:261)
  at android.view.View.layout (View.java:22406)
  at android.view.ViewGroup.layout (ViewGroup.java:6594)
  at android.widget.LinearLayout.setChildFrame (LinearLayout.java:1812)
  at android.widget.LinearLayout.layoutVertical (LinearLayout.java:1656)
  at android.widget.LinearLayout.onLayout (LinearLayout.java:1565)
  at android.view.View.layout (View.java:22406)
  at android.view.ViewGroup.layout (ViewGroup.java:6594)
  at android.widget.FrameLayout.layoutChildren (FrameLayout.java:323)
  at android.widget.FrameLayout.onLayout (FrameLayout.java:261)
  at com.android.internal.policy.DecorView.onLayout (DecorView.java:1088)
  at android.view.View.layout (View.java:22406)
  at android.view.ViewGroup.layout (ViewGroup.java:6594)
  at android.view.ViewRootImpl.performLayout (ViewRootImpl.java:3417)
  at android.view.ViewRootImpl.performTraversals (ViewRootImpl.java:2884)
  at android.view.ViewRootImpl.doTraversal (ViewRootImpl.java:1932)
  at android.view.ViewRootImpl$TraversalRunnable.run (ViewRootImpl.java:8589)
  at android.view.Choreographer$CallbackRecord.run (Choreographer.java:949)
  at android.view.Choreographer.doCallbacks (Choreographer.java:761)
  at android.view.Choreographer.doFrame (Choreographer.java:696)
  at android.view.Choreographer$FrameDisplayEventReceiver.run (Choreographer.java:935)
  at android.os.Handler.handleCallback (Handler.java:873)
  at android.os.Handler.dispatchMessage (Handler.java:99)
  at android.os.Looper.loop (Looper.java:214)
  at android.app.ActivityThread.main (ActivityThread.java:7094)
  at java.lang.reflect.Method.invoke (Native Method)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:494)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:975)
Caused by: android.os.RemoteException: 
  at com.android.server.am.ActivityManagerService.getContentProviderImpl (ActivityManagerService.java:15677)
  at com.android.server.am.ActivityManagerService.getContentProviderImpl (ActivityManagerService.java:15586)
  at com.android.server.am.ActivityManagerService.getContentProvider (ActivityManagerService.java:16151)
  at android.app.IActivityManager$Stub.onTransact$getContentProvider$ (IActivityManager.java:11035)
  at android.app.IActivityManager$Stub.onTransact (IActivityManager.java:295)
Community
  • 1
  • 1
Ceri Turner
  • 830
  • 2
  • 12
  • 36
  • Have you tried to build, an obfuscated, release version of your app and test? Does it work? – Sagar Nov 16 '19 at 15:03
  • can you post full error log. Are you using uri from your phone storage? – Amit Tiwary Nov 16 '19 at 16:05
  • IT will be from either the phone storage, or from within the app, depending on if it was added from the gallery or taken form the camera in app. Full crash added – Ceri Turner Nov 16 '19 at 16:11
  • 1
    Check that the following are satisfied: Write permissions, and that you have a file provider if you are saving to a custom internal path. – TheRealChx101 Nov 20 '19 at 10:02
  • You are saying that you tried the code on emulators. I'd recommend to test such hardware related code on nearly every Android Version. Have you tried it on Android Pie, like the answers below suggest? – L3n95 Nov 20 '19 at 10:12
  • You're probably trying to access data from a third party app. – Taslim Oseni Nov 24 '19 at 19:56
  • I’m trying to access from the photos app – Ceri Turner Nov 24 '19 at 20:21
  • Look at here may be it would help you https://medium.com/@egemenhamutcu/fixing-securityexception-requiring-a-valid-contentprovider-on-android-8-1110d840522 – King of Masses Nov 25 '19 at 12:21

5 Answers5

4

I think you are getting the Security exception on an Android Pie or later operating system. This is because on these systems you have to declare the path that your app wants to use.

Please check: https://developer.android.com/reference/android/support/v4/content/FileProvider

Additionally, it is possible that your app is trying to get content from another app that requires permission like Google Photos requires: <uses-permission android:name="com.google.android.apps.photos.permission.GOOGLE_PHOTOS"/>

Check this: java.lang.SecurityException: Permission Denial: opening provider com.google.android.apps.photos.content.GooglePhotosImageProvider

Vatish Sharma
  • 1,536
  • 3
  • 16
  • 35
  • I’m getting it on 9, but I’m running 10 and can’t reproduce it myself. I’ve tried to reproduce it on a 9 similarly or and couldn’t – Ceri Turner Nov 20 '19 at 13:08
  • I get this error when trying to fire an intent to third-party(it was google photos in my case) gallery app to let choose a photo for my app. So probably you also need an app that needs permission before giving an intent to it. – Vatish Sharma Nov 20 '19 at 13:29
  • I've added that and it still crashes – Ceri Turner Nov 23 '19 at 16:46
4

From Api 24, you can not access the File Uris directly. You need to use File authorities for the folder and then use

val photoURI = FileProvider.getUriForFile(activity, BuildConfig.APPLICATION_ID + ".provider", File(path));

In AndroidManifes.xml

Add the following to application tag. In following packagename is BuildConfig.APPLICATION_ID

<provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="packagename.provider"
            android:enabled="true"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths" />
        </provider>

provider_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path
        name="external"
        path="." />
</paths>
Mustansar Saeed
  • 2,730
  • 2
  • 22
  • 46
3

This Exception usually is caused by using imageuri from third party app.Solution is to implement file provider.You can get many solution on how to implement fileprovider.

AkashToSky
  • 107
  • 1
  • 11
2

This is because at the new version Android 9 introduced a new FOREGROUND_SERVICE permission; the docs say:

Note: Apps that target Android 9 (API level 28) or higher and use foreground services must request the FOREGROUND_SERVICE permission. This is a normal permission, so the system automatically grants it to the requesting app. If an app that targets API level 28 or higher attempts to create a foreground service without requesting FOREGROUND_SERVICE, the system throws a SecurityException.

Just add the permission to the manifest and should do the trick, "in theory". Let us know!! Something like:

<manifest ...>   
     <uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> 
     <application ...>
</manifest>

Let´s try to take that bounty: Do you hace these permission?:

<uses-permission android:name="android.permission.MANAGE_DOCUMENTS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

Also I think this is not too bad to try:

public static final String KITKAT_VALUE = 1002;

  Intent intent;

    if (Build.VERSION.SDK_INT < 19){
                            intent = new Intent();
                            intent.setAction(Intent.ACTION_GET_CONTENT);
                            intent.setType("image/*");
                            startActivityForResult(intent, KITKAT_VALUE);
                        } else {
                            intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
                            intent.addCategory(Intent.CATEGORY_OPENABLE);
                            intent.setType("image/*");
                            startActivityForResult(intent, KITKAT_VALUE);
                    }

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
   if (requestCode == KITKAT_VALUE ) {
     if (resultCode == Activity.RESULT_OK) {
       // do something here
     }
  }
}
Qiqke
  • 486
  • 5
  • 19
  • 1
    I’ve had a quick look at the information and not sure how it applies – Ceri Turner Nov 20 '19 at 13:15
  • Don´t you have a file called `AndroidManifest.xml` where you place all the permissions like : ` ` – Qiqke Nov 20 '19 at 15:54
  • I've added that and it still crashes – Ceri Turner Nov 23 '19 at 16:46
  • Are you using a third app service??? maybe that 3th is using some permissions that are not able to use? – Qiqke Nov 24 '19 at 12:48
  • The 3rd party app it accesses is the phones photo app. The only thing I can think of is I changed the way it accessed it a while ago and I'm wondering if the permissions were never set to keep access. Newly added images from photos work, but it appears older ones don't. This is how the images are added: https://pastebin.com/5CcqXQQu – Ceri Turner Nov 24 '19 at 15:31
  • Check my answer and hope it helps! – Qiqke Nov 26 '19 at 11:04
2

I suspect this is down to the permissions you've implemented in your AndroidManifest.xml file. If you are debugging on API Level 23 or higher version of android then you have to take the runtime permission for WRITE_EXTERNAL_STORAGE at runtime as Security exception occurs due to permission denied by device.

Omkar C.
  • 755
  • 8
  • 21