一个月前还是夏季,如今却已是冬季,西安真的是没有秋季和春季。OK,废话不多说,今天要说的是andriod内部的拨电话broadcast以及提一下AsyncTask。
咱们在看这篇博客之前,先看看我的那篇<<Windows Mobile 5 编程体验3>>。在那篇文章我提到了一个网站,可以获取手机号码归属地,天气预报等等一些webservice。下图是我当时在windows mobile模拟器上实现的效果,说到这个mobile,我本来是很想去学windows phone开发的,谁想还要交费买账号,太麻烦了,我放弃了,还不如学android呢,写个程序随便放上去了。不说了,看下图
是不是这样呢,我当时说了,这个号码谁随便输入的,如有雷同,纯属巧合。
OK,我们接下来看看这个网站WebService网站,进去之后,我们点击国内手机号码归属地查询WEB服务
进去之后,我们查看如下方法getMobileCodeInfo
OK,我们看到了该WebService得request请求参数和response返回结果。
那OK,知道了这些,我们何愁调用呢,接下来就看我们的android客户端如何调用它。
首先我们这次的设计是当activity启动后,我们拿到本机的号码。当用户播出电话的时候,先拿到本机号码归属地,再拿到播出号码的归属地,两个号码归属地进行对比,如果归属地不一致,则加拨17951或者17911。
首先来看本机号码的获取,我们现在activity中定义一个公开的变量
public String nativePhoneNumber;
在OnCreate方法中,我们拿到本机号码
1
2
3
4
5
6
|
private
String GetNativePhoneNumber(){
TelephonyManager telephonyManager = (TelephonyManager)
this
.getSystemService(Context.TELEPHONY_SERVICE);
return
telephonyManager.getLine1Number();
}
|
ok,拿到本机号码后,我们来看拨打这块的处理。我们知道,android有很多的内部广播,比如电池电量低,打电话,收短信,手机重启等等。这些广播我们都可以接收到,这样我们就可以实现一些功能,比如IP拨号,电池电量低自动调整屏幕亮度,切断网络等一些手机管理软件类似于360上面的一些功能。
这里我们接收拨出电话广播的代码如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
public
class
IpDialBroadCastReceiver
extends
BroadcastReceiver {
final
String IPChinaMobilePrefix =
"17951"
;
final
String IPChinaUnionPrefix =
"17911"
;
final
String ChinaMobile=
"移动"
;
final
String ChinaUnion=
"联通"
;
@Override
public
void
onReceive(Context context, Intent intent) {
String callNumber = getResultData();
//ProgressDialog pg=punchinalarm.owner.progressDialog;
//new MobileAdressTask(pg,callNumber).execute(callNumber);
String nativePhoneNumber = punchinalarm.owner.nativePhoneNumber;
String nativeAddress= punchinalarm.GetMobileAddress(nativePhoneNumber).toString();
String callAddress = punchinalarm.GetMobileAddress(callNumber).toString();
String newIPPhoneNumber=
""
;
if
(!nativeAddress.equalsIgnoreCase(callAddress)){
if
(nativeAddress.contains(ChinaMobile))
{
newIPPhoneNumber = IPChinaMobilePrefix.concat(callNumber);
}
else
{
newIPPhoneNumber = IPChinaUnionPrefix.concat(callNumber);
}
setResultData(newIPPhoneNumber);
}
}
}
|
在这里我们区分了联通和移动。当我们接收到打电话的广播之后,先拿到本机号码的归属地和所播电话的归属地进行对比,如果不一致,则加拨IP。这里主要是看一下punchinalarm.GetMobileAddress这个方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
public
static
SoapObject GetMobileAddress(String mobileNumber) {
SoapObject request =
new
SoapObject(NAMESPACE, METHOD_NAME);
PropertyInfo pi =
new
PropertyInfo();
pi.setName(
"mobileCode"
);
pi.setType(String.
class
);
pi.setValue(mobileNumber);
request.addProperty(pi);
pi=
new
PropertyInfo();
pi.setName(
"userID"
);
pi.setType(String.
class
);
pi.setValue(
""
);
request.addProperty(pi);
SoapSerializationEnvelope soapEnvelope =
new
SoapSerializationEnvelope(
SoapEnvelope.VER11);
soapEnvelope.dotNet =
true
;
HttpTransportSE httpTS =
new
HttpTransportSE(URL);
soapEnvelope.bodyOut = request;
soapEnvelope.setOutputSoapObject(request);
// 设置请求参数
try
{
httpTS.call(SOAP_ACTION, soapEnvelope);
}
catch
(IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch
(XmlPullParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
SoapObject result = (SoapObject) soapEnvelope.bodyIn;
return
result;
}
|
我们需要注意的就是NAMESPACE,METHOD_NAME,URL,SOAPACTION等。
1
2
3
4
|
final
static
String NAMESPACE =
"http://WebXml.com.cn/"
;
final
static
String METHOD_NAME =
"getMobileCodeInfo"
;
final
static
String SOAP_ACTION =
"http://WebXml.com.cn/getMobileCodeInfo"
;
final
static
String URL =
"http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx?wsdl"
;
|
如果大家不知道这些变量该怎么取,看下面
nameSpace知道了。
soapAction知道了,URL也知道了,MethodName也知道了。
好了,我们给webservice传入两个参数,userID不用传,具体的参数如何传看webservice中的描述。
拿到这两个归属地之后,我们重新设置拨号号码
setResultData(newIPPhoneNumber);
相当于对当前非IP拨号进行拦截,再进行IP拨号。我们先看看在模拟器中的效果。经过调试,我们发现本机号码是15555215554,归属地是安徽,运营商是联通(如有雷同,纯属巧合)
拨打的号码是13555556666,归属地是黑龙江,运营商是移动(如有雷同,纯属巧合)
所以两个归属地不一样,而且本机是联通,所以加拨17911。
OK,我们再看看在真机中的情况。结果报错,wifi连接着呢,为什么报错?找了半天原因,原来是我的这个APP没有开启网络权限。
就是这个个人理财APP,我们看一下效果
看见了吧,自动加拨了17951。最后我们再看一下异步的实现
代码如下,在获取通话广播之后,我们开启一个异步task去检测归属地
1
2
|
ProgressDialog pg=punchinalarm.owner.progressDialog;
new
MobileAdressTask(pg,callNumber).execute(callNumber);
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
public
class
MobileAdressTask
extends
AsyncTask<String, Integer, String> {
final
String IPPrefix =
"17951"
;
String callNumber;
ProgressDialog progressDialog;
public
MobileAdressTask(ProgressDialog progressDialog, String callNumber) {
this
.progressDialog = progressDialog;
this
.callNumber = callNumber;
}
protected
void
onPreExecute() {
super
.onPreExecute();
progressDialog.show();
}
protected
String doInBackground(String... params) {
publishProgress(
5
);
String s = params[
0
];
SoapObject soapObjValue = punchinalarm.GetMobileAddress(params[
0
]);
publishProgress(
100
);
return
soapObjValue ==
null
?
""
: soapObjValue.toString();
}
protected
void
onProgressUpdate(Integer... values) {
super
.onProgressUpdate(values);
progressDialog.setProgress(values[
0
]);
}
protected
void
onPostExecute(String result) {
super
.onPostExecute(result);
if
(!result.contains(
"西安"
) && !callNumber.startsWith(IPPrefix)) {
String newnumber = IPPrefix.concat(callNumber);
Intent dialIntent =
new
Intent(Intent.ACTION_CALL, Uri.parse(
"tel:"
+ newnumber));
punchinalarm.owner.startActivity(dialIntent);
}
progressDialog.dismiss();
}
}
|
在doInBackGroud中我们得到归属地并模拟进度条。得到归属地之后,我们判断如果不是西安的号码并且没有加拨17951我们就加拨17951。此时会有一个号码是hold状态。
OK,最后看一下真机效果
最后,别忘了这三个配置,前两个是读取手机信息和处理拨电话权限,最后一个是静态注册广播接收者。这个接受者就是上面提到的IpDialBroadCastReceiver,这个广播接收者只接收android.intent.action.NEW_OUTGOING_CALL这个action发出的广播。其中要注意的是这个receiver是注册在Application节点中的。
1
2
3
4
5
6
7
|
<
uses-permission
android:name
=
"android.permission.READ_PHONE_STATE"
/>
<
uses-permission
android:name
=
"android.permission.PROCESS_OUTGOING_CALLS"
/>
<
receiver
android:name
=
"bruce.broadcastor.IpDialBroadCastReceiver"
>
<
intent-filter
android:priority
=
"1"
>
<
action
android:name
=
"android.intent.action.NEW_OUTGOING_CALL"
/>
</
intent-filter
>
</
receiver
>
|
哥们博客货真价实,小米3测试机,需要源码的同学去下载源码下载
本文转自 BruceAndLee 51CTO博客,原文链接:http://blog.51cto.com/leelei/1574894,如需转载请自行联系原作者