Android TelephonyManager (电话管理器)

TelephonyManager 用于管理手机通话状态,获取电话信息(设备信息、sim卡信息以及 网络信息),侦听电话状态(呼叫状态服务状态、信号强度状态等)以及可以调用电话拨号器拨打电话

获得 TelephonyManager 的服务对象

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

调用拨号器拨打电话号码

Uri uri=Uri.parse("tel:"+电话号码);    
Intent intent=new Intent(Intent.ACTION_DIAL,uri);    
startActivity(intent);

获取 Sim 卡信息与网络信息

  1. 创建一个 空的 Android 项目 cn.twle.android.PhoneInfo

  2. 创建包 cn.twle.android.common 并在包下创建权限管理帮助类 PermHelper.java

    package cn.twle.android.common;
    
    import android.content.Context;
    import android.content.pm.PackageManager;
    import android.support.v4.content.ContextCompat;
    
    public class PermHelper
    {
        private final Context mContext;
    
        public PermHelper(Context context) {
            mContext = context.getApplicationContext();
        }
    
        // 判断权限集合
        public boolean lacksPermissions(String... permissions) {
            for (String permission : permissions) {
                if (lacksPermission(permission)) {
                    return true;
                }
            }
            return false;
        }
    
        // 判断是否缺少权限
        private boolean lacksPermission(String permission) {
            return ContextCompat.checkSelfPermission(mContext, permission) == PackageManager.PERMISSION_DENIED;
        }
    }
    
  3. 添加授权页

    授权页, 首先使用系统默认的授权页, 当用户拒绝时, 指导用户手动设置, 当用户再次操作失败后, 返回继续提示

    用户手动退出授权页时, 给使用页发送授权失败的通知

    我们可以保存这个授权页并将其在多个应用中复用

  4. 创建授权页 PermActivity.java

    package cn.twle.android.phoneinfo;
    
    import android.app.Activity;
    import android.content.DialogInterface;
    import android.content.Intent;
    import android.content.pm.PackageManager;
    import android.net.Uri;
    import android.os.Bundle;
    import android.provider.Settings;
    import android.support.annotation.NonNull;
    import android.support.annotation.Nullable;
    import android.support.v4.app.ActivityCompat;
    import android.support.v7.app.AlertDialog;
    import android.support.v7.app.AppCompatActivity;
    
    import cn.twle.android.common.PermHelper;
    
    public class PermActivity extends AppCompatActivity {
        public static final int PERMISSIONS_GRANTED = 0; // 权限授权
        public static final int PERMISSIONS_DENIED = 1; // 权限拒绝
    
        private static final int PERMISSION_REQUEST_CODE = 0; // 系统权限管理页面的参数
        private static final String EXTRA_PERMISSIONS =
                "cn.twle.android.common.permission.extra_permission"; // 权限参数
        private static final String PACKAGE_URL_SCHEME = "package:"; // 方案
    
        private PermHelper permHelper; // 权限检测器
        private boolean isRequireCheck; // 是否需要系统权限检测, 防止和系统提示框重叠
    
        // 启动当前权限页面的公开接口
        public static void startActivityForResult(Activity activity, int requestCode, String... permissions) {
            Intent intent = new Intent(activity, PermActivity.class);
            intent.putExtra(EXTRA_PERMISSIONS, permissions);
            ActivityCompat.startActivityForResult(activity, intent, requestCode, null);
        }
    
        @Override protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            if (getIntent() == null || !getIntent().hasExtra(EXTRA_PERMISSIONS)) {
                throw new RuntimeException("PermissionsActivity需要使用静态startActivityForResult方法启动!");
            }
            //setContentView(R.layout.activity_perm);
    
            permHelper = new PermHelper(this);
            isRequireCheck = true;
        }
    
        @Override protected void onResume() {
            super.onResume();
            if (isRequireCheck) {
                String[] permissions = getPermissions();
                if (permHelper.lacksPermissions(permissions)) {
                    requestPermissions(permissions); // 请求权限
                } else {
                    allPermissionsGranted(); // 全部权限都已获取
                }
            } else {
                isRequireCheck = true;
            }
        }
    
        // 返回传递的权限参数
        private String[] getPermissions() {
            return getIntent().getStringArrayExtra(EXTRA_PERMISSIONS);
        }
    
        // 请求权限兼容低版本
        private void requestPermissions(String... permissions) {
            ActivityCompat.requestPermissions(this, permissions, PERMISSION_REQUEST_CODE);
        }
    
        // 全部权限均已获取
        private void allPermissionsGranted() {
            setResult(PERMISSIONS_GRANTED);
            finish();
        }
    
        /**
         * 用户权限处理,
         * 如果全部获取, 则直接过.
         * 如果权限缺失, 则提示Dialog.
         *
         * @param requestCode  请求码
         * @param permissions  权限
         * @param grantResults 结果
         */
        @Override
        public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
            if (requestCode == PERMISSION_REQUEST_CODE && hasAllPermissionsGranted(grantResults)) {
                isRequireCheck = true;
                allPermissionsGranted();
            } else {
                isRequireCheck = false;
                showMissingPermissionDialog();
            }
        }
    
        // 含有全部的权限
        private boolean hasAllPermissionsGranted(@NonNull int[] grantResults) {
            for (int grantResult : grantResults) {
                if (grantResult == PackageManager.PERMISSION_DENIED) {
                    return false;
                }
            }
            return true;
        }
    
        // 显示缺失权限提示
        private void showMissingPermissionDialog() {
            AlertDialog.Builder builder = new AlertDialog.Builder(PermActivity.this);
            builder.setTitle("帮助");
            builder.setMessage("当前应用缺少必要权限。\n请点击\"设置\"-\"权限\" 打开所需权限。\n最后点击两次回退按钮,即可返回");
    
            // 拒绝, 退出应用
            builder.setNegativeButton("推出", new DialogInterface.OnClickListener() {
                @Override public void onClick(DialogInterface dialog, int which) {
                    setResult(PERMISSIONS_DENIED);
                    finish();
                }
            });
    
            builder.setPositiveButton("设置", new DialogInterface.OnClickListener() {
                @Override public void onClick(DialogInterface dialog, int which) {
                    startAppSettings();
                }
            });
    
            builder.setCancelable(false);
    
            builder.show();
        }
    
        // 启动应用的设置
        private void startAppSettings() {
            Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
            intent.setData(Uri.parse(PACKAGE_URL_SCHEME + getPackageName()));
            startActivity(intent);
        }
    }
    
  5. 修改 activity_main.xml

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:padding="5dp">
    
        <TextView
            android:id="@+id/ms_phone1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    
        <TextView
            android:id="@+id/ms_phone2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    
        <TextView
            android:id="@+id/ms_phone3"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    
        <TextView
            android:id="@+id/ms_phone4"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    
        <TextView
            android:id="@+id/ms_phone5"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    
        <TextView
            android:id="@+id/ms_phone6"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    
        <TextView
            android:id="@+id/ms_phone7"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    
        <TextView
            android:id="@+id/ms_phone8"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    
        <TextView
            android:id="@+id/ms_phone9"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    
    </LinearLayout>
    
  6. 修改 AndroidManifest.xml 中加上权限

    <!-- 添加访问手机位置的权限 -->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <!-- 添加访问手机状态的权限 -->
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
    
  7. 修改 MainActivity.java

    package cn.twle.android.phoneinfo;
    
    import android.Manifest;
    import android.content.Context;
    import android.content.Intent;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.telephony.TelephonyManager;
    import android.widget.TextView;
    
    import cn.twle.android.common.PermHelper;
    
    public class MainActivity extends AppCompatActivity {
    
        final private static int REQUEST_CODE = 29; // 请求码
    
        static final String[] PERMISSIONS = new String[]{
                Manifest.permission.READ_PHONE_STATE,
                Manifest.permission.ACCESS_COARSE_LOCATION
        };
    
        private PermHelper permHelper;
    
        private TextView ms_phone1;
        private TextView ms_phone2;
        private TextView ms_phone3;
        private TextView ms_phone4;
        private TextView ms_phone5;
        private TextView ms_phone6;
        private TextView ms_phone7;
        private TextView ms_phone8;
        private TextView ms_phone9;
        private TelephonyManager tm;
        private String[] phoneType = {"未知","2G","3G","4G"};
        private String[] simState = {"状态未知","无SIM卡","被PIN加锁","被PUK加锁",
                "被NetWork PIN加锁","已准备好"};
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            permHelper = new PermHelper(this);
    
            if (permHelper.lacksPermissions(PERMISSIONS)) {
                startPermissionsActivity();
            }
    
            // 获得系统提供的 TelphonyManager 对象的实例
            tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
    
            ms_phone1 = (TextView) findViewById(R.id.ms_phone1);
            ms_phone2 = (TextView) findViewById(R.id.ms_phone2);
            ms_phone3 = (TextView) findViewById(R.id.ms_phone3);
            ms_phone4 = (TextView) findViewById(R.id.ms_phone4);
            ms_phone5 = (TextView) findViewById(R.id.ms_phone5);
            ms_phone6 = (TextView) findViewById(R.id.ms_phone6);
            ms_phone7 = (TextView) findViewById(R.id.ms_phone7);
            ms_phone8 = (TextView) findViewById(R.id.ms_phone8);
            ms_phone9 = (TextView) findViewById(R.id.ms_phone9);
    
            ms_phone1.setText("设备编号:" + tm.getDeviceId());
            ms_phone2.setText("软件版本:" + (tm.getDeviceSoftwareVersion()!= null?
                    tm.getDeviceSoftwareVersion():"未知"));
            ms_phone3.setText("运营商代号:" + tm.getNetworkOperator());
            ms_phone4.setText("运营商名称:" + tm.getNetworkOperatorName());
            ms_phone5.setText("网络类型:" + phoneType[tm.getPhoneType()]);
            ms_phone6.setText("设备当前位置:" + (tm.getCellLocation() != null ? tm
                    .getCellLocation().toString() : "未知位置"));
            ms_phone7.setText("SIM卡的国别:" + tm.getSimCountryIso());
            ms_phone8.setText("SIM卡序列号:" + tm.getSimSerialNumber());
            ms_phone9.setText("SIM卡状态:" + simState[tm.getSimState()]);
        }
    
        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
            // 拒绝时, 关闭页面, 缺少主要权限, 无法运行
            if (requestCode == REQUEST_CODE && resultCode == PermActivity.PERMISSIONS_DENIED) {
                finish();
            }
        }
    
        @Override
        protected void onResume() {
            super.onResume();
            if (permHelper.lacksPermissions(PERMISSIONS)) {
                startPermissionsActivity();
            }
        }
    
        private void startPermissionsActivity() {
            PermActivity.startActivityForResult(this, REQUEST_CODE, PERMISSIONS);
        }
    
    }
    

