TelephonyManager (gestionnaire de téléphone)


Introduction à cette section :

Ce chapitre est le dernier chapitre du didacticiel d'introduction de base d'Android. Il explique principalement quelques points de connaissances épars et quelques omissions. Pour compléter les points de connaissances, ces points de connaissances dispersés incluent l'utilisation de divers services système, tels que le gestionnaire de téléphone et le gestionnaire de SMS dans cette section. Vibrateurs, réveils, fonds d'écran, etc., capteurs et autres ! C'est le bordel et tout ! D'accord, ce que nous allons apprendre dans cette section Il s'agit de TelephonyManager, comme son nom l'indique : utilisé pour gérer l'état des appels du téléphone mobile, obtenir des informations sur le téléphone (informations sur l'appareil, informations sur la carte SIM et Informations réseau), écoutez l'état du téléphone (état du service d'appel, état de la force du signal, etc.) et pouvez appeler le numéroteur téléphonique pour passer des appels ! Sans plus tarder, commençons cette section~

API officielle :TelephonyManager


1 Obtenez l'objet de service de TelephonyManager

<🎜. >

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


Exemple d'utilisation


1) Appelez le numéroteur pour composer le numéro. numéro de téléphone

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


2) Obtenir des informations sur la carte SIM et des informations sur le réseau

Exécution des rendus :

1.png

Code d'implémentation  :

Fichier de mise en page :

activity_main.xml :

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="5dp"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/tv_phone1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="20sp" />

    <TextView
        android:id="@+id/tv_phone2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="20sp" />

    <TextView
        android:id="@+id/tv_phone3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="20sp" />

    <TextView
        android:id="@+id/tv_phone4"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="20sp" />

    <TextView
        android:id="@+id/tv_phone5"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="20sp" />

    <TextView
        android:id="@+id/tv_phone6"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="20sp" />

    <TextView
        android:id="@+id/tv_phone7"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="20sp" />

    <TextView
        android:id="@+id/tv_phone8"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="16sp" />

    <TextView
        android:id="@+id/tv_phone9"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="20sp" /></LinearLayout>

MainActivity.java :

public class MainActivity extends AppCompatActivity {

    private TextView tv_phone1;
    private TextView tv_phone2;
    private TextView tv_phone3;
    private TextView tv_phone4;
    private TextView tv_phone5;
    private TextView tv_phone6;
    private TextView tv_phone7;
    private TextView tv_phone8;
    private TextView tv_phone9;
    private TelephonyManager tManager;
    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);
        //①获得系统提供的TelphonyManager对象的实例
        tManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
        bindViews();
    }

    private void bindViews() {
        tv_phone1 = (TextView) findViewById(R.id.tv_phone1);
        tv_phone2 = (TextView) findViewById(R.id.tv_phone2);
        tv_phone3 = (TextView) findViewById(R.id.tv_phone3);
        tv_phone4 = (TextView) findViewById(R.id.tv_phone4);
        tv_phone5 = (TextView) findViewById(R.id.tv_phone5);
        tv_phone6 = (TextView) findViewById(R.id.tv_phone6);
        tv_phone7 = (TextView) findViewById(R.id.tv_phone7);
        tv_phone8 = (TextView) findViewById(R.id.tv_phone8);
        tv_phone9 = (TextView) findViewById(R.id.tv_phone9);

        tv_phone1.setText("设备编号:" + tManager.getDeviceId());
        tv_phone2.setText("软件版本:" + (tManager.getDeviceSoftwareVersion()!= null?
                tManager.getDeviceSoftwareVersion():"未知"));
        tv_phone3.setText("运营商代号:" + tManager.getNetworkOperator());
        tv_phone4.setText("运营商名称:" + tManager.getNetworkOperatorName());
        tv_phone5.setText("网络类型:" + phoneType[tManager.getPhoneType()]);
        tv_phone6.setText("设备当前位置:" + (tManager.getCellLocation() != null ? tManager
                .getCellLocation().toString() : "未知位置"));
        tv_phone7.setText("SIM卡的国别:" + tManager.getSimCountryIso());
        tv_phone8.setText("SIM卡序列号:" + tManager.getSimSerialNumber());
        tv_phone9.setText("SIM卡状态:" + simState[tManager.getSimState()]);
    }
}

Au fait, n'oubliez pas d'ajouter des autorisations dans AndroidManifest.xml !

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

Au fait, vous souhaitez peut-être obtenir le standard réseau au lieu du 2G, 3G, 4G ordinaire. En fait, nous pouvons aller au code source de la classe TelephonyManager :

.

2.png

Nous pouvons juger différentes normes de réseau en fonction de la valeur de ce networkType, par exemple, si networkType == 1 Celui-ci est GPRS~ et la valeur de ce networkType peut être obtenue via

3.png

