• android实现来去电监听的实现


    通过本案例,主要学习以下几点:

    (1)通过查看api文档,找到实现相应功能所需要的,intent的action属性,其对应的extra字段,以及所需要的相关权限。

    (2)对于仅在后台运行的服务,如何开启。例如本案例并没有前台界面,仅仅需要在后台开启一个servcie进行实时监听,然而service需要启动时机,因此考虑利用广播来启动。监听系统开机的广播事件,在其receive方法中,开启后台服务。(考虑过如果仅仅监听来电,是否可以在onreceive方法中之间为系统的telephoneService设置对应的监听事件,不过这种方法,总比不上自己重写一个服务更优美《一方面因为onrecive的周期大概10秒左右,另一方面,添加监听事件一般仅需要一次,没有必要每一次onreceive都为其设置监听事件,多次设置甚至会出错?,后来在api文档中发现这么一句话,不知道是不是由于这个原因:

    In particular, you may not show a dialog or bind to a service from within a BroadcastReceiver. For the former, you should instead use the NotificationManagerAPI. For the latter, you can use Context.startService() to send a command to the service》)。这个思路很重要,可以用在自己的项目中需要开启服务向服务器段上传数据的需求中。

    首先看配置文件:

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="org.lxh.demo" 
        android:versionCode="1" 
        android:versionName="1.0">
        <uses-sdk android:minSdkVersion="10" />
        <application 
            android:icon="@drawable/icon" android:label="@string/app_name">
            <receiver 
                android:name=".PhoneBroadcastReceiver">
                <intent-filter>
                    <action 
                        android:name="android.intent.action.PHONE_STATE" />   
    <action android:name="android.intent.action.BOOT_COMPLETED" /> <action android:name="android.intent.action.NEW_OUTGOING_CALL" /> </intent-filter> </receiver> <service android:name=".PhoneService" /> </application> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" /> </manifest>

    之前总是感觉很神奇,不知到这些action字段、权限字段从何而来,因为纯粹是经验的积累,其实这些在api文档中都能找到。

    接着看receiver的实现类:

    package org.lxh.demo;
    
    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;
    
    public class PhoneBroadcastReceiver extends BroadcastReceiver {    // ¹ã²¥ŽŠÀí
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(
                    Intent.ACTION_NEW_OUTGOING_CALL)) {             // È¥µç²Ù×÷
                String outgoingNumber = intent
                    .getStringExtra(Intent.EXTRA_PHONE_NUMBER);     // È¡µÃÈ¥µçºÅÂë
                Intent pit = new Intent(context, PhoneService.class);    // ¶šÒåIntent
                pit.putExtra("outgoingNumber", outgoingNumber);     // ±£ŽæÈ¥µçºÅÂë
                context.startService(pit);                             // Æô¶¯Service
            } else {                                                 // ÀŽµç
                context.startService(new Intent(
                        context, PhoneService.class));                 // Æô¶¯Service
            }
        }
    
    }

    不要在receiver中进行复杂的操作,如本例子中,仅仅是开启对应的服务。

    之后就是自己编写的服务类:

    package org.lxh.demo;
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    import android.app.Service;
    import android.content.Context;
    import android.content.Intent;
    import android.os.IBinder;
    import android.telephony.PhoneStateListener;
    import android.telephony.TelephonyManager;
    
    public class PhoneService extends Service {
        private TelephonyManager telephony = null;                     // µç»°¹ÜÀíÆ÷
        private String outgoingNumber = null;                         // ±£ÁôÈ¥µçºÅÂë
    
        @Override
        public void onCreate() {
            this.telephony = (TelephonyManager) super
                    .getSystemService(Context.TELEPHONY_SERVICE);     // È¡µÃ·þÎñ
            this.telephony.listen(new PhoneStateListenerImpl(),
                    PhoneStateListener.LISTEN_CALL_STATE);             // ÉèÖõ绰ŒàÌý
            super.onCreate();
        }
    
        @Override
        public void onStart(Intent intent, int startId) {            // Æô¶¯·þÎñ
            // Ö»ÓÐÍš¹ýonStart()·œ·š²Å¿ÉÒÔÈ¡µÃÍš¹ýIntentŽ«µÝ¹ýÀŽµÄÊýŸÝ£¬¶øÈ¥µçºÅÂ뜫͚¹ýŽË·œÊœŽ«µÝ
            this.outgoingNumber = intent.getStringExtra("outgoingNumber"); // È¡µÃÈ¥µçºÅÂë
            super.onStart(intent, startId);
        }
    
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }
    
        private class PhoneStateListenerImpl extends PhoneStateListener {    // µç»°ŒàÌý
            @Override
            public void onCallStateChanged(int state, String incomingNumber) { // žÄ±äºôœÐ׎̬
                switch (state) {                                    // ÅжÏ׎̬
                case TelephonyManager.CALL_STATE_IDLE:                 // ûÓвŠÈë»ò²Š³öµç»°²Ù×÷׎̬
                    break;
                case TelephonyManager.CALL_STATE_RINGING:            // Óе绰œøÈë
                    System.out.println("²ŠÈëµç»°ºÅÂ룺"
                            + incomingNumber
                            + "£¬²ŠÈëʱŒä£º"
                            + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
                                    .format(new Date()));            // ºóÌšÊä³ö
                    break;
                case TelephonyManager.CALL_STATE_OFFHOOK:            // ʹÓõ绰
                    System.out.println("²Š³öµç»°ºÅÂ룺"
                            + PhoneService.this.outgoingNumber
                            + "£¬²ŠÈëʱŒä£º"
                            + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
                                    .format(new Date()));            // ºóÌšÊä³ö
                    break;
                }
            }
    
        }
    }
  • 相关阅读:
    结构与联合
    信号与槽知识点
    函数
    元对象编译器moc
    堆与栈
    More Effective C++ (虚拟构造函数)
    重载 覆盖 隐藏
    继承专题
    PowerDesigner 的常用方法(转)
    搜狗输入法导入Google词库bug
  • 原文地址:https://www.cnblogs.com/bobodeboke/p/3102484.html
Copyright © 2020-2023  润新知