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;
            }
        }

    }
}
原文地址:https://www.cnblogs.com/bobodeboke/p/3102484.html