Android Storage Access Framework 使用方法简介

Android Storage Access Framework(SAF), 是Android 4.4版本(API 19)开始引入的,它可以很方便的让用户浏览、打开设备上的文件以及浏览最近使用过的文件列表。而且SAF不仅可以让用户查看本地存储的文件,也可以使用户查看网络上的文件,同时它还可以查看临时存储设备上的文件:一旦成功插入一个USB储存设备,我们就可以浏览它上面的文件。因此SAF可以很方便的让我们的应用实现文件浏览以及进行常见文件操作。

如下图所示:

 

一般来说,Storage Access Framework总体上分为以下三个部分:

  1. Document Provider:文件提供者。它是一个提供文件信息给SAF的Content Provider。可以包括本地的文件也可以包括网络上的文件,只要它们实现类DocumentsProvider,并且把文件信息作为服务提供出去即可。Android平台也有内置的一些实现了这个类的Content Provider,比如下载的内容,存储的图片,存储的视频等等。
  2. Client App:这个就是使用SAF的应用,一般就是我们自己写的应用。比如你写了一个图片编辑App,要用到SAF来浏览图片,那么这个图片编辑App就是Client App。
  3. Picker:选择器。其实就是你打开SAF后的界面,它可以选择你需要浏览或者操作的文件,当然指定不同的参数,这个选择器可能展示的内容不同,但是展示的内容都来自于Document Provider提供的数据。

下面我们来看一下如何在我们的App中使用SAF:这里定义了四个操作:showImage,createFile,deleteFile,alterFile



1.浏览文件

浏览文件的操作很简单,这也是SAF的优点。一般来说、我们只要使用Intent.ACTION_OPEN_DOCUMENT来构造一个intent,然后再设置intent的category、type或者其他属性来指定我们需要的文件类型,最后调用startActivity方法就可以。代码如下所示:
/*
	 * show image
	 */
	public void showImage(){
		Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
		intent.addCategory(Intent.CATEGORY_OPENABLE);
		intent.setType("image/*");
		if (intent.resolveActivity(getPackageManager()) != null) {
			startActivityForResult(intent, REQUEST_CODE);
		} else {
			Toast.makeText(getApplicationContext(),
					"No Activity to handle the intent", Toast.LENGTH_SHORT)
					.show();
		}
	}
上述代码中setType()方法,指定了要查看的文件类型为image,这个我们可以根据自己的需要设置的,比如查看文本文件:text/*,查看所有的文件:*/*等等。指定了文件类型之后,我们判断了activity是否能被处理掉,如果可以,我们调用startActivityForResult()发送这个intent。这里调用startActivityForResult而不是startActivity的原因是:当我们选择文件列表中的某个文件后,我们一般都需要对这个文件进行后续处理,比如图像裁剪,图像放缩,图像展示等等,这样我们就需要把这个文件传送回这个Activity,所以就使用了startActivityForResult。
处理的代码:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		if (resultCode == Activity.RESULT_OK) {
			if (requestCode == REQUEST_CODE) {
				Uri uri = null;
				if (data != null) {
					uri = data.getData();
					Log.i("example", "Uri: " + uri.toString());
					try {
						findViewById(R.id.rlyt_bg).setBackground(
								new BitmapDrawable(getBitmapFromUri(uri)));
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}...


其中getBitmapFromUri()可以通过uri得到文件,代码如下:
private Bitmap getBitmapFromUri(Uri uri) throws IOException {
		ParcelFileDescriptor parcelFileDescriptor = getContentResolver()
				.openFileDescriptor(uri, "r");
		FileDescriptor fileDescriptor = parcelFileDescriptor
				.getFileDescriptor();
		image = BitmapFactory.decodeFileDescriptor(fileDescriptor);
		parcelFileDescriptor.close();
		return image;
	}

这样就可以查看并且展示一个图片了,这里代码的操作是把查看到的图片作为activity的背景,执行的结果如下:

2.创建文件

利用SAF不仅仅可以查看文件,同时创建文件。基本上的代码跟查看文件类似,只是我们要多定义一些文件的信息,比如文件名。创建代码如下:
private void createFile(String mimeType, String fileName) {
		Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
		intent.addCategory(Intent.CATEGORY_OPENABLE);
		intent.setType(mimeType);
		intent.putExtra(Intent.EXTRA_TITLE, fileName);
		startActivityForResult(intent, WRITE_REQUEST_CODE);
	}

指定了文件类型mimeType和文件名之后,我们通过Intent.ACTION_CREATE_DOCUMENT就可以创建文件了,但是要注意的是,我们要想向创建了文件里面写数据,还是需要startActivityForResult来获取已创建的文件的URI的。

3.删除文件

删除文件比较简单,知道了文件的URI,直接调用:
DocumentsContract.deleteDocument(getContentResolver(), uri);

 就可以删除了,如果删除成功了,会返回true,否则false。

另外这种删除文件,只是把Document Provider内部的该文件信息删除了,事实上你磁盘上的文件没有被删除的。

4,修改文件

修改文件其实跟我们第一步查看文件差不多,首先选择你要查看的文件,然后通过startActivityForResult得到返回的文件的URI:
Intent alterIntent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
alterIntent.addCategory(Intent.CATEGORY_OPENABLE);
alterIntent.setType("text/plain");
startActivityForResult(alterIntent, EDIT_REQUEST_CODE);

然后对文件进行修改:
private void alterDocument(Uri uri) {
		try {
			
			ParcelFileDescriptor pfd = MainActivity.this.getContentResolver()
					.openFileDescriptor(uri, "w");
			FileOutputStream fileOutputStream = new FileOutputStream(
					pfd.getFileDescriptor());
			fileOutputStream.write(("Overwritten by MyFile at "
					+ System.currentTimeMillis() + "\n").getBytes());
			// Let the document provider know you're done by closing the stream.
			fileOutputStream.close();
			pfd.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}


OK,以上就是SAF的简单用法,事实上SAF最有用的地方还是可以查看无论是网络还是本地上的文件,另外我们也可以自定义Document Provider来让SAF展示我们自己APP希望展示的文件,这一部分在暂时先不介绍,有兴趣的可以阅读以下谷歌官方的API。另外本文大部分代码均来自谷歌官方的API。本文使用的源码如下:
http://download.csdn.net/detail/ypz_ghost/7955469

      最后,转载请注明出处[http://blog.csdn.net/ypz_ghost/article/details/39433361],谢谢。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值