Android API之ExternalStorage操作

官方API文档:

https://developer.android.com/guide/topics/sensors/sensors_environment.html

https://developer.android.com/reference/android/os/Environment.html

/**
 * Android中外存储设备(SD卡)操作
 *
 * @description:
 * @author ldm
 * @date 2016-7-21 上午9:33:53
 */
public class ExternalStorage extends Activity {
    // 装载控件的容器
    private ViewGroup container;
    /**
     * Android的外部存储,在APILevel=8之前,所有的文件都是建议放在Environment.getExternalStorageState()目录下的。
     * 从API Level=8开始,对于应用程序的私有文件应该放在Context.getExternalFilesDir目录下。
     * 非私有的(shared)的文件应该放在目录下Environment.getExternalStoragePublicDirectory(String)所指定的目录下。
     * 私有的文件放在Environment.getExternalStorageDirectory()所指定的目录下。
     */
    // 非私有图片
    private Item mExternalStoragePublicPicture;
    // 私有图片
    private Item mExternalStoragePrivatePicture;
    // 私有文件
    private Item mExternalStoragePrivateFile;
    // 处存储设备文件扫描广播
    private BroadcastReceiver mExternalStorageReceiver;
    // 外存储是否可用
    boolean mExternalStorageAvailable = false;
    // 外存储是否可写操作
    boolean mExternalStorageWriteable = false;

