首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 移动开发 > Android >

Android 4.4没法写sdcard解决方案

2014-02-21 
Android 4.4无法写sdcard解决方案/* * Copyright (C) 2014 NextApp, Inc. ** Licensed under the Apache L

Android 4.4无法写sdcard解决方案

/* * Copyright (C) 2014 NextApp, Inc. *  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at *  * http://www.apache.org/licenses/LICENSE-2.0 *  * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language * governing permissions and limitations under the License. */package nextapp.mediafile;import java.io.File;import java.io.IOException;import java.io.OutputStream;import android.content.ContentResolver;import android.content.ContentValues;import android.net.Uri;import android.provider.MediaStore;/** * Wrapper for manipulating files via the Android Media Content Provider. As of Android 4.4 KitKat, applications can no longer write * to the "secondary storage" of a device. Write operations using the java.io.File API will thus fail. This class restores access to * those write operations by way of the Media Content Provider. *  * Note that this class relies on the internal operational characteristics of the media content provider API, and as such is not * guaranteed to be future-proof. Then again, we did all think the java.io.File API was going to be future-proof for media card * access, so all bets are off. *  * If you're forced to use this class, it's because Google/AOSP made a very poor API decision in Android 4.4 KitKat. * Read more at https://plus.google.com/+TodLiebeck/posts/gjnmuaDM8sn * * Your application must declare the permission "android.permission.WRITE_EXTERNAL_STORAGE". */public class MediaFile {    private final File file;    private final ContentResolver contentResolver;    private final Uri filesUri;    private final Uri imagesUri;    public MediaFile(ContentResolver contentResolver, File file) {        this.file = file;        this.contentResolver = contentResolver;        filesUri = MediaStore.Files.getContentUri("external");        imagesUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;    }    /**     * Deletes the file. Returns true if the file has been successfully deleted or otherwise does not exist. This operation is not     * recursive.     */    public boolean delete()            throws IOException {        if (!file.exists()) {            return true;        }        boolean directory = file.isDirectory();        if (directory) {            // Verify directory does not contain any files/directories within it.            String[] files = file.list();            if (files != null && files.length > 0) {                return false;            }        }        String where = MediaStore.MediaColumns.DATA + "=?";        String[] selectionArgs = new String[] { file.getAbsolutePath() };        // Delete the entry from the media database. This will actually delete media files (images, audio, and video).        contentResolver.delete(filesUri, where, selectionArgs);        if (file.exists()) {            // If the file is not a media file, create a new entry suggesting that this location is an image, even            // though it is not.            ContentValues values = new ContentValues();            values.put(MediaStore.Files.FileColumns.DATA, file.getAbsolutePath());            contentResolver.insert(imagesUri, values);            // Delete the created entry, such that content provider will delete the file.            contentResolver.delete(filesUri, where, selectionArgs);        }        return !file.exists();    }    public File getFile() {        return file;    }    /**     * Creates a new directory. Returns true if the directory was successfully created or exists.     */    public boolean mkdir()            throws IOException {        if (file.exists()) {            return file.isDirectory();        }        ContentValues values;        Uri uri;        // Create a media database entry for the directory. This step will not actually cause the directory to be created.        values = new ContentValues();        values.put(MediaStore.Files.FileColumns.DATA, file.getAbsolutePath());        contentResolver.insert(filesUri, values);        // Create an entry for a temporary image file within the created directory.        // This step actually causes the creation of the directory.        values = new ContentValues();        values.put(MediaStore.Files.FileColumns.DATA, file.getAbsolutePath() + "/temp.jpg");        uri = contentResolver.insert(imagesUri, values);        // Delete the temporary entry.        contentResolver.delete(uri, null, null);        return file.exists();    }    /**     * Returns an OutputStream to write to the file. The file will be truncated immediately.     */    public OutputStream write()            throws IOException {        if (file.exists() && file.isDirectory()) {            throw new IOException("File exists and is a directory.");        }        // Delete any existing entry from the media database.        // This may also delete the file (for media types), but that is irrelevant as it will be truncated momentarily in any case.        String where = MediaStore.MediaColumns.DATA + "=?";        String[] selectionArgs = new String[] { file.getAbsolutePath() };        contentResolver.delete(filesUri, where, selectionArgs);        ContentValues values = new ContentValues();        values.put(MediaStore.Files.FileColumns.DATA, file.getAbsolutePath());        Uri uri = contentResolver.insert(filesUri, values);        if (uri == null) {            // Should not occur.            throw new IOException("Internal error.");        }        return contentResolver.openOutputStream(uri);    }}

热点排行