1. 程式人生 > >關於dom.4j讀取安卓本地檔案不能開啟問題:org.dom4j.DocumentException: Couldn't open /storage/emulated/0/upload.xml

關於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型別.採用目的程式碼

解決了上述問題。