Android Manager之TelephonyManager(电话管理器)

1.简介

TelephonyManager,见名知义:用于管理手机通话状态,获取电话信息(设备信息、sim卡信息以及 网络信息),侦听电话状态(呼叫状态服务状态、信号强度状态等)以及可以调用电话拨号器拨打电话! 话不多开始本节内容。


2.跳转到拨打电话页面


权限

Android Manager之TelephonyManager(电话管理器)


注意1:此处只为了演示调起电话功能 所以没有考虑Android 6.0及以上敏感权限问题

资料1:Android 6.0以上 需要运行时申请的权限(一)

资料2:Android 6.0以上 需要运行时申请的权限(二)



2.1.代码(拨号页面)

Uri uri=Uri.parse("tel:"+"11111111");

Intent intent=new Intent(Intent.ACTION_DIAL,uri);

startActivity(intent);


2.2.效果

Android Manager之TelephonyManager(电话管理器)


2.3.代码(直接拨打电话)

Uri uri=Uri.parse("tel:"+"11111111");
Intent intent=new Intent(Intent.ACTION_CALL,uri);
startActivity(intent);


2.4.效果

Android Manager之TelephonyManager(电话管理器)




3.TelephonyManager使用


3.1.获取TelephonyManager对象

TelephonyManager mr = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);


3.2.获取Sim卡信息与网络信息

stringBuilder.append("设备编号:" + mr.getDeviceId()+"\n\n");

stringBuilder.append("软件版本:" + (mr.getDeviceSoftwareVersion()!= null?mr.getDeviceSoftwareVersion():"未知")+"\n\n");

stringBuilder.append("运营商代号:" + mr.getNetworkOperator()+"\n\n");

stringBuilder.append("运营商名称:" + mr.getNetworkOperatorName()+"\n\n");

stringBuilder.append("网络类型:" + mr.getPhoneType()+"\n\n");

stringBuilder.append("设备当前位置:" + (mr.getCellLocation() != null ? mr.getCellLocation().toString() : "未知位置")+"\n\n");

stringBuilder.append("SIM卡的国别:" + mr.getSimCountryIso()+"\n\n");

stringBuilder.append("SIM卡***:" + mr.getSimSerialNumber()+"\n\n");

stringBuilder.append("SIM卡状态:" + mr.getSimState()+"\n\n");


TextView resulttextview= (TextView) findViewById(R.id.activity_sms_textviews);
resulttextview.setText(stringBuilder.toString());



3.3.效果

Android Manager之TelephonyManager(电话管理器)


SIM卡状态

Android Manager之TelephonyManager(电话管理器)

{"状态未知","无SIM卡","被PIN加锁","被PUK加锁","被NetWork PIN加锁","已准备好"}



网络状态

Android Manager之TelephonyManager(电话管理器)

Android Manager之TelephonyManager(电话管理器)


Android Manager之TelephonyManager(电话管理器)



3.4.获取手机的信号强度

网络信号强度的单位是dBm(毫瓦分贝),一般用负数表示,正常手机信号变化范围是从-110dBm (差)到-50dBm(好)之间。

另外2G,3G,4G获得信号强度的方式都是重写PhoneStateListener的onSignalStrengthsChanged() 方法,当信号强度发生改变的时候就会触发这个事件,我们可以在这个事件里获取信号强度。


3.5.代码

Android Manager之TelephonyManager(电话管理器)


 private class MyPhoneStateListener extends PhoneStateListener {

 private int asu = 0,lastSignal = 0;

     @Override

     public void onSignalStrengthsChanged(SignalStrength signalStrength) {

         super.onSignalStrengthsChanged(signalStrength);

         asu = signalStrength.getGsmSignalStrength();

         lastSignal = -113 + 2 * asu;

         resulttextview.setText("当前手机的信号强度:" + lastSignal + " dBm" );

     }

}


mr.listen(new MyPhoneStateListener(),290);


3.6.效果

Android Manager之TelephonyManager(电话管理器)



3.7.监听手机的所有来电


