关于dom.4j读取安卓本地文件不能打开问题:org.dom4j.DocumentException: Couldn't open /storage/emulated/0/upload.xml

最近使用dom.4j来创建和读写安卓本地文件出现的问题。

首先配置好权限,重要的话说三遍以上,androidmanifest里面

 <!-- 允许应用程序写数据到外部存储设备(主要是SD卡) -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />

然后android6.0系统以上的手机光以上配置是没有用的需要动态权限获取,秉持用的时候才获取的操作流程,加在读文件之前询问用户是否允许读写。代码示例:

 if (PermissionUtils.hasRequiredPermissions(this, getRequiredPermissions(true))) {

          //这里放你要实现的读取操作
        } else {
            PermissionUtils.requestRequiredPermissions(this, getRequiredPermissions(true));
        }


    }


    /**
     * 组件运行需要的权限列表
     *
     * @return 列表数组
     */
    @TargetApi(Build.VERSION_CODES.M)
    protected String[] getRequiredPermissions(boolean onlyRw) {
        String[] permissions = new String[]{
                Manifest.permission.READ_EXTERNAL_STORAGE,
                Manifest.permission.WRITE_EXTERNAL_STORAGE,

        };
        if (!onlyRw)
            return permissions;
        return new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,
                Manifest.permission.WRITE_EXTERNAL_STORAGE};
    }

工具类:

需要添加一个工具类用于检测已经获得的权限


import android.annotation.TargetApi;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.os.Build;
import android.support.annotation.RequiresApi;

/**
 * 运行时权限授权工具类
 */

public class PermissionUtils
{
    // 请求权限的标示code
    public static final int REQUEST_PERMISSION_CODE = 1;
    /**
     * 权限授权结果委托
     */
    public interface GrantedResultDelgate
    {
        // 授予权限的结果,在对话结束后调用
         void onPermissionGrantedResult(boolean permissionGranted);
    }

    /**
     * 要求的权限是否已被授予
     *
     * @return
     *            true or false
     */
    @TargetApi(Build.VERSION_CODES.M)
    public static boolean hasRequiredPermissions(Activity activity, String[] permissions)
    {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return true;

        if (permissions != null && permissions.length > 0)
        {
            for (String key : permissions)
            {
                if (activity.checkSelfPermission(key) != PackageManager.PERMISSION_GRANTED )
                {
                    return false;
                }
            }
        }
        return true;
    }

    /**
     * 请求权限
     */
    @RequiresApi(api = Build.VERSION_CODES.M)
    public static void requestRequiredPermissions(Activity activity, String[] permissions)
    {
        if (permissions != null && permissions.length > 0)
        {
            activity.requestPermissions(permissions, REQUEST_PERMISSION_CODE);
        }
    }

    /**
     * 处理用户的许可结果
     */
    public static void handleRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults, Activity activity,GrantedResultDelgate grantedResultDelegate)
    {
        if (requestCode == REQUEST_PERMISSION_CODE)
        {
            boolean isOK = true;

            for (int value : grantResults)
            {
                if (value != PackageManager.PERMISSION_GRANTED)
                {
                    isOK = false;
                    break;
                }
            }

            isOK = hasRequiredPermissions(activity, permissions);

            if (grantedResultDelegate != null) grantedResultDelegate.onPermissionGrantedResult(isOK);
        }
    }
}

问题一:

当文件路径为“upload.xml”,这种只有文件名的方式是存储在android系统文件中的,结果读取除了问题

第一次出现:Read-only file system,也就是说没有权限读取系统文件中文件,我们应该添加路径

解决方式:文件路径改成 

getApplicationContext().getFilesDir().getPath().toString()+"/upload.xml"

或者sd卡方式

Environment.getExternalStorageDirectory()+"/upload.xml"

问题二:

再次运行出现:org.dom4j.DocumentException: Couldn't open /storage/emulated/0/upload.xml

为什么添加了权限还是无法打开文件呢,使用原代码java项目运行并不会报错,但是android机子运行就会有问题。

代码如下:

原代码
String path = "D:\\config.xml";
SAXReader reader = new SAXReader();
Document document = reader.read(path);

目的代码:
String path = "D:\\config.xml";
File file = new File(path);
SAXReader reader = new SAXReader();
Document document = reader.read(file); 

解决方法如下:将解析的XML文档转换为File类型.采用目的代码

解决了上述问题。


版权声明:本文为u012763405原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。