Report Crash android.os.FileUriExposedException on Android N

1

With the update of the google play console I get the error reports.

Apparently only affects the version of Android 7 (Android N)

java.lang.RuntimeException: 
  at android.app.ActivityThread.deliverResults(ActivityThread.java:4525)
  at android.app.ActivityThread.handleSendResult(ActivityThread.java:4568)
  at android.app.ActivityThread.-wrap22(ActivityThread.java:0)
  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1706)
  at android.os.Handler.dispatchMessage(Handler.java:102)
  at android.os.Looper.loop(Looper.java:154)
  at android.app.ActivityThread.main(ActivityThread.java:6688)
  at java.lang.reflect.Method.invoke(Native Method:0)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358)
Caused by: android.os.FileUriExposedException: 
  at android.os.StrictMode.onFileUriExposed(StrictMode.java:1799)
  at android.net.Uri.checkFileUriExposed(Uri.java:2346)
  at android.content.Intent.prepareToLeaveProcess(Intent.java:9510)
  at android.content.Intent.prepareToLeaveProcess(Intent.java:9468)
  at android.app.Instrumentation.execStartActivity(Instrumentation.java:1525)
  at android.app.Activity.startActivityForResult(Activity.java:4389)
  at android.support.v4.app.BaseFragmentActivityJB.startActivityForResult(BaseFragmentActivityJB.java:48)
  at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:75)
  at android.app.Activity.startActivityForResult(Activity.java:4348)
  at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:871)
  at android.app.Activity.startActivity(Activity.java:4672)
  at android.app.Activity.startActivity(Activity.java:4640)
  at pro.caminsderonda.app.caminsderonda.DetailedActivity.openTrackKML(DetailedActivity.java:592)
  at pro.caminsderonda.app.caminsderonda.DetailedActivity.onRequestPermissionsResult(DetailedActivity.java:563)
  at android.app.Activity.dispatchRequestPermissionsResult(Activity.java:7404)
  at android.app.Activity.dispatchActivityResult(Activity.java:7230)
  at android.app.ActivityThread.deliverResults(ActivityThread.java:4521)

Searching for more information on FileUriExposedException

The exception jumps when I open a file .kml with an external application to my app, that is, through an intent.

private void openTrackKML() {
    try {
        String fileName = myItem.getTrackURI();
                /*int pos = fileName.lastIndexOf(".");
                if (pos > 0) {
                    fileName = fileName.substring(0, pos);
                }*/

        //int idTrackResource = this.getResources().getIdentifier("raw/" +fileName,"id",this.getPackageName());

        ByteArrayOutputStream byteArrayOutputStream = FileDirUtils.readFileFromAssets(this, fileName);
        FileDirUtils.saveExternalFile(byteArrayOutputStream, "temp_track.kml");

        Log.d(TAG, "id Track Rresource: " + String.valueOf(fileName));

        File file = new File(Environment.getExternalStorageDirectory(), "temp_track.kml");
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setDataAndType(Uri.fromFile(file), "application/vnd.google-earth.kml+xml");
        startActivity(intent);

                /*//Open by url
                Uri uri = Uri.parse(myItem.getTrackURI());
                Log.d(TAG, "action_gotrack click()" + uri.toString());
                if (URLUtil.isValidUrl(uri.toString())) {
                    //startActivity( new Intent(Intent.ACTION_VIEW, uri));
                }*/
    } catch (ActivityNotFoundException e) {
        Snackbar.make(getWindow().getDecorView(), getString(R.string.detailed_warning_install_kml_viewer), Snackbar.LENGTH_LONG)
                .setAction("Action", null).show();
    }

}

Write permissions, I also ask for them in runtime

<uses-permission
    android:name="android.permission.INTERNET"
    android:required="false" />
<uses-permission
    android:name="android.permission.WRITE_EXTERNAL_STORAGE"
    android:required="false" />
<uses-permission
    android:name="android.permission.READ_EXTERNAL_STORAGE"
    android:required="false" />

Testing in the emulator, because I do not have Android N device returns me

  android.os.FileUriExposedException: file:///storage/emulated/0/temp_track.kml exposed beyond app through Intent.getData()
      at android.os.StrictMode.onFileUriExposed(StrictMode.java:1799)
      at android.net.Uri.checkFileUriExposed(Uri.java:2346)
      at android.content.Intent.prepareToLeaveProcess(Intent.java:8933)
      at android.content.Intent.prepareToLeaveProcess(Intent.java:8894)
      at android.app.Instrumentation.execStartActivity(Instrumentation.java:1517)
      at android.app.Activity.startActivityForResult(Activity.java:4224)
      at android.support.v4.app.BaseFragmentActivityJB.startActivityForResult(BaseFragmentActivityJB.java:50)
      at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:79)
      at android.app.Activity.startActivityForResult(Activity.java:4183)
      at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:859)
      at android.app.Activity.startActivity(Activity.java:4507)
      at android.app.Activity.startActivity(Activity.java:4475)
      at pro.caminsderonda.app.caminsderonda.DetailedActivity.openTrackKML(DetailedActivity.java:592)
      at pro.caminsderonda.app.caminsderonda.DetailedActivity.processActionOption(DetailedActivity.java:504)
      at pro.caminsderonda.app.caminsderonda.DetailedActivity.access$000(DetailedActivity.java:57)
      at pro.caminsderonda.app.caminsderonda.DetailedActivity$1.onClick(DetailedActivity.java:109)
      at android.view.View.performClick(View.java:5610)
      at android.view.View$PerformClick.run(View.java:22265)
      at android.os.Handler.handleCallback(Handler.java:751)
      at android.os.Handler.dispatchMessage(Handler.java:95)
      at android.os.Looper.loop(Looper.java:154)
      at android.app.ActivityThread.main(ActivityThread.java:6077)
      at java.lang.reflect.Method.invoke(Native Method)
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
    
asked by Webserveis 19.05.2017 в 19:54
source

1 answer

3

This error FileUriExposedException is generated as you have already explained in Android N :

Now you have to make a change when you get the Uri of the file by:

imageUri = Uri.parse(filepath);

example:

     if (Build.VERSION.SDK_INT >=  Build.VERSION_CODES.N) {
              imageUri = Uri.parse(filepath);
        } else{
               imageUri = Uri.fromFile(new File(filepath));
        }

In your code it would be:

if (Build.VERSION.SDK_INT >=  Build.VERSION_CODES.N) {                
    intent.setDataAndType(Uri.parse(Environment.getExternalStorageDirectory() + "temp_track.kml"), "application/vnd.google-earth.kml+xml");        
} else{
    intent.setDataAndType(Uri.fromFile(new File(Environment.getExternalStorageDirectory() + "temp_track.kml"), "application/vnd.google-earth.kml+xml");
}

Another solution is to change the targetSdkVersion to a version smaller than 24 (Android N)

It is similar to the problem in this question:

Problem when opening the camera in Android application

    
answered by 19.05.2017 / 20:13
source