其它信息

如果想获取网络制式,而非普通的 2G,3G,4G 这样,可以调用 getNetworkClass() 方法

/**
 * Return general class of network type, such as "3G" or "4G". In cases
 * where classification is contentious, this method is conservative.
 *
 * @hide
 */
public static int getNetworkClass(int networkType) {
    switch (networkType) {
        case NETWORK_TYPE_GPRS:
        case NETWORK_TYPE_GSM:
        case NETWORK_TYPE_EDGE:
        case NETWORK_TYPE_CDMA:
        case NETWORK_TYPE_1xRTT:
        case NETWORK_TYPE_IDEN:
            return NETWORK_CLASS_2_G;
        case NETWORK_TYPE_UMTS:
        case NETWORK_TYPE_EVDO_0:
        case NETWORK_TYPE_EVDO_A:
        case NETWORK_TYPE_HSDPA:
        case NETWORK_TYPE_HSUPA:
        case NETWORK_TYPE_HSPA:
        case NETWORK_TYPE_EVDO_B:
        case NETWORK_TYPE_EHRPD:
        case NETWORK_TYPE_HSPAP:
        case NETWORK_TYPE_TD_SCDMA:
            return NETWORK_CLASS_3_G;
        case NETWORK_TYPE_LTE:
        case NETWORK_TYPE_IWLAN:
        case NETWORK_TYPE_LTE_CA:
            return NETWORK_CLASS_4_G;
        default:
            return NETWORK_CLASS_UNKNOWN;
    }
}

