Android 10ファイルストレージ

79486 ワード

文書ディレクトリ
  • 概要
  • は、サンドボックス
  • に画像を記憶する.
  • 砂箱に画像
  • をロード
  • は、共通ディレクトリ
  • に画像を記憶する.
  • 共通ディレクトリロード画像
  • 共通ディレクトリ削除画像
  • 共通ディレクトリ照会画像
  • は、共通ディレクトリ
  • に共通ファイルを格納する.
  • パブリックディレクトリクエリー一般ファイル
  • インストールパスロード画像
  • は、画像をインストールパス
  • に記憶する.
    概要
  • このコード部分は、Android Q(10)のファイル格納アダプタを学習した後、自身の必要に応じて書き換えた
  • である.
  • 以下の内容は、Android 10(Q)、すなわちtargetSdkValerson>28のアプリケーション
  • に基づく.
  • Android Qでは、ファイルの読み書き権限を申請する必要はなくなり、デフォルトでは自分の砂箱ファイルと公共メディアファイルを読み書きすることができます.したがってQ以上は、文書の読み書き権限
  • を動的に申請する必要はない.
  • 従来の学習方向がAndroidカメラに関連するため、コード例は記憶画像を主とする
  • である.
  • apk実装経路は/data/data/であり、砂箱経路/sdcard/Android/data/xxxは操作実装を行わずに
  • を直ちに生成することはない.
    画像をサンドボックスに保存
    /** storage location: sdcard/Android/data/packagename
     *
     * @param context
     * @param fileName
     * @param image
     * @param environmentType
     * @param dirName
     */
    public static void saveImage2SandBox(Context context, String fileName, byte[] image, String environmentType, String dirName) {
        File standardDirectory;
        String dirPath;
    
        if (TextUtils.isEmpty(fileName) || 0 == image.length) {
            Log.e(TAG, "saveImage2SandBox: fileName is null or image is null!");
            return;
        }
    
        if (!TextUtils.isEmpty(environmentType)) {
            standardDirectory = context.getExternalFilesDir(environmentType);
        } else {
            standardDirectory = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        }
    
        if (!TextUtils.isEmpty(dirName)) {
            dirPath = standardDirectory + "/" + dirName;
        } else {
            dirPath = String.valueOf(standardDirectory);
        }
    
        File imageFileDirctory = new File(dirPath);
        if (!imageFileDirctory.exists()) {
            if (!imageFileDirctory.mkdir()) {
                Log.e(TAG, "saveImage2SandBox: mkdir failed! Directory: " + dirPath);
                return;
            }
        }
        
    //        if (queryImageFromSandBox(context, fileName, environmentType, dirName)) {
    //            Log.e(TAG, "saveImage2SandBox: The file with the same name already exists!");
    //            return;
    //        }
    
        try {
            File imageFile = new File(dirPath + "/" + fileName);
            FileOutputStream fileOutputStream = new FileOutputStream(imageFile);
            fileOutputStream.write(image);
            fileOutputStream.flush();
            fileOutputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    

    砂箱に画像をロード
    /** storage location: sdcard/Android/data/packagename
     *
     * @param context
     * @param fileName
     * @param environmentType
     * @param dirName
     * @return
     */
    public static byte[] loadImageFromSandBox(Context context, String fileName, String environmentType, String dirName) {
        String type;
        String dirPath;
        
        if (TextUtils.isEmpty(fileName)) {
            Log.e(TAG, "loadImageFromSandBox: fileName is null");
            return null;
        }
        
        if (!TextUtils.isEmpty(environmentType)) {
            type = environmentType;
        } else {
            type = Environment.DIRECTORY_PICTURES;
        }
    
        File standardDirectory = context.getExternalFilesDir(type);
        if (null == standardDirectory) {
            return null;
        }
        
        if (!TextUtils.isEmpty(dirName)) {
            dirPath = standardDirectory + "/" + dirName;
        } else {
            dirPath = String.valueOf(standardDirectory);
        }
        
        File direction = new File(dirPath);
        File[] files = direction.listFiles();
        if (files != null) {
            for (File file : files) {
                String name = file.getName();   //           
                if (file.isFile() && fileName.equals(name)) {
                    try {
                        InputStream inputStream = new FileInputStream(file);
                        byte[] image = new byte[inputStream.available()];
                        inputStream.read(image);
                        inputStream.close();
                        return image;
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        return null;
    }
    

    共通ディレクトリへの画像の保存
    /**
     *
     * @param context
     * @param fileName just file name, not include path
     * @param image
     * @param subDir sub direction name, not absolute path
     */
    public static void saveImage2Public(Context context, String fileName, byte[] image, String subDir) {
        String subDirection;
        if (!TextUtils.isEmpty(subDir)) {
            if (subDir.endsWith("/")) {
                subDirection = subDir.substring(0, subDir.length() - 1);
            } else {
                subDirection = subDir;
            }
        } else {
            subDirection = "DCIM";
        }
    
        Cursor cursor = searchImageFromPublic(context, subDir, fileName);
        if (cursor != null && cursor.moveToFirst()) {
            try {
                int id = cursor.getInt(cursor.getColumnIndex(MediaStore.Images.Media._ID));                     // uri id,      
                Uri uri = Uri.withAppendedPath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "" + id);
                Uri contentUri = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id);
                if (uri != null) {
                    OutputStream outputStream = context.getContentResolver().openOutputStream(uri);
                    if (outputStream != null) {
                        outputStream.write(image);
                        outputStream.flush();
                        outputStream.close();
                    }
                }
                return;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        try {
            //       ContentValues 
            ContentValues contentValues = new ContentValues();
            //     
            contentValues.put(MediaStore.Images.Media.DISPLAY_NAME, fileName);
            //  Android Q     
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                //android Q     DATA  ,  RELATIVE_PATH  
                //RELATIVE_PATH           
                //                       ,          
                contentValues.put(MediaStore.Images.Media.RELATIVE_PATH, subDirection);
                //contentValues.put(MediaStore.Images.Media.RELATIVE_PATH, "Music/sample");
            } else {
                contentValues.put(MediaStore.Images.Media.DATA, Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getPath());
            }
            //      
            contentValues.put(MediaStore.Images.Media.MIME_TYPE, "image/JPEG");
            //  insert  ,           
            //EXTERNAL_CONTENT_URI       ,    
            Uri uri = context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
            if (uri != null) {
                //    uri,          
                //         uri   
                OutputStream outputStream = context.getContentResolver().openOutputStream(uri);
                if (outputStream != null) {
                    outputStream.write(image);
                    outputStream.flush();
                    outputStream.close();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    

    共通ディレクトリの画像のロード
    /**
     *
     * @param context
     * @param filePath relative path in Q, such as: "DCIM/" or "DCIM/dir_name/"
     *                 absolute path before Q
     * @return
     */
    public static byte[] loadImageFromPublic(Context context, String filePath, String fileName) {
        Cursor cursor = searchImageFromPublic(context, filePath, fileName);
    
        try {
            if (cursor != null && cursor.moveToFirst()) {
                //            
                do {
                    //         
                    int id = cursor.getInt(cursor.getColumnIndex(MediaStore.Images.Media._ID));                     // uri id,      
                    String path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.RELATIVE_PATH));   //        
                    String type = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.MIME_TYPE));       //     
                    String name = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DISPLAY_NAME));    //     
                    Log.d(TAG, "loadImageFromPublic: id = " + id);
                    Log.d(TAG, "loadImageFromPublic: name = " + name);
                    //    id  uri,        uri
                    Uri uri = Uri.withAppendedPath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "" + id);
                    //    :
                    Uri contentUri = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id);
                    if (uri != null) {
                        byte[] image;
                        InputStream inputStream = context.getContentResolver().openInputStream(uri);
                        if (null == inputStream || 0 == inputStream.available()) {
                            return null;
                        }
                        image = new byte[inputStream.available()];
                        inputStream.read(image);
                        inputStream.close();
                        return image;
                    }
                } while (cursor.moveToNext());
            }
    
            if (cursor != null) {
                cursor.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
    

    共通ディレクトリ削除画像
    /**
     *
     * @param context
     * @param filePath relative path in Q, such as: "DCIM/" or "DCIM/dir_name/"
     *                 absolute path before Q
     * @return
     */
    public static void deleteImageFromPublic(Context context, String filePath, String fileName) {
        Cursor cursor = searchImageFromPublic(context, filePath, fileName);
    
        if (cursor != null && cursor.moveToFirst()) {
            do {
                int id = cursor.getInt(cursor.getColumnIndex(MediaStore.Images.Media._ID));                     // uri id,      
    //                String path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.RELATIVE_PATH));   //        
    //                String type = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.MIME_TYPE));       //     
    //                String name = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DISPLAY_NAME));    //     
                context.getContentResolver().delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, MediaStore.Images.Media._ID + " LIKE ?", new String[]{String.valueOf(id)});
            }while (cursor.moveToNext());
        }
    
        if (cursor != null) {
            cursor.close();
        }
    }
    

    共通ディレクトリクエリー画像
    /**
     *
     * @param context
     * @param filePath relative path in Q, such as: "DCIM/" or "DCIM/dir_name/"
     *                 absolute path before Q
     * @return
     */
    private static Cursor searchImageFromPublic(Context context, String filePath, String fileName) {
        if (TextUtils.isEmpty(fileName)) {
            Log.e(TAG, "searchImageFromPublic: fileName is null");
            return null;
        }
        if (TextUtils.isEmpty(filePath)) {
            filePath = "DCIM/";
        } else {
            if (!filePath.endsWith("/")) {
                filePath = filePath + "/";
            }
        }
    
        //  androidQ     
        String queryPathKey = android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q ? MediaStore.Images.Media.RELATIVE_PATH : MediaStore.Images.Media.DATA;
        String selection = queryPathKey + "=? and " + MediaStore.Images.Media.DISPLAY_NAME + "=?";
        Cursor cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                new String[]{MediaStore.Images.Media._ID, queryPathKey, MediaStore.Images.Media.MIME_TYPE, MediaStore.Images.Media.DISPLAY_NAME},
                selection,
                new String[]{filePath, fileName},
                null);
    
        return cursor;
    }
    

    パブリックディレクトリへの一般ファイルの保存
    /**       ,  txt
     *
     * @param context
     * @param fileName just file name, not include path
     * @param image
     * @param subDir sub direction name, not absolute path
     */
    public static void saveTxt2Public(Context context, String fileName, String content, String subDir) {
        String subDirection;
        if (!TextUtils.isEmpty(subDir)) {
            if (subDir.endsWith("/")) {
                subDirection = subDir.substring(0, subDir.length() - 1);
            } else {
                subDirection = subDir;
            }
        } else {
            subDirection = "Documents";
        }
    
        Cursor cursor = searchTxtFromPublic(context, subDir, fileName);
        if (cursor != null && cursor.moveToFirst()) {
            try {
                int id = cursor.getInt(cursor.getColumnIndex(MediaStore.Files.FileColumns._ID));                     
                Uri uri = Uri.withAppendedPath(MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL), "" + id);
                Uri contentUri = ContentUris.withAppendedId(MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL), id);
                if (uri != null) {
                    OutputStream outputStream = context.getContentResolver().openOutputStream(uri);
                    if (outputStream != null) {
                        outputStream.write(content.getBytes());
                        outputStream.flush();
                        outputStream.close();
                    }
                }
                return;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        try {
            ContentValues contentValues = new ContentValues();
            contentValues.put(MediaStore.Files.FileColumns.DISPLAY_NAME, fileName);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                contentValues.put(MediaStore.Files.FileColumns.RELATIVE_PATH, subDirection);
            } else {
    
            }
            //      
            contentValues.put(MediaStore.Files.FileColumns.MEDIA_TYPE, MediaStore.Files.FileColumns.MEDIA_TYPE_NONE);
            Uri uri = context.getContentResolver().insert(MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL), contentValues);
            if (uri != null) {
                OutputStream outputStream = context.getContentResolver().openOutputStream(uri);
                if (outputStream != null) {
                    outputStream.write(content.getBytes());
                    outputStream.flush();
                    outputStream.close();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    

    共通ディレクトリクエリー通常ファイル
    /**
     *
     * @param context
     * @param filePath relative path in Q, such as: "DCIM/" or "DCIM/dir_name/"
     *                 absolute path before Q
     * @return
     */
    private static Cursor searchTxtFromPublic(Context context, String filePath, String fileName) {
        if (TextUtils.isEmpty(fileName)) {
            Log.e(TAG, "searchTxtFromPublic: fileName is null");
            return null;
        }
        if (!filePath.endsWith("/")) {
            filePath = filePath + "/";
        }
    
        String queryPathKey = MediaStore.Files.FileColumns.RELATIVE_PATH;
        String selection = queryPathKey + "=? and " + MediaStore.Files.FileColumns.DISPLAY_NAME + "=?";
        Cursor cursor = context.getContentResolver().query(MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL),
                new String[]{MediaStore.Files.FileColumns._ID, queryPathKey, MediaStore.Files.FileColumns.DISPLAY_NAME},
                selection,
                new String[]{filePath, fileName},
                null);
    
        return cursor;
    }
    

    インストールパスイメージのロード
    /** storage location: /data/data/packagename
     *
     * @param filePath
     * @return
     */
    public static byte[] loadImageFromSandBox2(String filePath) {
        byte[] image = null;
        try {
            InputStream inputStream = new FileInputStream(filePath);
            image = new byte[inputStream.available()];
            inputStream.read(image);
            inputStream.close();
            return image;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    
        return image;
    }
    

    画像をインストールパスに保存
    /** storage location: /data/data/packagename
     *
     * @param filePath
     * @param image
     */
    public static void saveImage2SandBox2(String filePath, byte[] image) {
        try {
            File imageFile = new File(filePath);
            FileOutputStream fileOutputStream = new FileOutputStream(imageFile);
            fileOutputStream.write(image);
            fileOutputStream.flush();
            fileOutputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }