Android Api Demos登顶之路(六十四)Content-->External Storage

这个demo演示了如何读写外部存储卡。演示了三种情况:
* 1.向存储卡的共享目录中的图片目录中写入一张图片:
* 位置为:/storage/sdcard/Pictures
* 2.向本地应用的图片目录中写入一张图片
* 位置为:/storage/sdcard/Android/data/包名/files/Pictures
* 3.向本地应用的目录中写入一个文件
* 位置为:/storage/sdcard/Android/data/包名/files/
activity_main.xml

ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:scrollbars="none" >

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

</ScrollView>

activity_item.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:background="#88a0a0a0"
        android:padding="4dp"
        android:gravity="center_vertical"
        android:id="@+id/label" />
    <TextView
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:padding="4dp"
        android:gravity="center_vertical"
        android:id="@+id/path" />
    <LinearLayout 
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <View 
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_weight="1"/>
        <Button 
            android:id="@+id/create"
            android:layout_width="100dp"
            android:layout_height="wrap_content"
            android:text="Create"
            android:layout_weight="0"/>
        <View 
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_weight="1"/>
        <Button 
            android:id="@+id/delete"
            android:layout_width="100dp"
            android:layout_height="wrap_content"
            android:text="Delete"
            android:layout_weight="0"/>
        <View 
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_weight="1"/>
    </LinearLayout>

</LinearLayout>

MainActivity

public class MainActivity extends Activity {
    private LinearLayout layout;

    // 定义一个类,用于管理每种情况的布局,因为是一样的布局,所以可以达到利用的目的
    static class Item {
         View mRoot;
         Button mCreate;
         Button mDelete;
    }

    // 定义三种情况下的布局
    Item mPublicPicture;
    Item mPrivatePicture;
    Item mPrivatefile;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        layout = (LinearLayout) findViewById(R.id.layout);