我们可以根据这个 networkType 的值,判断不同的网络制式,比如,如果 networkType == 1 那个是 GPRS 这种制式的,而这个networkType的值可以通过

/**
 * Returns a string representation of the radio technology (network type)
 * currently in use on the device.
 * @return the name of the radio technology
 *
 * @hide pending API council review
 */
public String getNetworkTypeName() {
    return getNetworkTypeName(getNetworkType());
}

/**
 * Returns a string representation of the radio technology (network type)
 * currently in use on the device.
 * @param subId for which network type is returned
 * @return the name of the radio technology
 *
 */
/** {@hide} */
public static String getNetworkTypeName(int type) {
    switch (type) {
        case NETWORK_TYPE_GPRS:
            return "GPRS";
        case NETWORK_TYPE_EDGE:
            return "EDGE";
        case NETWORK_TYPE_UMTS:
            return "UMTS";
        case NETWORK_TYPE_HSDPA:
            return "HSDPA";
        case NETWORK_TYPE_HSUPA:
            return "HSUPA";
        case NETWORK_TYPE_HSPA:
            return "HSPA";
        case NETWORK_TYPE_CDMA:
            return "CDMA";
        case NETWORK_TYPE_EVDO_0:
            return "CDMA - EvDo rev. 0";
        case NETWORK_TYPE_EVDO_A:
            return "CDMA - EvDo rev. A";
        case NETWORK_TYPE_EVDO_B:
            return "CDMA - EvDo rev. B";
        case NETWORK_TYPE_1xRTT:
            return "CDMA - 1xRTT";
        case NETWORK_TYPE_LTE:
            return "LTE";
        case NETWORK_TYPE_EHRPD:
            return "CDMA - eHRPD";
        case NETWORK_TYPE_IDEN:
            return "iDEN";
        case NETWORK_TYPE_HSPAP:
            return "HSPA+";
        case NETWORK_TYPE_GSM:
            return "GSM";
        case NETWORK_TYPE_TD_SCDMA:
            return "TD_SCDMA";
        case NETWORK_TYPE_IWLAN:
            return "IWLAN";
        case NETWORK_TYPE_LTE_CA:
            return "LTE_CA";
        default:
            return "UNKNOWN";
    }
}

