预备知识:Uri
这部分参考Uri详解,感谢博主
1、Uri与URI的异同
(1)所属的包不同。URI位置在java.net.URI,显然是Java提供的一个类。而Uri位置在android.net.Uri,是由Android提供的一个类。初步可以判断,Uri是URI的“扩展”以适应Android系统的需要。
(2)作用的不同。URI类代表了一个URI(这个URI不是类,而是其本来的意义:通用资源标志符——Uniform Resource Identifier)实例。Uri类是一个不可改变的URI引用,包括一个URI和一些碎片,URI跟在“#”后面。建立并且转换URI引用。而且Uri类对无效的行为不敏感,对于无效的输入没有定义相应的行为,如果没有另外制定,它将返回垃圾而不是抛出一个异常。
总结:Uri是Android开发的,扩展了Java中URI的一些功能来特定的适用于Android开发,所以大家在开发时,只使用Android 提供的Uri即可。
2、Uri组成
(1)[scheme:]scheme-specific-part[#fragment]
(2)[scheme:][//authority][path][?query][#fragment]
(3)[scheme:][//host:port][path][?query][#fragment]
在android中,除了scheme、authority是必须要有的,其它的几个path、query、fragment,它们每一个可以选择性的要或不要,但顺序不能变
3、通过“content://”类型的Uri查询数据
这里用到了Android四大组建中ContentProvider的知识---ContentResolver。
(1)ConentResolver.query(uri , projection , selection , selectionArgs , sortOrder)
1)uri:可以理解为SQL语句的表名
2)projection:理解为SQL语句的列名,搜索哪些列
3)selection:理解为SQL语句的where条件
4)selectionArgs:配合第三个参数使用,当第三个参数中使用了占位符(?)
5)sortOrder:排序规则
(2)上面函数返回一个游标Cursor。下面介绍游标的使用。
若使用游标访问数据,首先使用cursor.moveToFirst()或者cursor.moveTo(int offset)找到一条数据。
然后可以访问某一条数据的某一个字段。使用cursor.getColumnIndex(String columnName)查询某字段的index。
使用cursor.getSting(int index)获取某字段信息。
----------------------------------------------------分割线-------------------------------------------------------
一、使用Intent访问其他Activity
一些通用的使用请参考Android API指南--通用Intent,超级详细。下面详细介绍几个。
1、访问相机拍照并获取照片
(1)将照片保存到外部存储器
重点在于启动相机之前,设置照片的保存路径。
往Intent中放入参数MediaStore.EXTRA_OUTPUT,是一个Uri。而Uri的获取通过文件路径。
当拍照返回后,直接对文件操作就可以(因为已经知道文件的路径了)。当然要判断一下是否拍照了(根据resultCode)
(2)不保存照片,直接使用
这种方法的重点在于拍照后的数据处理。。启动相机时不需要传入任何参数。
照片数据的获取是从Intent的Extra中获取“data”数据,就是一个Bitmap,可以随便使用。
2、访问流文件,图片、文档、音乐、视频等
重点:
(1)使用Intent.ACTIONGET_CONTENT操作。
(2)设置type,image/jpg、image/png、audio/x-mpeg(mp3)、video/mp4等等,如果想匹配多种类型,也可以使用通配符*。
(3)Extra(必须):
EXTRA_ALLOW_MULTIPLE(boolean,声明用户是否可以一次选择多个文件)
EXTRA_LOCAL_ONLY(boolean,声明是否返回的文件必须直接存在于设备上,而不是需要从远程服务下载)
(4)category(可选):CATEGORY_OPENABLE(只返回可通过openFileDescriptor()以文件流形式表示的“可打开”文件)
处理返回数据--通过Uri:
(1)一般会让你从图库或者文件管理器中选择,个人发现,从图库选择返回content://类型的Uri,从文件管理器选择返回file://类型的Uri
(2)如果用户只选择一项,您就可以从getData()检索该项目。如果用户选择多项,则getData()返回 null,此时您必须改为从getClipData()返回的ClipData对象检索每个项目。
(3)ClipData对象,他有很多条数据(类似List),使用getItemAt(int index)得到Item对象,Item可以get到Text,HtmlText,Intent和Uri。
3、使用ACTION.PICK访问图库
Intent(Intent.ACTION_PICK , MediaStore.Images.media.EXTERNAL_CONTENT_URI),也可以添加多选Extra,这种方法是直接跳转到图库,上面会选择是图库或文件管理器或其他。下面是处理得到的图片或其他类型的
特别注意要加入读写(此时仅仅是读)外部存储器的权限,MediaStore.Images.Media.DATA('_data')这个字段中保存的是文件路径。
二、使用Intent发送(分享)数据
1、分享文字
2、分享二进制(流文件)
你也可以分享多条数据,传入一个ArrayList<Uri>即可
三、Activity接受处理Intent数据
如果想让别的应用启动你的Activity,就是分享一些东西,可以这样做
1、在Mainifest.xml文件<activity>标签中添加<intent-filter>标签,消息的传递是通过Intent。
2、<intent-filter>添加三种标签
1)<action>,在name属性中,声明接受的 Intent 操作。一般是android.intent.action.SEND或android.intent.action.SEND_MULTIPLE;
2)<category>,为了接收隐式 Intent,必须将CATEGORY_DEFAULT类别包括在 Intent 过滤器中;
3)<data>,使用一个或多个指定数据 URI 各个方面(scheme、host、port、path等)和 MIME 类型的属性,声明接受的数据类型。您可以指定下列属性
注:如果您无需声明关于数据的具体信息Uri,您应只指定android:mimeType属性声明您的 Activity 处理的数据类型,比如text/plain或image/jpeg。
3、处理消息
在onCreate()或onStart()方法中getIntent()可以获取到传入的Intent,如果接受多种消息类型,可以通过getType()进行区分。
官方推荐通过getStringExtra(Intent.EXTRA_TEXT)获取String、getParcelableExtra(Intent.EXTRA_STREAM)获取一个Uri和getParcelableArrayListExtra(Intent.EXTRA_STREAM)获取多个ArrayList<Uri>。当然也可以通过getData()和getClipData()。
4、返回处理结果
----------------------------------------------------分割线-------------------------------------------------------
其他:判断Intent能否被解析
也就是看看你手机上是否安装了相应的软件能打开你的Intent请求。
三个方法:
(1)Package.resolveActivity(Intent intent , int flags),是一个抽象方法,我猜测是调用Native层方法。
(2)Intent.resolveActivity(Package pm),分析源码得知是调用了Package的方法。返回一个ComponentName。
(3)Package.queryIntentActivities(Intent intent , int flags),返回List,即能启动该Intent的Activity集合