, c'est-à-dire la méthode getNetworkType() ! D'accord, c'est aussi simple que cela. Vous pouvez lister un tableau comme ci-dessus, puis l'utiliser. Différents indices affichent des valeurs différentes ! À propos, il y a aussi le statut et les valeurs de la carte Sim dans le tableau de chaînes, qui peuvent être consultés dans le code source :

4.png

D'autres peuvent être explorés par vous-même~


3) Obtenez la force du signal du téléphone mobile

L'unité de force du signal réseau est le dBm (milliwatt décibel), qui est généralement exprimé sous forme de nombre négatif. La plage normale du signal d'un téléphone mobile est de -110 dBm. Entre (médiocre) et -50 dBm (bon), s'il est inférieur à -50 dBm, cela signifie que vous vous trouvez près de la station de base, comme mon écran n5 La force du signal est de -51 dBm, parfois de -59 dBm, car le bâtiment Nansoft est à côté et il y a une station de base au-dessus...

De plus, la manière d'obtenir la force du signal en 2G, 3G et 4G consiste à remplacer onSignalStrengthsChanged() de PhoneStateListener. Méthode, cet événement sera déclenché lorsque la force du signal change. Nous pouvons obtenir la force du signal dans cet événement !

Exemple de code pour obtenir la force du signal sur un téléphone portable :

dBm =-113+2*asuIl s'agit d'une formule fixe , asu (Unité de signalisation indépendante)

Rendu des opérations :

5.png

Code d'implémentation :

MainActivity.java :

public class MainActivity extends AppCompatActivity {

    private TextView tv_rssi;
    private MyPhoneStateListener mpsListener;
    private TelephonyManager tManager;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tManager = ((TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE));
        tv_rssi = (TextView) findViewById(R.id.tv_rssi);
        mpsListener  = new MyPhoneStateListener();
        tManager.listen(mpsListener,290);
    }

    private class MyPhoneStateListener extends PhoneStateListener {
        private int asu = 0,lastSignal = 0;
        @Override
        public void onSignalStrengthsChanged(SignalStrength signalStrength) {
            asu = signalStrength.getGsmSignalStrength();
            lastSignal = -113 + 2 * asu;
            tv_rssi.setText("当前手机的信号强度:" + lastSignal + " dBm" );
            super.onSignalStrengthsChanged(signalStrength);
        }
    }
}

De plus, comme les cartes de l'auteur sont toutes des cartes mobiles, je ne connais pas China Unicom et Telecom, mais j'ai vu plusieurs API comme celle-ci de le code source :

  • getEvdoDbm() : China Telecom 3G
  • getCdmaDbm() : China Unicom 3G
  • getLteDbm() : 4G

Ceux-ci devraient pouvoir obtenir directement la force du signal en dBm Si vous avez les conditions, vous pouvez l'essayer~

Aussi. , n'oubliez pas d'ajouter des autorisations !

<!-- 添加访问手机状态的权限 -->
 <uses-permission android:name="android.permission.READ_PHONE_STATE"/>

4) Surveillez tous les appels entrants sur votre téléphone mobile

Pour les résultats de l'enregistrement des appels surveillés, vous pouvez les obtenir de différentes manières. Ce qui est utilisé ici est de. Les enregistrements sont écrits dans un fichier, Et vous pouvez également vous l'envoyer sous forme de messages texte, ou le télécharger sur une certaine plateforme. Bien sûr, s'il n'y a pas beaucoup d'enregistrements de communication, vous pouvez également utiliser des messages texte. S’il y en a plus, ce sera facile à découvrir pour les autres ! De plus, Activity est utilisé ici à la place de Service, ce qui signifie ouvrir cette Activité, Ce n'est qu'alors que nous pouvons surveiller. Habituellement, nos besoins doivent être exécutés secrètement en arrière-plan. En raison de contraintes de temps, nous n'écrirons pas le service si nécessaire. Vous pouvez le modifier vous-même et laisser le Service démarrer dès le démarrage !

Analyse du code :

C'est très simple, c'est en fait juste une réécriture de TelephonyManager L'écouteur d'état de l'appelPhoneStateListener appelle ensuite la méthode TelephonyManager.listen() pour écouter Lorsqu'un appel arrive, Le programme enregistrera le numéro de l'appelant dans le fichier !

Code d'implémentation:

MainActivity.java:

public class MainActivity extends Activity  
{  
    TelephonyManager tManager;  
  
    @Override  
    public void onCreate(Bundle savedInstanceState)  
    {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.main);  
        // 取得TelephonyManager对象  
        tManager = (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:  
                        OutputStream os = null;  
                        try  
                        {  
                            os = openFileOutput("phoneList", MODE_APPEND);  
                        }  
                        catch (FileNotFoundException e)  
                        {  
                            e.printStackTrace();  
                        }  
                        PrintStream ps = new PrintStream(os);  
                        // 将来电号码记录到文件中  
                        ps.println(new Date() + " 来电:" + number);  
                        ps.close();  
                        break;  
                    default:  
                        break;  
                }  
                super.onCallStateChanged(state, number);  
            }  
        };  
        // 监听电话通话状态的改变  
        tManager.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);  
    }  
}

