1.简介

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


2.跳转到拨打电话页面


权限

android telephonymanager android telephonymanager 编译_Android 获取设备联系人数据



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



2.1.代码(拨号页面)

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

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


startActivity(intent);


2.2.效果

android telephonymanager android telephonymanager 编译_Android 拨打电话_02


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

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


2.4.效果

android telephonymanager android telephonymanager 编译_Android 获取设备联系人数据_03




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 telephonymanager android telephonymanager 编译_Android 监听手机的所有来电_04


SIM卡状态

android telephonymanager android telephonymanager 编译_TelephonyManager_05

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



网络状态

android telephonymanager android telephonymanager 编译_Android 监听手机的所有来电_06

android telephonymanager android telephonymanager 编译_Android 获取设备联系人数据_07


android telephonymanager android telephonymanager 编译_Android 拨打电话_08



3.4.获取手机的信号强度

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

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


3.5.代码

android telephonymanager android telephonymanager 编译_Android 拨打电话_09


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 telephonymanager android telephonymanager 编译_TelephonyManager_10



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 telephonymanager android telephonymanager 编译_Android 获取设备联系人数据_11



根据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等信息。