1.点击item,通过intent打开指定路径的图片。

2.测试6.0,5.0正常运行代码

File file=new File(item.address);

Intent intent = new Intent("android.intent.action.VIEW");
intent.addCategory("android.intent.category.DEFAULT"); intent.addFlags (Intent.FLAG_ACTIVITY_NEW_TASK); Uri uri = Uri.fromFile(new File(item.address)); intent.setDataAndType (uri, "image/*"); startActivity(intent);

  

3.在7.0上运行报错。

com.aolian.mychezai, PID: 3881
android.os.FileUriExposedException: file:///storage/emulated/0/AA/17-03-01%2009-31-08%202335-01%E7%AB%AF%20B%E7%B3%BB%20STU-V-N-LOG.txt exposed beyond app through Intent.getData()
at android.os.StrictMode.onFileUriExposed(StrictMode.java:1816)
at android.net.Uri.checkFileUriExposed(Uri.java:2350)
at android.content.Intent.prepareToLeaveProcess(Intent.java:9076)
at android.content.Intent.prepareToLeaveProcess(Intent.java:9037)
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1530)
at android.app.Activity.startActivityForResult(Activity.java:4391)
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:4335)
at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:859)
at android.app.Activity.startActivity(Activity.java:4697)
at android.app.Activity.startActivity(Activity.java:4665)
at com.aolian.mychezai.view.FileManagerActivity$7.onItemLongClick(FileManagerActivity.java:377)
at android.widget.AbsListView.performLongPress(AbsListView.java:3298)
at android.widget.AbsListView$CheckForLongPress.run(AbsListView.java:3215)
at android.os.Handler.handleCallback(Handler.java:755)

  

4. 从Android 7.0开始,一个应用提供自身文件给其它应用使用时,如果给出一个file://格式的URI的话,应用会抛出FileUriExposedException。这是由于谷歌认为目标app可能    不具有文件权限,会造成潜在的问题。所以让这一行为快速失败。详见这里。这里讨论两种解决方式。

http://blog.csdn.net/xiaoyu940601/article/details/54406725

<1> FileProvider方式

(1) manifest声明 
在manifest中声明一个provider。name(即类名)为android.support.v4.content.FileProvider。(红色为应用包名)

<manifest>
...
<application>
...
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.aolian.mychezai.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
... </application> </manifest>

  

其中authorities可以自定义。为了避免和其它app冲突,最好带上自己app的包名。file_paths.xml中编写该Provider对外提供文件的目录。文件放置在res/xml/下。 

(2)编写file_paths.xml  里面的external-path 对应是sdcard路径下的

<paths xmlns:android="http://schemas.android.com/apk/res/android">
<files-path name="my_images" path="images/"/>
...
</paths>

  

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="my_images" path="AA/"/> </paths>

  

内部的element可以是files-path,cache-path,external-path,external-files-path,external-cache-path,分别对应Context.getFilesDir(),Context.getCacheDir(),Environment.getExternalStorageDirectory(),Context.getExternalFilesDir(),Context.getExternalCacheDir()等几个方法。后来翻看源码发现还有一个没有写进文档的,但是也可以使用的element,是root-path,直接对应文件系统根目录。不过既然没有写进文档中,其实还是有将来移除的可能的。使用的话需要注意一下风险。

(3)在Java代码当中使用 以分享一个图片为例:

File file = ...;    //要分享的图片文件
Uri uri = FileProvider.getUriForFile(context, "com.mydomain.fileprovider", file); //第二个参数是manifest中定义的`authorities`
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("image/*");
intent.putExtra(Intent.EXTRA_TITLE, title);
intent.putExtra(Intent.EXTRA_TEXT, text);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); //这一步很重要。给目标应用一个临时的授权。
startActivity(intent); //或者其它最

  

2 VmPolicy方式

以上方法固然是推荐使用的,正确的方法。但是我在实际开发中遇到这样的问题。某些应用(此处点名新浪微博)根本无法理解一个指向文件的content://格式的URI。新浪微博接收到这类URI之后,无法加载图片,并会在点击发送微博时崩溃。 
另一方面,新浪微博对权限管理的处理采取了一种比较流氓的方式。它会在启动时申请文件读写权限,而如果拒绝该权限的话,居然就直接退出了。我反正是不信什么需要文件权限来放缓存放数据的说辞。放缓存放数据有着一堆不需要权限的目录可用。但是这样一来,我们其实是不需要担心传递一个file://格式URI过去而对方没有权限的。 
话说回来,如何解决这一问题呢?我在调研的时候观察到严格模式的一个方法:StrictMode.VmPolicy.Builder.detectFileUriExposure()。顾名思义,调用这个方法就会检测FileUriExposure这件事。这个方法其实从API18就有了,是不是有可能在API24变成了默认选项呢? 
在Application.onCreate加入如下代码,置入一个不设防的VmPolicy:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
}

  

再用旧的方式直接把file://格式的URI发送出去。没有再抛出FileUriExposedException。

-----

5.进入读取文件时 报错显示权限拒绝问题。

Caused by: android.database.sqlite.SQLiteCantOpenDatabaseException: 
unknown error (Sqlite code 14): Could not open database, (OS error - 13:Permission denied)
at android.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:219)
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:203)

  

