如何进入系统拨号盘,或者直接打电话,发短信,还有data,scheme,uri的关系
2016-02-01 16:47
507 查看
一.背景
Android做app,有时候需要去调用系统的拨号盘,或者直接拨打某个电话,还有发送短信(直接发送和带着默认的号码和内容跳到系统应用),网上有很多例子,可以直接拿来用,可是如果换做是调用其他的系统应用你会咩?下面就授之以渔!!!
二.实例
用一个跳到短信的需求来讲怎么查源代码(点我获取应用层代码)。(1)首先用模拟器打开新建短信,观察开启了什么Activity
(2)从上面可以发现启动了ComposeMessageActivity,接下来查看他的源码和Intent-filter
(3)查看
通过上面就可以知道怎么跳到信息应用,很多会对 Data,MineType还有Scheme搞不清,等会我就区分下,先讲完这里,如果要带着内容怎么搞?
(4)看看怎么带着内容跳到系统的信息应用
所以综上基本就可以知道怎么用了
(5)代码
public class MainActivity extends AppCompatActivity implements View.OnClickListener { private Button btDialDirect; private Button btDialInDirect; private Button btSendSms; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btDialDirect = (Button) findViewById(R.id.bt_dial_direct); btDialInDirect = (Button) findViewById(R.id.bt_dial_indirect); btSendSms = (Button) findViewById(R.id.bt_sendSms); btSendSms.setOnClickListener(this); btDialDirect.setOnClickListener(this); btDialInDirect.setOnClickListener(this); } @Override public void onClick(View v) { Intent intent = new Intent(); Uri data = null; if(btDialDirect == v){ //直接打出去 intent.setAction(Intent.ACTION_CALL); data = Uri.parse("tel:"+110); }else if(btDialInDirect == v){ //跳到拨号盘然后自己打 intent.setAction(Intent.ACTION_DIAL); data = Uri.parse("tel:"+110); }else if(btSendSms == v){ intent.setAction(Intent.ACTION_SENDTO); data = Uri.parse("smsto:" + 5556); intent.putExtra("sms_body","come here"); } intent.setData(data); startActivity(intent); } }详细的源码就不放了,不能再简单了。。。
三.讲讲data,scheme,uri的关系
Activity之间的跳转分为2种:(1)显式跳转:
在可以引用到那个类, 并且可以引用到那个类的字节码时可以使用。一般用于自己程序的内部。显式跳转不可以跳转到其他程序的页面中。(2) 隐式跳转:
可以在当前程序跳转到另一个程序的页面。隐式跳转不需要引用到那个类,但是必须得知道那个界面的动作(action)和信息(category),有时还需要Data。Activity之间通过Intent进行通信。Intent即意图,用于描述一个页面的信息,同时也是一个数据的载体。
隐式跳转的Activity(自己写这个Activity要在清单文件注册action,和category,data(有时),其他app隐式调用这个Activity,就不用注册Activity)
因为自己的如果不注册,那触发这些action,category都不知道是启动哪个Activity隐式跳转可以跳转到其他程序的Activity,只要知道Activity的动作(action)以及信息(category)。因此,能够被隐式跳转的Activity,在清单文件中声明时必须指定动作和信息这两个属性。
上面的写的android.intent.category.DEFAULT可以不写,原因是系统用过startActivity或者startActivityForResult的时候会默认为Intent加上“android.intent.category.Default”这个category
(3)系统入口:
若清单文件中的Activity声明为:则此Activity将作为程序的入口,有几个作为入口的Activity,apk文件安装的时候就会生成几个图标。
(4)data,mimeType和URI的区别
<data android:scheme="http" /> <data android:scheme="https" /> <data android:scheme="inline" /> <data android:mimeType="text/html"/> <data android:mimeType="text/plain"/> <data android:mimeType="application/xhtml+xml"/> <data android:mimeType="application/vnd.wap.xhtml+xml"/> 或者 <data android:scheme="http" android:scheme="https" android:scheme="inline" android:mimeType="text/html" android:mimeType="text/plain" android:mimeType="application/xhtml+xml" android:mimeType="application/vnd.wap.xhtml+xml"/>
可以看出上面的data由两部分组成,mimeType和URI组成
mimeType(媒体类型,比如 image/jpeg,audio/mpeg4-generic 和video)
URI,下面是它的结构<scheme>://<host>:<port>/[<path>|<pathPrefix>|<pathPattern>]
实际例子
Content://com.example.project:200/folder/subfolder/etc
http://www.baidu.com:80/search/info
Scheme:URI的模式(URI默认值为content和file),比如http,file,content等,如果URI中没有指定scheme,那么整个URI的其他参数无效,他也意味着URI是无效的(就像Uri.parse("smsto:"
+ 5556);如果没有写smsto,那后面的5556就没有什么软用)
Host:是URI的主机名
Port:URI中的端口号
注意:
<intent-filter>
<data android:mimeType="image/*" />
。。。
</intent-filter>
意这种规则制定了媒体类型为所有类型的图片,虽然没有指定URI,但是却有默认值,(URI默认值为content和file),也就是虽然没有指定URI,但是Intent中的URI部分的scheme必须为Content或者file才能匹配
intent.setDataAndType(Uri.parse(“file://abc”),”image/png”).(注意setData和setType不能单独写否则会互相清空)
(5)一些注意事项
Intent-Filter的匹配规则对于Service和BroadCastReceiver也是同样的道理,不过系统对于service的建议是尽量使用显示调用方式来启动服务。但是要注意一点,如果硬是方式开启一个Activity的时候,需要做一个判断,看是否有Activity能够匹配我们的隐式Intent
判断是否有匹配的隐式 (避免不匹配直接崩掉)
1.PackManager resolveActivity
2.Intent resolveActivity
3.PackMagager querryIntentActivityes,这个方法和resolveActivity方法不同的是:它不是返回最佳匹配的Activity信息而是返回所有成功匹配的Activity信息,我们看一下两者的原型
Public abstract List<ResolveInfo> queryIntentActivities(Intent intent, int flags)
Public abstract ResolveInfo resolveActivity (Intent intent ,int flags)
第二个参数要使用 MATCH_DEFAULT_ONLY 这个标记位,这个标记为的含义是仅仅匹配那些在intent-filter中声明了<category android:name = “android.intent.category.Default/>”这个category的Activity
这个标记为的意义在于,只要上述的两个方法不返回null,那么startActivity一定可以成功,如果不用这个标记位,就会把intent-filter中category不含Default的那些Activity匹配出来,从而导致导致startActivity可能失败,因为不含有Default这个category的Activity是无法接收隐式Intent
相关文章推荐
- DRBD+HeartBeat+NFS 搭建高可用文件共享服务器笔记 推荐
- POI读取自定义中文日期格式问题
- oracle 分析函数
- 根据覆盖物自动缩放画面比例
- radiogroup weight后 依然不居中
- Servlet异常处理
- 设置边框 设置圆角
- node项目中的定时任务
- 百度2015校招笔试题(头巾问题)
- hdu 2096 小明A+B
- hibernate配置
- laydate时间控件
- 一个控件看不见可能的原因
- 同步synchronized用法
- Linux SSH安装及使用
- LoadRunner使用笔记
- 图片处理工具类
- Can I create an array whose component type is a concrete parameterized type? 我可以创建一个泛型数组嘛?
- Spring(AbstractRoutingDataSource)实现动态数据源切换--转载
- PHP删除目录及目录下所有文件或删除指定文件