话不多说,直接上log:
07-24 21:29:44.385 24685 24685 E AndroidRuntime: FATAL EXCEPTION: main
07-24 21:29:44.385 24685 24685 E AndroidRuntime: Process: com.android.providers.calendar, PID: 24685
07-24 21:29:44.385 24685 24685 E AndroidRuntime: android.os.FileUriExposedException: file:///storage/emulated/0/calendar.db.zip exposed beyond app through ClipData.Item.getUri()
07-24 21:29:44.385 24685 24685 E AndroidRuntime: at android.os.StrictMode.onFileUriExposed(StrictMode.java:1965)
07-24 21:29:44.385 24685 24685 E AndroidRuntime: at android.net.Uri.checkFileUriExposed(Uri.java:2356)
07-24 21:29:44.385 24685 24685 E AndroidRuntime: at android.content.ClipData.prepareToLeaveProcess(ClipData.java:942)
07-24 21:29:44.385 24685 24685 E AndroidRuntime: at android.content.Intent.prepareToLeaveProcess(Intent.java:9850)
07-24 21:29:44.385 24685 24685 E AndroidRuntime: at android.content.Intent.prepareToLeaveProcess(Intent.java:9856)
07-24 21:29:44.385 24685 24685 E AndroidRuntime: at android.content.Intent.prepareToLeaveProcess(Intent.java:9835)
07-24 21:29:44.385 24685 24685 E AndroidRuntime: at android.app.Instrumentation.execStartActivity(Instrumentation.java:1610)
07-24 21:29:44.385 24685 24685 E AndroidRuntime: at android.app.Activity.startActivityForResult(Activity.java:4550)
07-24 21:29:44.385 24685 24685 E AndroidRuntime: at android.app.Activity.startActivityForResult(Activity.java:4505)
07-24 21:29:44.385 24685 24685 E AndroidRuntime: at com.android.providers.calendar.CalendarDebugActivity.emailFile(CalendarDebugActivity.java:196)
07-24 21:29:44.385 24685 24685 E AndroidRuntime: at com.android.providers.calendar.CalendarDebugActivity.-wrap0(Unknown Source:0)
07-24 21:29:44.385 24685 24685 E AndroidRuntime: at com.android.providers.calendar.CalendarDebugActivity$DumpDbTask.onPostExecute(CalendarDebugActivity.java:177)
07-24 21:29:44.385 24685 24685 E AndroidRuntime: at com.android.providers.calendar.CalendarDebugActivity$DumpDbTask.onPostExecute(CalendarDebugActivity.java:171)
07-24 21:29:44.385 24685 24685 E AndroidRuntime: at android.os.AsyncTask.finish(AsyncTask.java:695)
07-24 21:29:44.385 24685 24685 E AndroidRuntime: at android.os.AsyncTask.-wrap1(Unknown Source:0)
07-24 21:29:44.385 24685 24685 E AndroidRuntime: at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:712)
07-24 21:29:44.385 24685 24685 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:106)
07-24 21:29:44.385 24685 24685 E AndroidRuntime: at android.os.Looper.loop(Looper.java:164)
07-24 21:29:44.385 24685 24685 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:6550)
07-24 21:29:44.385 24685 24685 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
07-24 21:29:44.385 24685 24685 E AndroidRuntime: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
07-24 21:29:44.385 24685 24685 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:857)
07-24 21:29:44.388 879 5283 I am_crash: [24685,0,com.android.providers.calendar,814235205,android.os.FileUriExposedException,file:///storage/emulated/0/calendar.db.zip exposed beyond app through ClipData.Item.getUri(),StrictMode.java,1965]
07-24 21:29:44.398 29687 29700 W Monkey : // CRASH: com.android.providers.calendar (pid 24685)
07-24 21:29:44.398 29687 29700 W Monkey : // Short Msg: android.os.FileUriExposedException
07-24 21:29:44.399 29687 29700 W Monkey : // Long Msg: android.os.FileUriExposedException: file:///storage/emulated/0/calendar.db.zip exposed beyond app through ClipData.Item.getUri()
07-24 21:29:44.400 29687 29700 W Monkey : // Build Label: TCL/REVVL_2_5052W/A30ATMO:8.1.0/OPM1.171019.011/vAR2B-0:user/release-keys
07-24 21:29:44.400 29687 29700 W Monkey : // Build Changelist: vAR2B-0
07-24 21:29:44.401 29687 29700 W Monkey : // Build Time: 1531814111000
07-24 21:29:44.402 29687 29700 W Monkey : // android.os.FileUriExposedException: file:///storage/emulated/0/calendar.db.zip exposed beyond app through ClipData.Item.getUri()
07-24 21:29:44.402 29687 29700 W Monkey : // at android.os.StrictMode.onFileUriExposed(StrictMode.java:1965)
07-24 21:29:44.402 29687 29700 W Monkey : // at android.net.Uri.checkFileUriExposed(Uri.java:2356)
07-24 21:29:44.402 29687 29700 W Monkey : // at android.content.ClipData.prepareToLeaveProcess(ClipData.java:942)
07-24 21:29:44.402 29687 29700 W Monkey : // at android.content.Intent.prepareToLeaveProcess(Intent.java:9850)
07-24 21:29:44.402 29687 29700 W Monkey : // at android.content.Intent.prepareToLeaveProcess(Intent.java:9856)
07-24 21:29:44.402 29687 29700 W Monkey : // at android.content.Intent.prepareToLeaveProcess(Intent.java:9835)
07-24 21:29:44.402 29687 29700 W Monkey : // at android.app.Instrumentation.execStartActivity(Instrumentation.java:1610)
07-24 21:29:44.402 29687 29700 W Monkey : // at android.app.Activity.startActivityForResult(Activity.java:4550)
07-24 21:29:44.402 29687 29700 W Monkey : // at android.app.Activity.startActivityForResult(Activity.java:4505)
07-24 21:29:44.402 29687 29700 W Monkey : // at com.android.providers.calendar.CalendarDebugActivity.emailFile(CalendarDebugActivity.java:196)
07-24 21:29:44.402 29687 29700 W Monkey : // at com.android.providers.calendar.CalendarDebugActivity.-wrap0(Unknown Source:0)
07-24 21:29:44.402 29687 29700 W Monkey : // at com.android.providers.calendar.CalendarDebugActivity$DumpDbTask.onPostExecute(CalendarDebugActivity.java:177)
07-24 21:29:44.402 29687 29700 W Monkey : // at com.android.providers.calendar.CalendarDebugActivity$DumpDbTask.onPostExecute(CalendarDebugActivity.java:171)
07-24 21:29:44.402 29687 29700 W Monkey : // at android.os.AsyncTask.finish(AsyncTask.java:695)
07-24 21:29:44.402 29687 29700 W Monkey : // at android.os.AsyncTask.-wrap1(Unknown Source:0)
07-24 21:29:44.402 29687 29700 W Monkey : // at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:712)
07-24 21:29:44.402 29687 29700 W Monkey : // at android.os.Handler.dispatchMessage(Handler.java:106)
07-24 21:29:44.402 29687 29700 W Monkey : // at android.os.Looper.loop(Looper.java:164)
07-24 21:29:44.402 29687 29700 W Monkey : // at android.app.ActivityThread.main(ActivityThread.java:6550)
07-24 21:29:44.402 29687 29700 W Monkey : // at java.lang.reflect.Method.invoke(Native Method)
07-24 21:29:44.402 29687 29700 W Monkey : // at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
07-24 21:29:44.402 29687 29700 W Monkey : // at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:857)
07-24 21:29:44.402 29687 29700 W Monkey : //
07-24 21:29:44.404 879 5283 W ActivityManager: Force-killing crashed app com.android.providers.calendar at watcher's request
关于异常android.os.FileUriExposedException出现的原因及解决方式。
原因:Android developer上的介绍:
The exception that is thrown when an application exposes a file://
Uri
to another app.
当一个应用暴露一个file://的Uri给另外一个应用时这个异常就会被抛出。
This exposure is discouraged since the receiving app may not have access to the shared path. For example, the receiving app may not have requested the Manifest.permission.READ_EXTERNAL_STORAGE
runtime permission, or the platform may be sharing the Uri
across user profile boundaries.
由于接收应用程序可能无法访问共享路径,因此不鼓励这种暴露。
Instead, apps should use content://
Uris so the platform can extend temporary permission for the receiving app to access the resource.
相反,应用程序应该使用content:// uri,这样平台就可以扩展接收应用程序访问资源的临时权限。
This is only thrown for applications targeting Build.VERSION_CODES.N
or higher. Applications targeting earlier SDK versions are allowed to share file://
Uri
, but it's strongly discouraged.
只在大于N的Android版本上回抛出这个异常。
解决方案:使用content:// uri
具体解决过程:
1.在AndroidManifest.xml文件中注册一个FileProvider:
<provider
android:name="android.support.v4.content.FileProvider" //一般是固定写法
android:authorities="com.android.providers.calendar.fileProvider"//自己命名,一般是包名+fileProvider
android:exported="false" //必须设置为false,否则就exposed
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/calendar_file_paths" /> //共享文件的路径
</provider>
2.calendar_file_paths.xml文件:
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2017 Tcl Corporation Limited -->
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<root-path name="root_path" path="." /> //
</paths>
3.在java代码中:
import android.support.v4.content.FileProvider;
private void emailFile(File file) {
Log.i(TAG, "Drafting email to send " + file.getAbsolutePath());
//mengqin.zhang 08/03/2018 mod begin
Uri uri = FileProvider.getUriForFile(CalendarDebugActivity.this, "com.android.providers.calendar.fileProvider", file);
Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.debug_tool_email_subject));
intent.putExtra(Intent.EXTRA_TEXT, getString(R.string.debug_tool_email_body));
intent.setType(MIME_TYPE);
//intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));//注释掉之前的
intent.putExtra(Intent.EXTRA_STREAM, uri); //新加的
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
//mengqin.zhang 08/03/2018 mod end
startActivityForResult(Intent.createChooser(intent,
getString(R.string.debug_tool_email_sender_picker)), 0);
}
4.如果是进行mm编译的apk,看是否需要在Andorid.mk中添加:
LOCAL_STATIC_ANDROID_LIBRARIES := \
android-support-v4