Résultat d'exécution :

Attention ! Gardez ce programme au premier plan ! Utilisez un autre téléphone pour composer le numéro, et vous pourrez ensuite utiliser l'application Explorateur de fichiers DDMS. Nous pouvons voir le fichier phoneList dans le répertoire des fichiers correspondant au nom du package. Nous pouvons l'exporter vers l'ordinateur et l'ouvrir. Le contenu approximatif du fichier est le suivant :

THR 30 octobre 12h05 : 48 GMT 2014 Appel : 137xxxxxxxx

Au fait, n'oubliez pas les autorisations !

<!-- 授予该应用读取通话状态的权限 -->  
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>

5) Les appels de la liste noire sont automatiquement raccrochés

La soi-disant liste noire consiste à ajouter certains numéros de téléphone à une collection lorsque le téléphone mobile reçoit ces appels. raccrocher! Mais Android ne nous fournit pas d'API pour raccrocher le téléphone, nous devons donc appeler l'API dans le service via AIDL. Raccrochez le téléphone !

La première étape consiste donc à copier les deux fichiers suivants dans le code source Android aux emplacements correspondants sous src. Pour créer le package correspondant ! Mettez simplement le fichier aidl sous le package ci-dessus !!! Il vous suffit ensuite d'appeler endCall d'ITelephony pour raccrocher l'appel !

Ce qui est donné ici est une simple interception d'un seul numéro après avoir saisi le numéro et cliqué sur le bouton bouclier, si l'appel est bloqué. entre à ce moment-là des mots ; Il raccrochera directement. Le code est relativement simple. Collez-le ci-dessous. Le simulateur utilisé étant Genymotion, je ne le démontrerai pas. Capture d'écran après l'exécution du programme !

MainActivity.java

:

public class MainActivity extends Activity {  
  
    private TelephonyManager tManager;  
    private PhoneStateListener pListener;  
    private String number;  
    private EditText locknum;  
    private Button btnlock;  
      
    public class PhonecallListener extends PhoneStateListener  
    {  
        @Override  
        public void onCallStateChanged(int state, String incomingNumber) {  
            switch(state)  
            {  
            case TelephonyManager.CALL_STATE_IDLE:break;  
            case TelephonyManager.CALL_STATE_OFFHOOK:break;  
            //当有电话拨入时  
            case TelephonyManager.CALL_STATE_RINGING:  
                if(isBlock(incomingNumber))  
                {  
                    try  
                    {  
                        Method method = Class.forName("android.os.ServiceManager")  
                                .getMethod("getService", String.class);  
                        // 获取远程TELEPHONY_SERVICE的IBinder对象的代理  
                        IBinder binder = (IBinder) method.invoke(null,  
                            new Object[] { TELEPHONY_SERVICE });  
                        // 将IBinder对象的代理转换为ITelephony对象  
                        ITelephony telephony = ITelephony.Stub.asInterface(binder);  
                        // 挂断电话  
                        telephony.endCall();  
                    }catch(Exception e){e.printStackTrace();}  
                }  
                break;  
            }  
            super.onCallStateChanged(state, incomingNumber);  
        }  
    }  
      
      
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  
          
        locknum = (EditText) findViewById(R.id.locknum);  
        btnlock = (Button) findViewById(R.id.btnlock);  
          
        //获取系统的TelephonyManager管理器  
        tManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);  
        pListener = new PhoneStateListener();  
        tManager.listen(pListener, PhoneStateListener.LISTEN_CALL_STATE);  
          
        btnlock.setOnClickListener(new OnClickListener() {  
              
            @Override  
            public void onClick(View v) {  
                number = locknum.getText().toString();                
            }  
        });  
          
    }  
      
    public boolean isBlock(String phone)  
    {  
        if(phone.equals(number))return true;  
        return false;  
    }  
}

Autorisations, autorisations, autorisations

:

<!-- 授予该应用控制通话的权限 -->  
<uses-permission android:name="android.permission.CALL_PHONE" />    
<!-- 授予该应用读取通话状态的权限 -->  
<uses-permission android:name="android.permission.READ_PHONE_STATE" />

Aussi , la version chinoise des propriétés et méthodes associées peut être consultée : API relative aux informations sur le téléphone Android

Téléchargez l'exemple de code dans cette section

<🎜. >TelephonyManagerDemo.zip

TelephonyManagerDemo2.zip

Liste noire d'interception Demo.zip

Résumé de cette section :

D'accord, cette section sur TelephonyManager (gestionnaire de téléphone) se termine ici, elle aurait dû être couverte La plupart des exigences de développement ont été remplies. S'il manque quelque chose, n'hésitez pas à le mentionner ~

Merci~