TelephonyManager mr  = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);


 PhoneStateListener listener = new PhoneStateListener() {

            

     @Override

      public void onCallStateChanged(int state, String number) {

             switch (state) {

                 // 无任何状态

                 case TelephonyManager.CALL_STATE_IDLE:

                     break;

                 case TelephonyManager.CALL_STATE_OFFHOOK:

                     break;
                 // 来电铃响时
                 case TelephonyManager.CALL_STATE_RINGING:
                     //相应操作
                     break;
                 default:
                     break;
             }
             super.onCallStateChanged(state, number);

         }

};

        
mr.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);



3.8.获取手机通讯录数据


ContentResolver resolver = getContentResolver();
 // 获取手机联系人

Cursor phoneCursor = resolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, PHONES_PROJECTION, null, null, null);

if (null != phoneCursor) {

      StringBuilder stringBuilder=new StringBuilder();

      while (phoneCursor.moveToNext()) {

            //得到手机号码

           String phoneNumber = phoneCursor.getString(PHONES_NUMBER_INDEX);

           //得到联系人名称

           String contactName = phoneCursor.getString(PHONES_DISPLAY_NAME_INDEX);

           //得到联系人ID

           Long contactid = phoneCursor.getLong(PHONES_CONTACT_ID_INDEX);

           //得到联系人头像ID 大于0 表示联系人有头像

           Long photoid = phoneCursor.getLong(PHONES_PHOTO_ID_INDEX);


           stringBuilder.append("ID:"+contactid+"\n\n");

           stringBuilder.append("photoid:"+photoid+"\n\n");

           stringBuilder.append("姓名:"+contactName+"\n\n");

           stringBuilder.append("电话号码:"+phoneNumber+"\n\n");

       }

       phoneCursor.close();

       resulttextview.setText(stringBuilder.toString());

}


/**获取库Phon表字段**/
private static final String[] PHONES_PROJECTION = new String[] {ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER, ContactsContract.CommonDataKinds.Photo.PHOTO_ID, ContactsContract.CommonDataKinds.Phone.CONTACT_ID };


/**联系人显示名称**/

private static final int PHONES_DISPLAY_NAME_INDEX = 0;

/**电话号码**/

private static final int PHONES_NUMBER_INDEX = 1;

/**头像ID**/

private static final int PHONES_PHOTO_ID_INDEX = 2;

/**联系人的ID**/

private static final int PHONES_CONTACT_ID_INDEX = 3;


Android Manager之TelephonyManager(电话管理器)



根据photoid获取Bibtmap

Uri uri =ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI,contactid);

InputStream input = ContactsContract.Contacts.openContactPhotoInputStream(resolver, uri);

Bitmap contactPhoto = BitmapFactory.decodeStream(input);




3.9.获取当前连接基站信息LAC、CID


代码:

int type=mr.getPhoneType();

if(TelephonyManager.PHONE_TYPE_CDMA==type){//电信

      CdmaCellLocation cdmaCellLocation = (CdmaCellLocation) mr.getCellLocation();

      int cid = cdmaCellLocation.getBaseStationId(); //获取cdma基站识别标号 BID

      int lac = cdmaCellLocation.getNetworkId(); //获取cdma网络编号NID

      stringBuilder.append("电信cid:"+cid+"\n\n");

      stringBuilder.append("电信lac:"+lac+"\n\n");

}else if(TelephonyManager.PHONE_TYPE_GSM==type){//移动和联通

      GsmCellLocation gsmCellLocation = (GsmCellLocation) mr.getCellLocation();

      int cid = gsmCellLocation.getCid(); //获取gsm基站识别标号

      int lac = gsmCellLocation.getLac(); //获取gsm网络编号

      stringBuilder.append("移动和联通cid:"+cid+"\n\n");

      stringBuilder.append("移动和联通lac:"+lac+"\n\n");

 }


电信用的是cdma制式网络,移动和联通用的gsm网络,这两种网络基站信息封装类在android中是不同的,cdma要用CdmaCellLocation,gsm要用GsmCellLocation。
从TelephonManager获取基站定位信息CellLocation,其中封装了需要的CID和LAC等信息。



附1:

TelephonyManager官方连接:

http://androiddoc.qiniudn.com/reference/android/telephony/TelephonyManager.html



附2:

Android Manager之汇总