即这个 getNetworkType() 方法获得!好了,就这么简单,可以像上面列好一个数组然后根据 不同的下标显示不同的值!

Sim 卡状态的,字符串数组中的值

/**
     * Returns a constant indicating the state of the default SIM card.
     *
     * @see #SIM_STATE_UNKNOWN
     * @see #SIM_STATE_ABSENT
     * @see #SIM_STATE_PIN_REQUIRED
     * @see #SIM_STATE_PUK_REQUIRED
     * @see #SIM_STATE_NETWORK_LOCKED
     * @see #SIM_STATE_READY
     * @see #SIM_STATE_NOT_READY
     * @see #SIM_STATE_PERM_DISABLED
     * @see #SIM_STATE_CARD_IO_ERROR
     * @see #SIM_STATE_CARD_RESTRICTED
     */
    public int getSimState() {
        int slotIndex = getSlotIndex();
        // slotIndex may be invalid due to sim being absent. In that case query all slots to get
        // sim state
        if (slotIndex < 0) {
            // query for all slots and return absent if all sim states are absent, otherwise
            // return unknown
            for (int i = 0; i < getPhoneCount(); i++) {
                int simState = getSimState(i);
                if (simState != SIM_STATE_ABSENT) {
                    Rlog.d(TAG, "getSimState: default sim:" + slotIndex + ", sim state for " +
                            "slotIndex=" + i + " is " + simState + ", return state as unknown");
                    return SIM_STATE_UNKNOWN;
                }
            }
            Rlog.d(TAG, "getSimState: default sim:" + slotIndex + ", all SIMs absent, return " +
                    "state as absent");
            return SIM_STATE_ABSENT;
        }
        return getSimState(slotIndex);
    }

参考文档

  1. Android TelephonyManager 官方 API

  2. Android电话信息相关 API

Android 基础教程

关于   |   FAQ   |   我们的愿景   |   广告投放   |  博客

  简单教程,简单编程 - IT 入门首选站

Copyright © 2013-2022 简单教程 twle.cn All Rights Reserved.