    // 自定义的Item
    static class Item {
        View mRoot;
        // 创建文件的Button
        Button mCreate;
        // 删除文件Button
        Button mDelete;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.external_storage);
        initViews();
        addViewsToContainer();
        startWatchingExternalStorage();
    }

    /**
     * 给ViewGroup添加View
     *
     * @description:
     * @author ldm
     * @date 2016-7-21 上午9:06:33
     */
    private void addViewsToContainer() {
        mExternalStoragePublicPicture = createStorageControls(
                "Picture: getExternalStoragePublicDirectory",
                Environment
                        .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
                new View.OnClickListener() {
                    public void onClick(View v) {
                        createExternalStoragePublicPicture();
                        updateExternalStorageState();
                    }
                }, new View.OnClickListener() {
                    public void onClick(View v) {
                        deleteExternalStoragePublicPicture();
                        updateExternalStorageState();
                    }
                });
        container.addView(mExternalStoragePublicPicture.mRoot);
        mExternalStoragePrivatePicture = createStorageControls(
                "Picture getExternalFilesDir",
                getExternalFilesDir(Environment.DIRECTORY_PICTURES),
                new View.OnClickListener() {
                    public void onClick(View v) {
                        createExternalStoragePrivatePicture();
                        updateExternalStorageState();
                    }
                }, new View.OnClickListener() {
                    public void onClick(View v) {
                        deleteExternalStoragePrivatePicture();
                        updateExternalStorageState();
                    }
                });
        container.addView(mExternalStoragePrivatePicture.mRoot);
        mExternalStoragePrivateFile = createStorageControls(
                "File getExternalFilesDir", getExternalFilesDir(null),
                new View.OnClickListener() {
                    public void onClick(View v) {
                        createExternalStoragePrivateFile();
                        updateExternalStorageState();
                    }
                }, new View.OnClickListener() {
                    public void onClick(View v) {
                        deleteExternalStoragePrivateFile();
                        updateExternalStorageState();
                    }
                });
        container.addView(mExternalStoragePrivateFile.mRoot);
    }

    private void initViews() {
        container = (ViewGroup) findViewById(R.id.container);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        stopWatchingExternalStorage();
    }

    private void handleExternalStorageState(boolean available, boolean writeable) {
        boolean has = hasExternalStoragePublicPicture();
        mExternalStoragePublicPicture.mCreate.setEnabled(writeable && !has);
        mExternalStoragePublicPicture.mDelete.setEnabled(writeable && has);
        has = hasExternalStoragePrivatePicture();
        mExternalStoragePrivatePicture.mCreate.setEnabled(writeable && !has);
        mExternalStoragePrivatePicture.mDelete.setEnabled(writeable && has);
        has = hasExternalStoragePrivateFile();
        mExternalStoragePrivateFile.mCreate.setEnabled(writeable && !has);
        mExternalStoragePrivateFile.mDelete.setEnabled(writeable && has);
    }

    private void updateExternalStorageState() {
        String state = Environment.getExternalStorageState();
        if (Environment.MEDIA_MOUNTED.equals(state)) {
            mExternalStorageAvailable = mExternalStorageWriteable = true;
        } else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
            mExternalStorageAvailable = true;
            mExternalStorageWriteable = false;
        } else {
            mExternalStorageAvailable = mExternalStorageWriteable = false;
        }
        handleExternalStorageState(mExternalStorageAvailable,
                mExternalStorageWriteable);
    }

    private void startWatchingExternalStorage() {
        mExternalStorageReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                updateExternalStorageState();
            }
        };
        IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_MEDIA_MOUNTED);
        filter.addAction(Intent.ACTION_MEDIA_REMOVED);
        registerReceiver(mExternalStorageReceiver, filter);
        updateExternalStorageState();
    }

    private void stopWatchingExternalStorage() {
        unregisterReceiver(mExternalStorageReceiver);
    }

    // 创建外存储中公共图片
    private void createExternalStoragePublicPicture() {

        File path = Environment
                .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
        File file = new File(path, "DemoPicture.jpg");

        try {
            path.mkdirs();
            InputStream is = getResources()
                    .openRawResource(R.drawable.balloons);
            OutputStream os = new FileOutputStream(file);
            byte[] data = new byte[is.available()];
            is.read(data);
            os.write(data);
            is.close();
            os.close();

            // 媒体文件进行扫描,看是否有新文件,使得MediaProvider同步媒体数据库
            // scanFile(Context context, String[] paths, String[] mimeTypes,
            // OnScanCompletedListener callback)
            // 传入参数分别是上下文对象,文件路径对应的数组,文件类型及扫描监听
            MediaScannerConnection.scanFile(this,
                    new String[] { file.toString() }, null,
                    new MediaScannerConnection.OnScanCompletedListener() {
                        public void onScanCompleted(String path, Uri uri) {
                            Log.i("ExternalStorage", "Scanned " + path + ":");
                            Log.i("ExternalStorage", "-> uri=" + uri);
                        }
                    });
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 删除外存储中是否有指定的公共图片
    private void deleteExternalStoragePublicPicture() {

        File path = Environment
                .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
        File file = new File(path, "DemoPicture.jpg");
        file.delete();
    }

    // 判断外存储中是否有指定的公共图片
    private boolean hasExternalStoragePublicPicture() {
        File path = Environment
                .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
        File file = new File(path, "DemoPicture.jpg");
        return file.exists();
    }

    // 在外存储中创建私有文件
    private void createExternalStoragePrivatePicture() {
        // 创建文件
        File path = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        File file = new File(path, "DemoPicture.jpg");

        try {

            InputStream is = getResources()
                    .openRawResource(R.drawable.balloons);
            OutputStream os = new FileOutputStream(file);
            byte[] data = new byte[is.available()];
            is.read(data);
            os.write(data);
            is.close();
            os.close();

            // 媒体文件进行扫描,看是否有新文件,使得MediaProvider同步媒体数据库
            // scanFile(Context context, String[] paths, String[] mimeTypes,
            // OnScanCompletedListener callback)
            // 传入参数分别是上下文对象,文件路径对应的数组,文件类型及扫描监听
            MediaScannerConnection.scanFile(this,
                    new String[] { file.toString() }, null,
                    new MediaScannerConnection.OnScanCompletedListener() {
                        public void onScanCompleted(String path, Uri uri) {
                            // 扫描完成后处理
                        }
                    });
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 删除外存储中指定的私有图片
    private void deleteExternalStoragePrivatePicture() {
        File path = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        if (path != null) {
            File file = new File(path, "DemoPicture.jpg");
            file.delete();
        }
    }

    // 判断是否有指定的图片
    private boolean hasExternalStoragePrivatePicture() {
        File path = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        if (path != null) {
            File file = new File(path, "DemoPicture.jpg");
            return file.exists();
        }
        return false;
    }
    //在外存储中创建私有文件
    private void createExternalStoragePrivateFile() {
        File file = new File(getExternalFilesDir(null), "DemoFile.jpg");
        try {
            InputStream is = getResources()
                    .openRawResource(R.drawable.balloons);
            OutputStream os = new FileOutputStream(file);
            byte[] data = new byte[is.available()];
            is.read(data);
            os.write(data);
            is.close();
            os.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void deleteExternalStoragePrivateFile() {
        // 获取外部存储文件的路径。如果文件存在则删除
        File file = new File(getExternalFilesDir(null), "DemoFile.jpg");
        if (file != null) {
            file.delete();
        }
    }

    private boolean hasExternalStoragePrivateFile() {
        // 获取外部存储文件的路径。如果文件不存在,则返lse
        File file = new File(getExternalFilesDir(null), "DemoFile.jpg");
        return (file != null) && file.exists();
    }

    /**
     *
     * @description:创建Item对View
     * @author ldm
     * @date 2016-7-21 上午9:08:00
     */
    private Item createStorageControls(CharSequence label, File path,
            View.OnClickListener createClick, View.OnClickListener deleteClick) {
        // 获取系统LayoutInflater
        LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
        // 始化Item
        Item item = new Item();
        item.mRoot = inflater.inflate(R.layout.external_storage_item, null);
        TextView tv = (TextView) item.mRoot.findViewById(R.id.label);
        tv.setText(label);
        if (path != null) {
            tv = (TextView) item.mRoot.findViewById(R.id.path);
            tv.setText(path.toString());
        }
        // 初始化Button及点击事件
        item.mCreate = (Button) item.mRoot.findViewById(R.id.create);
        item.mCreate.setOnClickListener(createClick);
        item.mDelete = (Button) item.mRoot.findViewById(R.id.delete);
        item.mDelete.setOnClickListener(deleteClick);
        return item;
    }
}

—-布局文件——

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:scrollbars="none" >

    <LinearLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" >
    </LinearLayout>

</ScrollView>
时间: 2024-10-05 19:32:29

Android API之ExternalStorage操作的相关文章

[Android系列—] 4. 添加操作栏(Action Bar)

前言 操作栏是最重要的设计元素之一,使用它来实现你的应用程序活动.通过提供多种用户界面功能, 使应用程序快速和其他的Andorid应用程序一致, 以便被用户熟悉和接受. 主要功能包括: 1. 标识你的应用程序,指示在应用程序的用户的位置. 2. 能很方便的操作重要的功能(像搜索功能) 3. 导航和视图切换功能(使用制表符或下拉列表) 类似的效果如下: 设置操作栏 在基本的使用状况是, 操作栏在左边显示活动的标题和应用的图标. 类似: 设置一个基本的操作栏需要你使用的应用活动主题支持操作栏, 这和

Android Studio无法关联Api23源码-提示Souces for android api 23 platform not found

最近升级了As,然后忽然就关联不上源码了,很不方便,找个Activity的源码都只有outline没有解释,还提示这个错误: Decompiled .class file, bytecode version: Souces for android api 23 platform not found 在D:\Android\sdk\sources\android-23明明下载了源码,找了半天,原来是AS的默认配置有问题.最后的解决方法在 StackOverFlow的这个帖子上: Sources f

Android 编程下 java.lang.NoClassDefFoundError: cn.jpush.android.api.JPushInterface 报错

使用了极光推送的 jar 包项目在从 SVN 中检出后,假设不又一次对 jar 包和 Bulid Path 进行配置就会抛出 java.lang.NoClassDefFoundError: cn.jpush.android.api.JPushInterface 的错误,进行例如以下操作就可以消除这样的错误: 删除 libs 目录下的 jpush-sdk-release1.3.8.jar(极光推送的 jar 包),又一次在 libs 目录中增加  jpush-sdk-release1.3.8.ja

[Android新手区] SQLite 操作详解--SQL语法

该文章完全摘自转自:北大青鸟[Android新手区] SQLite 操作详解--SQL语法  :http://home.bdqn.cn/thread-49363-1-1.html SQLite库可以解析大部分标准SQL语言.但它也省去了一些特性并且加入了一些自己的新特性.这篇文档就是试图描述那些SQLite支持/不支持的SQL语法的.查看关键字列表. 如下语法表格中,纯文本用蓝色粗体显示.非终极符号为斜体红色.作为语法一部分的运算符用黑色Roman字体表示. 这篇文档只是对SQLite实现的SQ

Android之旅十五 android中的网络操作

android中的网络操作和java里面没有什么区别,java里面的很多网络操作方法都可以搬到android中去使用,主要几个点: 1.post和get请求的区别,大家可以在网上查阅有关资料进行了解,get主要以向地址中拼接字符串参数发送到服务器,长度有限制,并且请求参数暴露在地址栏中,不怎么安全:post则主要是将请求参数转换为相应的http协议请求体发送到服务器,相比get方式,参数的长度没有限制,并且参数信息不会暴露给用户: 2.我们在java web里面通过浏览器以post方式发送数据,

Android 蓝牙的常用操作

最近对Android设备的蓝牙操作进行了一些研究, 下面做一些总结, 版本是4.4,列出的解决方案多来源于网络,感谢强大的网友们: 操作蓝牙可以分为常规的操作,和非常规的操作.所谓常规的操作,就是界面上有提示,需要客户许可进行的一些操作.非常规的则通常是采用反射等手段,达到不知不觉连接蓝牙的目的. 一. 常规操作: 1. 获取蓝牙的操作接口: BluetoothAdapter mBtAdapter = BluetoothAdapter.getDefaultAdapter(); 蓝牙的相关操作基本

Android API中常用的包(转)

在Android应用开发中,我们一般都是用java语言.所以Android很好的继承了java的功能,不过为了满足手机系统的需要和实现一些新的功能,Android还提供了一些特有的扩展的java功能.有了这些Android特有的包,我们才能实现Android平台上的许多功能,下面卓天下为大家介绍一些重要包: android.app :提供高层的程序模型.提供基本的运行环境 android.content :包含各种的对设备上的数据进行访问和发布的类 android.database :通过内容提

android SQLite 批量插入数据慢的解决方案 (正对于不同的android api 版本)

SQLite,是一款轻型的数据库,被广泛的运用到很多嵌入式的产品中,因为占用的资源非常少,二其中的操作方式几乎和我们接触的数据库不多,甚至只有几百K的他自然会被需求者青睐,下面讲一下在这样的轻型数据库中怎么对他进行一些读写操作. 之前做选择联系人的时候出现如果一个手机里联系人超过2000的话,往数据库里面插入会非常耗时,不同的手机存储的条数不同,这个存储的数量和手机的内存有很大的关系,往往取决于手机内存,下面对于数据量大的情况来写一下sqlite的批量查询. SqLite 掺入数据有几种 第一种

Android自动化框架 模拟操作 模拟测试

转自:http://bbs2.c114.net/home.php?mod=space&uid=1025779&do=blog&id=5322 几种常见的Android自动化测试框架及其应用 随着Android应用得越来越广,越来越多的公司推出了自己移动应用测试平台.例如,百度的MTC.东软易测云.Testin云测试平台…….由于自己所在项目组就是做终端测试工具的,故抽空了解了下几种常见的基于UI层面的自动化测试工具.趁晚上有空总结下,好记心不如烂笔头呀! 一 常见Android自动