String version_sdk = Build.VERSION.SDK_INT; // 设备SDK版本(Android版本号)如:23(android 6.0)
String version_release = Build.VERSION.RELEASE; // 设备的系统版本
// 获取设备号 TelephonyManager var1 = (TelephonyManager)getApplicationContext().getSystemService(TELEPHONY_SERVICE); String deviceId = var1.getDeviceId();
在Android平台中,通过TelephonyManager可以访问与手机通讯相关的信息,比如设备信息、网络信息及SIM卡信息,同时还可以监听电话的相关状态。下面我们通过几个方面来说明Android平台中如何使用电话技术。 1、获取TelephonyManager对象
TelephonyManager类提供的主要的方法: Public Methods int getCallState() 返回一个常数,表示设备上的呼叫状态 CellLocation getCellLocation() 返回设备的当前位置。 int getDataActivity() 返回一个常数,表示活动的数据连接的类型。 int getDataState() 返回一个常数表示当前数据连接状态 String getDeviceId() 返回唯一的设备ID,例如,IMEI GSM和MEID CDMA手机。 String getDeviceSoftwareVersion() 返回设备的软件版本号,例如,的IMEI / SV GSM手机。 String getLine1Number() 返回1号线的电话号码,例如,MSISDN用于GSM电话。 List<NeighboringCellInfo> getNeighboringCellInfo() 返回设备的相邻小区信息。 String getNetworkCountryIso() 返回注册的网络运营商的国家代码 String getNetworkOperator() 返回的MCC +跨国公司的注册网络运营商 String getNetworkOperatorName() 返回注册的网络运营商的名字 int getNetworkType() 返回一个常数,表示目前在设备上使用的无线电技术(网络类型)。 int getPhoneType() 返回设备的类型(手机制式)。 String getSimCountryIso() 返回SIM卡运营商的国家代码 String getSimOperator() 返回MCC +跨国公司(移动国家代码+移动网络代码)的提供者的SIM卡。 String getSimOperatorName() 返回服务提供者的名称(SPN)。 String getSimSerialNumber() 返回SIM卡的序列号,如果适用的话。 int getSimState() 返回一个常数表示SIM卡设备的状态。 String getSubscriberId() 返回唯一的用户ID,例如,IMSI为GSM手机。 String getVoiceMailAlphaTag() 检索与语音信箱号码相关的字母标识符。 String getVoiceMailNumber() 返回语音信箱号码。 boolean hasIccCard() boolean isNetworkRoaming() 返回true,如果该设备被认为是漫游当前网络上,支持GSM目的。 void listen(PhoneStateListener listener, int events) 注册一个侦听器对象接收改变指定的电话状态的通知。 TelephonyManager telephonyManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE); 2、通过TelephonyManager获取设备信息 String phoneTypeStr = "未知"; 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; } addTelephoneView("电话类型",phoneTypeStr); //GSM--IMEI CDMA--MEID String deviceId = telephonyManager.getDeviceId(); addTelephoneView("设备编号",deviceId); //软件版本编号 String softVersion = telephonyManager.getDeviceSoftwareVersion(); addTelephoneView("软件版本",softVersion); //手机号码(不一定能获取到) String phoneNumber = telephonyManager.getLine1Number(); addTelephoneView("手机号码",phoneNumber); 3、通过TelephonyManager获取网络信息 //网络信息:连接到一个网络时有效,如果是CDMA则不一定有效 //国家ISO代码 String networkCountry = telephonyManager.getNetworkCountryIso(); addTelephoneView("国家ISO代码",networkCountry); //运营商信息 String networkOperatorId = telephonyManager.getNetworkOperator(); addTelephoneView("运营商编号",networkOperatorId); String networkOperatorName=telephonyManager.getNetworkOperatorName(); addTelephoneView("运营商名称",networkOperatorName); //网络连接状态 int networktype = telephonyManager.getNetworkType(); addTelephoneView("网络类型",networktype+""); 4、通过TelephonyManager获取SIM卡信息 //SIM卡的状态 int simState = telephonyManager.getSimState(); switch (simState){ case TelephonyManager.SIM_STATE_READY: //SIM卡的ISO国家代码 String simISO = telephonyManager.getSimCountryIso(); addTelephoneView("SIM国家ISO",simISO); //SIM卡的运营商代码 String simOperator = telephonyManager.getSimOperator(); addTelephoneView("SIM运营商编号",simOperator); //SIM的运营商名称 String simOperatorName = telephonyManager.getSimOperatorName(); addTelephoneView("SIM运营商名称",simOperatorName); //SIM的序列号‘ String number = telephonyManager.getSimSerialNumber(); addTelephoneView("SIM序列号",number); break; } 注意获取信息的时候需要添加如下权限: <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
5、通过继承PhoneStateListener,使用TelephonyManager注册后进行监听电话状态。 PhoneStateListener可以通过重写方法onCallStateChanged、onDataConnectionStateChanged、onDataActivity等方法对来电状态、数据连接状态、数据传输状态进行监听。 通过TelephonyManager.listen方法进行注册,该方法有两个参数,一个参数为PhoneStateListener,第二个参数为监听标志,决定了监听哪些状态。 PhoneStateListener的之类代码如下: //定义电话状态监听器 private PhoneStateListener listener = new PhoneStateListener(){ @Override public void onCallStateChanged(int state, String incomingNumber) { super.onCallStateChanged(state, incomingNumber); String msg = "未知"; switch (state){ case TelephonyManager.CALL_STATE_IDLE: msg="电话空闲"; break; case TelephonyManager.CALL_STATE_RINGING: msg = incomingNumber+"来电话了,响铃中……"; break; case TelephonyManager.CALL_STATE_OFFHOOK: msg = "电话中……"; break; } Toast.makeText(TelephonyActivity.this,msg,Toast.LENGTH_LONG).show(); } @Override public void onDataConnectionStateChanged(int state) { super.onDataConnectionStateChanged(state); String msg = "未知"; switch (state){ case TelephonyManager.DATA_CONNECTED: msg="数据已连接"; break; case TelephonyManager.DATA_CONNECTING: msg = "数据正在连接中……"; break; case TelephonyManager.DATA_DISCONNECTED: msg = "数据已关闭!"; break; } show.setText(msg); } @Override public void onDataActivity(int direction) { super.onDataActivity(direction); String msg = "未知"; switch (direction){ case TelephonyManager.DATA_ACTIVITY_IN: msg = "下载"; break; case TelephonyManager.DATA_ACTIVITY_OUT: msg = "上传"; break; case TelephonyManager.DATA_ACTIVITY_INOUT: msg = "下载/上传"; break; case TelephonyManager.DATA_ACTIVITY_NONE: msg = "未知"; break; } show.setText(msg); } }; 注册代码: telephonyManager.listen(listener, PhoneStateListener.LISTEN_CALL_STATE |PhoneStateListener.LISTEN_DATA_CONNECTION_STATE |PhoneStateListener.LISTEN_DATA_ACTIVITY); 注销代码: telephonyManager.listen(listener,PhoneStateListener.LISTEN_NONE); 6、通过 BroadcastReceiver接收广播监听电话的状态。 当拨打电话时系统会发送 Intent.ACTION_NEW_OUTGOING_CALL广播,当电话状态发生变化的时候,系统会发送 TelephonyManager.ACTION_PHONE_STATE_CHANGED广播,我们通过接收这两个广播来监听电话的相关状态 BroadcastReceiver的关键代码如下: if(intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)){ //去电 String phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER); }else if(intent.getAction().equals(TelephonyManager.ACTION_PHONE_STATE_CHANGED)){ //来电 String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE); if(state.equals(TelephonyManager.EXTRA_STATE_RINGING)){ //有来电,响铃中 //TelephonyManager.EXTRA_STATE_IDLE; //TelephonyManager.EXTRA_STATE_OFFHOOK String phoneNumber= intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER); //比对电话号码 if(null !=backNumber && null != phoneNumber && backNumber.endsWith(phoneNumber)){ //挂掉电话 //AIDL Android接口定义语言 //IPC ITelephony iTelephony = getITelephony(context); try { iTelephony.endCall(); } catch (RemoteException e) { e.printStackTrace(); } finally { } } }else if(state.equals(TelephonyManager.EXTRA_STATE_IDLE)){ // }else if(state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)){ } } } 在清单文件中注册: <receiver android:name=".receiver.PhoneStateChanagedReceiver"> <intent-filter> <action android:name="android.intent.action.NEW_OUTGOING_CALL"/> <action android:name="android.intent.action.PHONE_STATE"/> </intent-filter> </receiver> 注意此处需要如下权限: <uses-permission android:name="android.permission.READ_PHONE_STATE"/> <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/> 7、电话拦截,在 6的基础上,完成电话拦截操作,这里需要使用到 ITelephony.aidl。 首先在 Android Studio的对应的 Module中创建 aidl目录,和 java目录同级,在该目录下创建 com.android.internal.telephony包和 android.telephony包,然后拷贝 ITelephony.aidl和 NeighboringCellInfo.aidl到对应的包下,然后从新构建。通过反射拿到 ITelephony对象并调用 endCall方法挂断电话。 关键代码如下: private static ITelephony getITelephony(Context context){ ITelephony iTelephony = null; TelephonyManager telephonyManager=(TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); Class<TelephonyManager> c = TelephonyManager.class; Method getITelephoneyMethod = null; try { getITelephoneyMethod = c.getDeclaredMethod("getITelephony",(Class[])null); getITelephoneyMethod.setAccessible(true); iTelephony = (ITelephony)getITelephoneyMethod.invoke(telephonyManager,(Object[])null); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return iTelephony; }
作者: 杰瑞教育 出处: http://www.cnblogs.com/jerehedu/ 版权声明:本文版权归 烟台杰瑞教育科技有限公司 和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
==========================================================================================================================
在开发中 我们有时候会需要获取当前手机的系统版本来进行判断,或者需要获取一些当前手机的硬件信息。
android.os.Build类中。包括了这样的一些信息。我们可以直接调用 而不需要添加任何的权限和方法。
android.os.Build.BOARD:获取设备基板名称
android.os.Build.BOOTLOADER:获取设备引导程序版本号
android.os.Build.BRAND:获取设备品牌
android.os.Build.CPU_ABI:获取设备指令集名称(CPU的类型)
android.os.Build.CPU_ABI2:获取第二个指令集名称
android.os.Build.DEVICE:获取设备驱动名称
android.os.Build.DISPLAY:获取设备显示的版本包(在系统设置中显示为版本号)和ID一样
android.os.Build.FINGERPRINT:设备的唯一标识。由设备的多个信息拼接合成。
android.os.Build.HARDWARE:设备硬件名称,一般和基板名称一样(BOARD)
android.os.Build.HOST:设备主机地址
android.os.Build.ID:设备版本号。
android.os.Build.MODEL :获取手机的型号 设备名称。
android.os.Build.MANUFACTURER:获取设备制造商
android:os.Build.PRODUCT:整个产品的名称
android:os.Build.RADIO:无线电固件版本号,通常是不可用的 显示unknown
android.os.Build.TAGS:设备标签。如release-keys 或测试的 test-keys
android.os.Build.TIME:时间
android.os.Build.TYPE:设备版本类型 主要为"user" 或"eng".
android.os.Build.USER:设备用户名 基本上都为android-build
android.os.Build.VERSION.RELEASE:获取系统版本字符串。如4.1.2 或2.2 或2.3等
android.os.Build.VERSION.CODENAME:设备当前的系统开发代号,一般使用REL代替
android.os.Build.VERSION.INCREMENTAL:系统源代码控制值,一个数字或者git hash值
android.os.Build.VERSION.SDK:系统的API级别 一般使用下面大的SDK_INT 来查看
android.os.Build.VERSION.SDK_INT:系统的API级别 数字表示
android.os.Build.VERSION_CODES类 中有所有的已公布的Android版本号。全部是Int常亮。可用于与SDK_INT进行比较来判断当前的系统版本
但是在6.0上面打电话需要动态请求权限,所以代码又改成这样:
if (Build.VERSION.SDK_INT >= 23) { //判断有没有拨打电话权限 if (PermissionChecker.checkSelfPermission(context, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) { //请求拨打电话权限 ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CALL_PHONE}, REQUEST_CODE); } else { callPhone("号码"); } } else { callPhone("号码"); }
解决办法:
1、看看目录E:\software\Android\sdk\platforms\android-23\optional 下有没有org.apache.http.legacy.jar 和 optional.json