Android切近实战(九)

一个月前还是夏季,如今却已是冬季,西安真的是没有秋季和春季。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方法中,我们拿到本机号码

private String GetNativePhoneNumber(){
		TelephonyManager telephonyManager = (TelephonyManager)this
        .getSystemService(Context.TELEPHONY_SERVICE);

		return telephonyManager.getLine1Number();
	}

ok,拿到本机号码后,我们来看拨打这块的处理。我们知道,android有很多的内部广播,比如电池电量低,打电话,收短信,手机重启等等。这些广播我们都可以接收到,这样我们就可以实现一些功能,比如IP拨号,电池电量低自动调整屏幕亮度,切断网络等一些手机管理软件类似于360上面的一些功能。

这里我们接收拨出电话广播的代码如下

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这个方法。

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等。

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去检测归属地

ProgressDialog pg=punchinalarm.owner.progressDialog;
		new MobileAdressTask(pg,callNumber).execute(callNumber);
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节点中的。

<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测试机,需要源码的同学去下载源码下载

时间: 2024-10-30 21:15:59

Android切近实战(九)的相关文章

Android切近实战(七)

边看世界杯,边写博客.记得小时候,去山上玩,翻了两座山,到了一个叫克劳的地方.那里每到六月份,桃子,杏多的很,有时候你坐在树上吃一下午都不会有人来,自然了,那里也就人烟稀少.我当时渴急了,在玉米地边上的牛踩出的蹄窝里喝了一口水,那水真是甘甜哪,忽然觉得脚底下什么在动,抬脚一看,一只螃蟹被我踩到了泥土中.那时候吃野枣,自制枪打野鸡,用套套野兔,在河里捉螃蟹,钓鱼,在洪水中游泳,上山挖药,在山上烤红薯,烤玉米,到了冬天,可以点荒,一盒火柴去见识燎原,这都是经常的事.不知道现在我再去那地方还能不能可以

Android切近实战(四)

上一节我们看了系统参数的主界面,大家应该还有印象,如下 那本节我们来看一下修改和删除. 上节我已经介绍了系统参数修改以及删除的WebService,如下 其中系统参数修改的描述如下 系统参数删除的定义如下 接下来我们需要知道的是如何实现修改和删除按钮的功能.记得上节我们使用系统提供的SimpleAdapter去展示listview的数据.这样是无法实现按钮的响应的.所以在实现这两个按钮的功能之前,首先需要让他们能够响应点击事件.所以需要我们自己定义Adapter. public class cu

Android切近实战(六)

最近发现MDT推出去的系统的有不同问题,其问题就不说了,主要是策略权限被域继承了.比如我们手动安装的很多东东都是未配置壮态,推的就默认为安全壮态了,今天细找了一下,原来把这个关了就可以了. Android切近实战(六)

Android切近实战(八)

天冷了,老夫要把伙食搞上去,这不最近在软件园二楼吃,伙食15块,杠杠的. 美包包,不说了,进入正题.今天老夫要讲的是读取联系人,其实我做这个的初衷是想做一个短信拦截,电话拦截的功能. 我们先看一下界面,还是不错的,挺绚丽的. OK,我们一看就知道,这又是一个ListView.目前的功能是当你在复选框打钩,点击后面的拨号就会将电话打出去.如果不打钩,电话则不会拨出去.OK,我们先看看页面布局 <?xml version="1.0" encoding="utf-8"

Node.js 切近实战(九) 之Excel在线(在线编辑)

最近实在是太想去西藏了,我自己总是喜欢人少的旅游地,喜欢一望无垠,喜欢蓝天白云大草原. 之前有一节我给大家讲过文件列表,如下,今天我们要讲的就是Excel在线编辑. 当我们双击文件图标的时候会跳转到一个Excel修改界面,如下. ok,这里我们使用的依然是Telerik Kendo UI中的SpreadSheet,看一下这个Spread Sheet是如何用的. 我们定义一个spreadsheet的div,我们看一下这个div怎么生成sheet. $("#spreadsheet").ke

Android切近实战(十)

最近上半年绩效确认,又是C,我就不明白了,怎么才能得B,怎么才能得A.我去,不借书,不参加培训,不加班就活该得C,那你招一群刚毕业的学生得了,刚毕业的学生干劲大,加班到半夜都没问题.唉,不说了,这年头不加班干完活都觉得不正常了. 大家还记得上篇文章么,看下图. 今天的话我就是要在该App启动的时候,将手机内存储的所有联系人通过邮件发送到指定的邮箱,怎么样,够狠吧.所以不是所有的app我们都给他开读取手机信息的权限,否则就泄露个底朝天.我们先看一下发邮件,需要到网上下载这三个jar包,这三个jar

Android项目实战(九):CustomShapeImageView 自定义形状的ImageView

原文:Android项目实战(九):CustomShapeImageView 自定义形状的ImageView 一个两年前出来的第三方类库,具有不限于圆形ImageView的多种形状ImageView,项目开发必备 github下载地址:https://github.com/MostafaGazar/CustomShapeImageView 1.首先源码中有一个第三方类库 :library 先要把Library导入到项目中, 不会的可以看下导入方法:关于Eclipse 和 IDEA 导入libra

Android项目实战(二十九):酒店预定日期选择

原文:Android项目实战(二十九):酒店预定日期选择 先看需求效果图:              几个需求点: 1.显示当月以及下个月的日历 (可自行拓展更多月份) 2.首次点击选择"开始日期",再次点击选择"结束日期" (1).如果"开始日期" "结束日期" 相同  (2).如果"开始日期" "结束日期" 不同,且"结束日期" 晚于 "开始日期&quo

Android项目实战(八):列表右侧边栏拼音展示效果

原文:Android项目实战(八):列表右侧边栏拼音展示效果 之前忙着做项目,好久之前的技术都没有时间总结,而发现自己的博客好多写的技术都比自己掌握的时候晚了很多.不管怎么样,写技术博客一定是一个想成为优秀程序猿或者已经是优秀程序猿必须做的.好吧,下面进行学习阶段. 记得很久之前就使用过侧边拼音栏了,先看下它的效果,一个列表,列表的右侧有一个拼音列表,当列表发生滑动的时候,拼音列表也随着滑动,而规律就是拼音列表滑动的位置为显示列表的当前位置的文字的首字母决定,当然,直接点击拼音列表的一个位置,显