        mPublicPicture = createStorageControls(
                "Picture: getExternalStoragePublicDirectory",
                Environment
                        .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
                new OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        createPublicPicture();
                        updateExternalStorageState();
                    }
                }, new OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        deletePublicPicture();
                        updateExternalStorageState();
                    }
                });
        layout.addView(mPublicPicture.mRoot);

        mPrivatePicture = createStorageControls("Picture: getExternalFilesDir",
                // 注意这个方法不在Environment里面而是在Activity当中
                getExternalFilesDir(Environment.DIRECTORY_PICTURES),
                new OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        createPrivatePicture();
                        updateExternalStorageState();
                    }
                }, new OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        deletePrivatePicture();
                        updateExternalStorageState();
                    }
                });
        layout.addView(mPrivatePicture.mRoot);

        mPrivatefile = createStorageControls("Picture: getExternalFilesDir",
        // 注意这个方法不在Environment里面而是在Activity当中
                getExternalFilesDir(null), new OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        createPrivateFile();
                        updateExternalStorageState();
                    }
                }, new OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        deletePrivateFile();
                        updateExternalStorageState();
                    }
                });
        layout.addView(mPrivatefile.mRoot);

        watchingStorageState();
    }

    //定义一个广播接收者,用于监视外部存储卡的挂载状态
    private BroadcastReceiver mReceiver;

    private void watchingStorageState() {
        mReceiver=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(mReceiver, filter);
        updateExternalStorageState();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //unregisterReceiver(mReceiver);
    }

    private boolean mStorageAvaiable = false;
    private boolean mStorageWriteable = false;

    // 更新外部存储卡的状态:判断存储卡是否可写可用,并根据存储卡的状态和目录中是否已经存在该文件
    // 来设置按钮的可用状态
    protected void updateExternalStorageState() {
        String state = Environment.getExternalStorageState();
        if (Environment.MEDIA_MOUNTED.equals(state)) {
            mStorageAvaiable = true;
            mStorageWriteable = true;
        } else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
            mStorageAvaiable = true;
            mStorageWriteable = false;
        } else {
            mStorageAvaiable = false;
            mStorageWriteable = false;
        }
        handleStorageState(mStorageAvaiable, mStorageWriteable);
    }

    private void handleStorageState(boolean avaiable, boolean writeable) {
        boolean has = hasPublicPicture();
        mPublicPicture.mCreate.setEnabled(!has && writeable);
        mPublicPicture.mDelete.setEnabled(has && writeable);
        has = hasPrivatePicture();
        mPrivatePicture.mCreate.setEnabled(!has && writeable);
        mPrivatePicture.mDelete.setEnabled(has && writeable);
        has=hasPrivateFile();
        mPrivatefile.mCreate.setEnabled(!has && writeable);
        mPrivatefile.mDelete.setEnabled(has && writeable);
    }

    private boolean hasPublicPicture() {
        File path = Environment
                .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
        File file = new File(path, "demopicture.jpg");
        return file.exists();
    }

    private boolean hasPrivatePicture() {
        File path = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        File file = new File(path, "demopicture.jpg");
        return file.exists();
    }

    private boolean hasPrivateFile() {
        File path = getExternalFilesDir(null);
        File file = new File(path, "demopicture.jpg");
        return file.exists();
    }

    // 该方法将一张图片复制到外部存储卡的共享目录的图片目录下
    protected void createPublicPicture() {
        File path = Environment
                .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
        File file = new File(path, "demopicture.jpg");
        try {
            // 确保目录被创建
            path.mkdirs();
            System.out.println(path);
            InputStream is = getResources().openRawResource(
                    R.drawable.ic_launcher);
            OutputStream os = new FileOutputStream(file);
            byte[] data = new byte[is.available()];
            is.read(data);
            os.write(data);
            is.close();
            os.close();

            // 对文件进行扫描,以确保用户能够马上使用刚刚被复制到的图片,比如在图库中更新显示
            MediaScannerConnection.scanFile(this,
                    new String[] { file.toString() }, null,
                    new OnScanCompletedListener() {
                        @Override
                        public void onScanCompleted(String path, Uri uri) {
                            Log.i("ExternalStorage", "Scanned " + path + ":");
                            Log.i("ExternalStorage", "-> uri=" + uri);
                        }
                    });
        } catch (Exception e) {
            Log.w("ExternalStorage", "Error Writing:" + file, e);
        }
    }

    protected void deletePublicPicture() {
        File path = Environment
                .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
        File file = new File(path, "demopicture.jpg");
        file.delete();
    }

    // 该方法将一张图片复制到外部存储卡本地应用目录下的图片目录下
    protected void createPrivatePicture() {
        File path = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        File file = new File(path, "demopicture.jpg");
        try {
            // 确保目录被创建
            path.mkdirs();
            System.out.println(path);
            InputStream is = getResources().openRawResource(
                    R.drawable.ic_launcher);
            OutputStream os = new FileOutputStream(file);
            byte[] data = new byte[is.available()];
            is.read(data);
            os.write(data);
            is.close();
            os.close();

            // 对文件进行扫描,以确保用户能够马上使用刚刚被复制到的图片,比如在图库中更新显示
            MediaScannerConnection.scanFile(this,
                    new String[] { file.toString() }, null,
                    new OnScanCompletedListener() {
                        @Override
                        public void onScanCompleted(String path, Uri uri) {
                            Log.i("ExternalStorage", "Scanned " + path + ":");
                            Log.i("ExternalStorage", "-> uri=" + uri);
                        }
                    });
        } catch (Exception e) {
            Log.w("ExternalStorage", "Error Writing:" + file, e);
        }
    }

    protected void deletePrivatePicture() {
        File path = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        File file = new File(path, "demopicture.jpg");
        file.delete();
    }

    // 该方法将一张图片复制到外部存储卡本地应用目录下
    protected void createPrivateFile() {
        File path = getExternalFilesDir(null);
        File file = new File(path, "demopicture.jpg");
        try {
            // 确保目录被创建
            path.mkdirs();
            System.out.println(path);
            InputStream is = getResources().openRawResource(
                    R.drawable.ic_launcher);
            OutputStream os = new FileOutputStream(file);
            byte[] data = new byte[is.available()];
            is.read(data);
            os.write(data);
            is.close();
            os.close();

            // 对文件进行扫描,以确保用户能够马上使用刚刚被复制到的图片,比如在图库中更新显示
            MediaScannerConnection.scanFile(this,
                    new String[] { file.toString() }, null,
                    new OnScanCompletedListener() {
                        @Override
                        public void onScanCompleted(String path, Uri uri) {
                            Log.i("ExternalStorage", "Scanned " + path + ":");
                            Log.i("ExternalStorage", "-> uri=" + uri);
                        }
                    });
        } catch (Exception e) {
            Log.w("ExternalStorage", "Error Writing:" + file, e);
        }
    }

    protected void deletePrivateFile() {
        File path = getExternalFilesDir(null);
        File file = new File(path, "demopicture.jpg");
        file.delete();
    }

    /*
     * 创建每种情况下的布局
     */
    private Item createStorageControls(String label, File path,
            View.OnClickListener createClick, View.OnClickListener deleteClick) {
        LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
        Item item = new Item();
        item.mRoot = inflater.inflate(R.layout.activity_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());
        }
        item.mCreate = (Button) item.mRoot.findViewById(R.id.create);
        item.mDelete = (Button) item.mRoot.findViewById(R.id.delete);
        item.mCreate.setOnClickListener(createClick);
        item.mDelete.setOnClickListener(deleteClick);
        return item;
    }

}

别忘了添加读写外部存储卡的权限

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值