全栈工程师开发手册 (作者:栾鹏)
安卓教程全解
安卓电话和网络开发全解,包括电话硬件检测、电话服务信息、sim信息、网络服务信息、数据连接和数据传输信息。通过phone state listener监听电话状态的变化和通过广播接收BroadcastReceiver监听电话状态变化。
拨打电话
调用
startPhone("17665343626");
//拨打电话的实现函数
private void startPhone(String phonenum) {
//使用系统电话服务栈启动电话呼叫
Intent whoyougonnacall = new Intent(Intent.ACTION_CALL, Uri.parse("tel:"+phonenum));
startActivity(whoyougonnacall);
}
检测电话硬件功能的支持
//检查电话硬件
private void checkphone() {
PackageManager pm = getPackageManager();
boolean telephonesupported = pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY); //是否包含电话功能
boolean gsmphonesupported = pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_GSM); //是否包含gsm电话功能
boolean cdmaphonesupported = pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_CDMA); //是否包含cdma电话功能
Log.v("电话硬件功能", "电话功能是否支持:"+telephonesupported);
Log.v("电话硬件功能", "gsm电话功能是否支持:"+gsmphonesupported);
Log.v("电话硬件功能", "cdma电话功能是否支持:"+cdmaphonesupported);
}
获取电话服务信息
private void phonestate() {
TelephonyManager telephonyManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE); //获取系统电话服务
//获取手机类型
String phonetypeStr = "unknow";
int phonetype=telephonyManager.getPhoneType();
switch (phonetype) {
case TelephonyManager.PHONE_TYPE_CDMA:phonetypeStr="cdma";break;
case TelephonyManager.PHONE_TYPE_GSM:phonetypeStr="gsm";break;
case TelephonyManager.PHONE_TYPE_SIP:phonetypeStr="sip";break;
case TelephonyManager.PHONE_TYPE_NONE:phonetypeStr="none";break;
default:break;
}
//读取gsm手机的imei或cdma手机的meid
String deviceid = telephonyManager.getDeviceId();
//读取手机上的软件版本(注意:不是sdk版本)
String softwareversion=telephonyManager.getDeviceSoftwareVersion();
//获取手机号码
String phonenumber = telephonyManager.getLine1Number();
Log.v("电话服务信息", "手机类型:"+phonetypeStr);
Log.v("电话服务信息", "meid号:"+deviceid);
Log.v("电话服务信息", "软件版本:"+softwareversion);
Log.v("电话服务信息", "手机号码:"+phonenumber);
}
获取网络服务信息
private void netstate()
{
TelephonyManager telephonyManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE); //获取系统电话服务
//获取连接网络所在国家的iso代码
String networkcountry=telephonyManager.getNetworkCountryIso();
//获得连接网络的运营商ID(MCC+MNC)
String networkoperatorid=telephonyManager.getNetworkOperator();
//获取连接网络的运营商名称
String networkname = telephonyManager.getNetworkOperatorName();
//获得手机卡支持的网络类型
int networkType = telephonyManager.getNetworkType();
String simnettype="";
switch (networkType) {
case TelephonyManager.NETWORK_TYPE_UNKNOWN: simnettype="NETWORK_TYPE_UNKNOWN"; break;
case TelephonyManager.NETWORK_TYPE_GPRS: simnettype="NETWORK_TYPE_GPRS"; break;
case TelephonyManager.NETWORK_TYPE_EDGE: simnettype="NETWORK_TYPE_EDGE"; break;
case TelephonyManager.NETWORK_TYPE_UMTS: simnettype="NETWORK_TYPE_UMTS"; break;
case TelephonyManager.NETWORK_TYPE_HSDPA: simnettype="NETWORK_TYPE_HSDPA"; break;
case TelephonyManager.NETWORK_TYPE_HSUPA: simnettype="NETWORK_TYPE_HSUPA"; break;
case TelephonyManager.NETWORK_TYPE_HSPA: simnettype="NETWORK_TYPE_HSPA"; break;
case TelephonyManager.NETWORK_TYPE_CDMA: simnettype="NETWORK_TYPE_CDMA"; break;
case TelephonyManager.NETWORK_TYPE_EVDO_0: simnettype="NETWORK_TYPE_EVDO_0"; break;
case TelephonyManager.NETWORK_TYPE_EVDO_A: simnettype="NETWORK_TYPE_EVDO_A"; break;
case TelephonyManager.NETWORK_TYPE_EVDO_B: simnettype="NETWORK_TYPE_EVDO_B"; break;
case TelephonyManager.NETWORK_TYPE_1xRTT: simnettype="NETWORK_TYPE_1xRTT"; break;
case TelephonyManager.NETWORK_TYPE_IDEN: simnettype="NETWORK_TYPE_IDEN"; break;
case TelephonyManager.NETWORK_TYPE_LTE: simnettype="NETWORK_TYPE_LTE"; break;
case TelephonyManager.NETWORK_TYPE_EHRPD: simnettype="NETWORK_TYPE_EHRPD"; break;
case TelephonyManager.NETWORK_TYPE_HSPAP: simnettype="NETWORK_TYPE_HSPAP"; break;
default:break;
}
//当前上网的网络类型
ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = manager.getActiveNetworkInfo();
String type="";
if (networkInfo != null && networkInfo.isConnected())
type = networkInfo.getTypeName();
Log.v("网络服务信息", "国家代码:"+networkcountry);
Log.v("网络服务信息", "运营商ID:"+networkoperatorid);
Log.v("网络服务信息", "运营商名称:"+networkname);
Log.v("网络服务信息", "手机卡网络类型:"+simnettype);
Log.v("网络服务信息", "当前上网网络类型:"+type);
}
获取sim卡信息
private void simstate() {
TelephonyManager telephonyManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE); //获取系统电话服务
int simstate = telephonyManager.getSimState();
String siminfo="";
switch (simstate) {
case TelephonyManager.SIM_STATE_ABSENT: siminfo="没有sim卡"; break;
case TelephonyManager.SIM_STATE_UNKNOWN: siminfo="未知情况"; break;
case TelephonyManager.SIM_STATE_PIN_REQUIRED: siminfo="需要sim卡的PIN来解锁"; break;
case TelephonyManager.SIM_STATE_PUK_REQUIRED: siminfo="需要sim卡的PUK来解锁"; break;
case TelephonyManager.SIM_STATE_NETWORK_LOCKED: siminfo="需要网络PIN来解锁"; break;
case TelephonyManager.SIM_STATE_READY: siminfo="sim卡正常"; break;
default:break;
}
//获取SIM的ISO国家代码
String simworkcountry=telephonyManager.getSimCountryIso();
//获得活动SIM的运营商ID(MCC+MNC)
String simworkoperatorid=telephonyManager.getSimOperator();
//获取sim运营商名称
String simworkname = telephonyManager.getSimOperatorName();
//获取sim的序列号
String simserial = telephonyManager.getSimSerialNumber();
Log.v("sim卡信息", "国家代码:"+simworkcountry);
Log.v("sim卡信息", "运营商ID:"+simworkoperatorid);
Log.v("sim卡信息", "运营商名称:"+simworkname);
Log.v("sim卡信息", "序列号:"+simserial);
Log.v("sim卡信息", "sim卡状态:"+siminfo);
}
读取数据连接和传输状态的详细信息
private void datastate() {
TelephonyManager telephonyManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE); //获取系统电话服务
int dataactivity = telephonyManager.getDataActivity();
int datastate = telephonyManager.getDataState();
String dataactivityinfo="";
switch (dataactivity) {
case TelephonyManager.DATA_ACTIVITY_IN:dataactivityinfo="正在接收数据";break;
case TelephonyManager.DATA_ACTIVITY_OUT:dataactivityinfo="正在发送数据";break;
case TelephonyManager.DATA_ACTIVITY_INOUT:dataactivityinfo="正在同时发送和接收数据";break;
case TelephonyManager.DATA_ACTIVITY_NONE:dataactivityinfo="当前没有数据传输";break;
default:break;
}
String datainfo="";
switch (datastate) {
case TelephonyManager.DATA_CONNECTED:datainfo="当前可以上网";break;
case TelephonyManager.DATA_CONNECTING:datainfo="正在开启上网服务";break;
case TelephonyManager.DATA_DISCONNECTED:datainfo="当前不可以上网";break;
case TelephonyManager.DATA_SUSPENDED:datainfo="正在电话,不能上网";break;
default:break;
}
Log.v("数据传输信息", "数据传输状态:"+dataactivityinfo);
Log.v("数据传输信息", "上网状态:"+datainfo);
}
使用phone state listener监听电话状态的变化
应用程序处于运行状态才能接受这个监视器回调。
首先定义自己的监听器
可以自定义传入电话呼叫监听器、蜂窝位置变化监视器、服务变化监视器、数据传输监视函数、数据连接监视函数、
//定义监听器
PhoneStateListener callStateListener = new PhoneStateListener(){
//传入电话呼叫监听器,处理传入的呼叫相关的电话号码
public void onCallStateChanged(int state,String incomingNumber) {
String callStateStr = "Unknown";
switch (state) {
case TelephonyManager.CALL_STATE_IDLE: //电话既不响铃,也不再通话中时
callStateStr = "没有电话呼叫";break;
case TelephonyManager.CALL_STATE_OFFHOOK: //当电话响铃时,此时系统会显示来电屏幕
callStateStr = "有电话呼入";break;
case TelephonyManager.CALL_STATE_RINGING: //当电话当前正在通话中时
callStateStr = "正在通话中"+incomingNumber;break;
default:
break;
}
Log.v("电话传入电话监视:", callStateStr);
}
//蜂窝位置变化监视器
public void onCellLocationChanged(CellLocation location) {
if (location instanceof GsmCellLocation) {
GsmCellLocation gsmCellLocation = (GsmCellLocation)location;
Toast.makeText(getApplicationContext(), String.valueOf(gsmCellLocation.getCid()), Toast.LENGTH_LONG).show();
Log.v("电话蜂窝位置监视:", "GSM:"+String.valueOf(gsmCellLocation.getCid()));
}
else if (location instanceof CdmaCellLocation) {
CdmaCellLocation cdmaCellLocation = (CdmaCellLocation)location;
StringBuilder sb=new StringBuilder();
sb.append(cdmaCellLocation.getBaseStationId()); //获取基站id
sb.append("\n@");
sb.append(cdmaCellLocation.getBaseStationLatitude()); //获取经纬度
sb.append(cdmaCellLocation.getBaseStationLongitude());
Log.v("电话蜂窝位置监视:", "CDMA:"+sb.toString());
}
}
//服务变化监视器
public void onServiceStateChanged(ServiceState serviceState) {
if (serviceState.getState() == ServiceState.STATE_IN_SERVICE) {
String toasttext = "运营商:"+serviceState.getOperatorAlphaLong();
Toast.makeText(context, toasttext, 1000).show();
Log.v("电话服务监视:", toasttext);
}
}
//数据传输监视函数
public void onDataActivity(int direction) {
String dataActivitystr = "none";
switch (direction) {
case TelephonyManager.DATA_ACTIVITY_IN:dataActivitystr="正在下载";break;
case TelephonyManager.DATA_ACTIVITY_OUT:dataActivitystr="正在上传";break;
case TelephonyManager.DATA_ACTIVITY_INOUT:dataActivitystr="正在下载或上传";break;
case TelephonyManager.DATA_ACTIVITY_NONE:dataActivitystr="没有数据传输";break;
default:break;
}
Log.v("电话数据传输监视:", dataActivitystr);
}
//数据连接监视函数
public void onDataConnectionStateChanged(int state) {
String datastatestr = "none";
switch (state) {
case TelephonyManager.DATA_CONNECTED:datastatestr="已经连接上";break;
case TelephonyManager.DATA_CONNECTING:datastatestr="正在连接";break;
case TelephonyManager.DATA_DISCONNECTED:datastatestr="连接失败";break;
case TelephonyManager.DATA_SUSPENDED:datastatestr="暂停挂起";break;
default:break;
}
Log.v("电话数据连接监视:", datastatestr);
}
};
注册监听器,实现状态变化监听。
private void phonechange() {
TelephonyManager telephonyManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE); //获取系统电话服务
telephonyManager.listen(callStateListener,
PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR | //呼叫转移
PhoneStateListener.LISTEN_CALL_STATE| //电话呼叫状态变化
PhoneStateListener.LISTEN_CELL_LOCATION | //蜂窝位置变化
PhoneStateListener.LISTEN_DATA_ACTIVITY | //数据连接变化
PhoneStateListener.LISTEN_DATA_CONNECTION_STATE | //数据传输变化
PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR |
PhoneStateListener.LISTEN_SERVICE_STATE | //网络服务变化
PhoneStateListener.LISTEN_SIGNAL_STRENGTHS //网络信号强度变化
); //参数:监听器,状态类型
}
使用广播接收监听电话状态变化
电话状态变化,系统向手机所有app广播intent,所以可以通过广播接收,捕获这个广播消息。
1、在manifest中注册广播接收器
<!-- 电话监视-->
<receiver android:name="com.lp.app.advice.Phonestatechangereceiver" >
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE"/>
</intent-filter>
</receiver>
2、实现这个接收器,在接收器中区别广播intent类别,和获取广播事件信息。
import android.content.Intent;
import android.widget.Toast;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.telephony.TelephonyManager;
//使用广播接收BroadcastReceiver监视电话状态的变化
public class Phonestatechangereceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String phonestateString = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
//这里仅监听传入的电话呼入
if (phonestateString.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
String phonenumber = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
Toast.makeText(context, "Incoming call from:"+phonenumber, 1000).show();
}
}
}