Use FileProvider when sending intents with files.
Fixes:
AndroidRuntime: Process: com.google.android.tag, PID: 14951
AndroidRuntime: android.os.FileUriExposedException: file:///.. exposed beyond app through Intent.getData()
AndroidRuntime: at android.os.StrictMode.onFileUriExposed(StrictMode.java:1960)
AndroidRuntime: at android.net.Uri.checkFileUriExposed(Uri.java:2348)
AndroidRuntime: at android.content.Intent.prepareToLeaveProcess(Intent.java:9881)
AndroidRuntime: at android.content.Intent.prepareToLeaveProcess(Intent.java:9835)
AndroidRuntime: at android.app.Instrumentation.execStartActivity(Instrumentation.java:1610)
AndroidRuntime: at android.app.Activity.startActivityForResult(Activity.java:4487)
Test: Read tag with file based Uri
Bug: 72087046
Change-Id: I4094b8dd2c1653f6ce9e1d94b1e718edf6d10d7c
(cherry picked from commit 7b4591e6be1856765dd8824878e377236eacfbc5)
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 09421dd..67225c5 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -24,6 +24,7 @@
<uses-permission android:name="android.permission.NFC" />
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.WAKE_LOCK" />
+ <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-feature android:name="android.hardware.nfc" required="true" />
@@ -51,5 +52,15 @@
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
+ <!-- Declare file provider to convert file:/// to content:// for file preview -->
+ <provider
+ android:name="android.support.v4.content.FileProvider"
+ android:authorities="com.android.apps.tag.provider"
+ android:exported="false"
+ android:grantUriPermissions="true">
+ <meta-data
+ android:name="android.support.FILE_PROVIDER_PATHS"
+ android:resource="@xml/provider_paths"/>
+ </provider>
</application>
</manifest>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 7ae9925..9817b4b 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -55,4 +55,7 @@
<!-- Description string for CALL_PHONE permission denied -->
<string name="call_phone_permission_denied">This application needs to access Telephone permission in order to make calls. You can manage Tag permission in Settings</string>
+ <!-- Description string for READ_EXTERNAL_STORAGE permission denied -->
+ <string name="external_storage_permission_denied">This application needs to access External Storage permission in order to access files. You can manage Tag permission in Settings</string>
+
</resources>
diff --git a/res/xml/provider_paths.xml b/res/xml/provider_paths.xml
new file mode 100644
index 0000000..4ff8931
--- /dev/null
+++ b/res/xml/provider_paths.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<paths xmlns:android="http://schemas.android.com/apk/res/android">
+ <external-path name="external_files" path="."/>
+</paths>
diff --git a/src/com/android/apps/tag/record/UriRecord.java b/src/com/android/apps/tag/record/UriRecord.java
index 2dca5e1..1be9b45 100644
--- a/src/com/android/apps/tag/record/UriRecord.java
+++ b/src/com/android/apps/tag/record/UriRecord.java
@@ -35,6 +35,7 @@
import android.os.Parcel;
import android.os.Parcelable;
import android.support.v4.app.ActivityCompat;
+import android.support.v4.content.FileProvider;
import android.telephony.PhoneNumberUtils;
import android.text.TextUtils;
import android.util.Log;
@@ -46,6 +47,7 @@
import android.widget.TextView;
import android.widget.Toast;
+import java.io.File;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.List;
@@ -114,6 +116,13 @@
return;
}
try {
+ if (mUri.getScheme().equalsIgnoreCase("file")) {
+ Uri uri = FileProvider.getUriForFile(info.activity,
+ "com.android.apps.tag.provider", new File(mUri.getPath()));
+ Intent intent = new Intent(Intent.ACTION_VIEW, uri);
+ intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ info.intent = intent;
+ }
info.activity.startActivity(info.intent);
info.activity.finish();
} catch (ActivityNotFoundException e) {
@@ -164,6 +173,14 @@
activity.requestPermissions(new String[]{Manifest.permission.CALL_PHONE}, 1);
}
}
+
+ if (mUri != null && mUri.getScheme().equalsIgnoreCase("file") &&
+ activity.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
+ if (!ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.READ_EXTERNAL_STORAGE))
+ Toast.makeText(activity.getApplicationContext(), R.string.external_storage_permission_denied, Toast.LENGTH_SHORT).show();
+ needRequestPermission = true;
+ activity.requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 1);
+ }
return needRequestPermission;
}
}