出现这种问题一般都是6.0以上需要动态申请权限。

Android7.0打开sdacrd图片问题的更多相关文章

  1. 拍照、本地图片工具类(兼容至Android7.0)

    拍照.本地图片工具类:解决了4.4以上剪裁会提示"找不到文件"和6.0动态授予权限,及7.0报FileUriExposedException异常问题. package com.hb ...

  2. Android7.0新特性,及Android N适配

    新特性部分 Android 7.0 Nougat 提供新功能以提升性能.生产效率和安全性,主要新增了下面的新特性和优化: 一.新的Notification Android N 添加了很多新的notif ...

  3. Appium适配Android7.0以上版本

    Appium适配Android7.0以上版本 测试机型: 华为荣耀V9 安卓版本: Android7.0 appium版本: 1.65 说明: 公司新采购了一批安卓机器,拿了其中一台华为荣耀V9跑之前 ...

  4. Android7.0 多窗口你值得拥有

    Android7.0 多窗口你值得拥有 什么是多窗口分屏? 多窗口分屏其实在国内并不陌生,已经有一些手机和平板搭载了"分屏多任务"和"APP窗口化"功能,但这些 ...

  5. Appium在Android7.0及以上系统运行时报错的解决方案

    背景:在使用Samsung S系列手机进行自动化测试时,发现同样脚本的情况下华为荣耀系列可以正常运行,最终发现差异在于Android7.0及以上系统和appium版本不匹配,需要升级appium.但需 ...

  6. 【转】Android7.0适配心得

    本文出自:贾鹏辉的技术博客(http://www.devio.org) http://www.devio.org/2016/09/28/Android7.0%E9%80%82%E9%85%8D%E5% ...

  7. Android7.0调用系统相机拍照、读取系统相册照片+CropImageView剪裁照片

    Android手机拍照.剪裁,并非那么简单 简书地址:[我的简书–T9的第三个三角] 前言 项目中,基本都有用户自定义头像或自定义背景的功能,实现方法一般都是调用系统相机–拍照,或者系统相册–选择照片 ...

  8. 工具软件 PYUV打开raw图片

    引自:http://blog.csdn.net/lavenderss/article/details/51495648 [pYUV]如何打开YUV/RGB图片 pYUV工具本身使用起来比较简单,但如果 ...

  9. Android7.0 Doze模式分析(一)Doze介绍 &amp; DeviceIdleController

     參考:http://blog.csdn.net/gaugamela/article/details/52981984 在Android M中.Google就引入了Doze模式.它定义了一种全新的 ...

随机推荐

  1. Ruby. Vs . Python

    前言:从语言的本质上来分析,我对Ruby持反对态度,毕竟语言是为了交流,在表达的效率层面为了正确性必须适当放弃复杂性.且有句老话说的好,Ruby In Rails 才是语言,而Ruby只是这个语言的工 ...

  2. vc++元文件的保存,保存图形,重绘图形

    1, CMateFileDC 可以用来多次打开自己的画布,这个元文件包含许多接口的命令 当绘制好之后可以用来播放元文件 首先,创建一个CMateFileDC的元文件对象 然后调用Create原函数,创 ...

  3. spring重点一:处理对象创建时间 个数以及方式

    /** * 1) 对象创建: 单例/多例(个数) * scope="singleton", 默认值, 即 默认是单例 [service/dao/工具类] *  scope=&quo ...

  4. iOS runLoop 原理多线程 总结 NSTimer优化

    可以理解为字面意思:Run 表示运行,Loop 表示循环.结合在一起就是运行的循环的意思.哈哈,我更愿意翻译为『跑圈』.直观理解就像是不停的跑圈. RunLoop 实际上是一个对象,这个对象在循环中用 ...

  5. K3 新单到老单关联字段的添加

    新单到老单字段的添加分为两种: 一种为文本字段信息的关联,新单与老单字段的信息均为文本字段: 另一种为基础资料信息的关联,新单与老单均为基础资料字段信息.       K3 WISE 11.0中存储老 ...

  6. HDU-1695 GCD(求一个区间内与一个数互质的个数)

    题意: 给你一个T,是样例的个数,接下来是五个数l1,r1,l2,r2,k  前四个数代表两个区间(l1,r1),(l2,r2)这个题l1=1,l2=1; 取x1属于(1,r1),x2属于(1,r2) ...

  7. 找不到javax.servlet.http.HttpServletResponse和javax.servlet.http.HttpServletRequest

    导了个项目进eclipse,发现很多文件都报了错,错误提示是没有引入javax.servlet.http.HttpServletRequest和javax.servlet.http.HttpServl ...

  8. 做支付遇到的HttpClient大坑

    前言 HTTPClient大家应该都很熟悉,一个很好的抓网页,刷投票或者刷浏览量的工具.但是还有一项非常重要的功能就是外部接口调用,比如说发起微信支付,支付宝退款接口调用等:最近我们在这个工具上栽了一 ...

  9. robot Framework选择单选框

  10. 工具-常用VS插件

    工欲善其事,必先利其器,没有好的工具,怎么能高效的开发出高质量的代码呢?本文为各ASP.NET 开发者介绍一些高效实用的工具,涉及SQL 管理,VS插件,内存管理,诊断工具等,涉及开发过程的各个环节, ...