广播BroadcastReceiver(2)

  有序广播的优先级:
       发送有序广播的方法有:
   public void sendOrderedBroadcast(Intent intent,String receiverPermission)


       在接收有序广播时,能够自己为接收者指定优先级:
            静态注冊广播接收者时,在AndroidMainfest.xml文件里为<receiver>的<intent-filter>节点配置
 android:priority属性;
   动态注冊广播接收者时。调用IntentFilter对象的setPriority()方法;
   有序广播的优先级:
      优先级属性值越大,则优先级越高;
      优先级属性同样时,动态注冊的广播接收者优先级高于静态注冊的广播接收者。
      同为静态/动态注冊的广播接收者。且优先级同样时,越早注冊的优先级越高。
      同为静态注冊的广播接收者。且优先级同样,但归属于不同的应用程序时,
      按系统载入应用程序的先后顺序确定优先级(通常表现为按应用程序的包名排序);
   始终接收广播的方法:
       某些应用程序可能须要始终接收特定的广播。比如手机管理类软件,则须要始终接收主叫、
来电、短信等广播,为了正常接收到这些广播。且让自己的应用程序处于高优先级,一般会:
    使用一个静态注冊的广播接收者。接收开机广播;
    接收到开机广播后,启动一个Service在后台执行;
    在后台执行的Service中,动态的广播接收者,接收业务所需的广播。
    
            有序广播的传递
         中止有序广播
      在广播接收者中,调用abortBroadcast()则能够中止有序广播的继续传递。
      即优先级更低的BroadcastReceiver将不会收到该广播;
      须要注意的是:使用该方法仅能用于接收有序广播,假设接收普通广播时调用
      该方法则会导致程序异常。
 在广播接收者们之间传递数据:
       在有序广播的传递过程中,能够调用setResultXXX()系列方法设置数据,
比如:setResultData()、setResultExtras()等,并使用getResultXXX()系列方法获取这些数据。
管理呼出电话
    呼出电话的广播为:
         android.intent.action.NEW_OUTGOING_CALL
 对呼出电话的管理的原理:
        呼出电话是从拨号到呼叫的过程,当呼出电话时,系统会发出呼叫电话的有序广播,而且将须要呼叫的电话号码
使用setResultData()进行传递。处理程序接收到该广播后运行呼叫。


处理呼叫的程序接收该广播的优先级较低,因此,自己定义广播接收者。

在接收到呼出电话的广播后,改动setResult()传递的电话号码。就可以实现对呼出电话的管理。

对呼出的电话进行操作的实例:

        Activity不用改动。默认状态就可以。

这里仅仅给出广播:

package com.example.chargecall;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

public class OutReceiver extends BroadcastReceiver{

	@Override
	public void onReceive(Context context, Intent intent) {
		// 改动呼出的电话号码:
		/*能够对电话号码进行多种操作。假设想要禁止呼出的电话号码,能够直接设置为空值
		 * 
		 * */
		String number = getResultData();
		number = "12345" + number;
		setResultData(number);
		
	}

}

在AndroidMainfest.xml中加入权限跟receiver:

       <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>

 <receiver android:name="com.example.chargecall.OutReceiver" >
            <intent-filter>
                <action android:name="android.intent.action.NEW_OUTGOING_CALL"/>
            </intent-filter>
        </receiver>


对呼入的电话进行拦截:
        拦截呼入电话的实现原理:
     当存在呼入电话时,系统发出例如以下广播:
           android.intent.action.PHONE_STATE
TeleohyManager是电话管理器,为其配置PhoneStateListener就可以监听相关状态(响铃、通话、空暇),且
该监听器的会调方法中可获取来电号码;
调用ITelephony接口定义的boolean endCall()方法就可以挂断电话。通过TelephonyManager的getTelephony()

方法就可以获得ITelephony接口的对象。

对呼入的电话进行操作的实例:

       相同的。主界面使用默认的就可以,

给出广播:

       

package com.example.interceptcall;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import com.android.internal.telephony.ITelephony;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.RemoteException;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;


public class PhoneStateReceiver extends BroadcastReceiver {
	TelephonyManager manager;

	@Override
	public void onReceive(Context context, Intent intent) {
		manager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
		PhoneStateListener listener = new InnerPhoneStateListener();
		int events = PhoneStateListener.LISTEN_CALL_STATE;
		manager.listen(listener, events);

	}
 
	private ITelephony getITelephony(){
		ITelephony iTelephony = null;
		Method method = null;
		try {
			method = TelephonyManager.class.getDeclaredMethod("getITelephony", (Class[])null);
		    method.setAccessible(true);
		    iTelephony =  (ITelephony) method.invoke(manager, null);
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
		return iTelephony;
	}
	private class InnerPhoneStateListener extends PhoneStateListener{

		@Override
		public void onCallStateChanged(int state, String incomingNumber) {
			// TODO Auto-generated method stub
			switch (state) {
			case TelephonyManager.CALL_STATE_IDLE://空暇状态
				
				break;
			case TelephonyManager.CALL_STATE_OFFHOOK://通话状态
				
				break;
			case TelephonyManager.CALL_STATE_RINGING://响铃状态
				   if("15539187816".equals(incomingNumber)){//挂断电话
					   try {
						getITelephony().endCall();
					} catch (RemoteException e) {
						e.printStackTrace();
					}
				   }
				break;

			}
			super.onCallStateChanged(state, incomingNumber);
		}
		
	}
}
因为不能识别ITelephony,还须要自己定义aidl接口,这样才干够,

ITelephony:

package com.android.internal.telephony;

interface ITelephony {
      boolean endCall();
}

注意包名要使用这里边的包名,

相同,要把权限加到AndroidMainfest.xml中,还要把写好的广播加入到这里边。

posted @ 2017-06-18 12:02  claireyuancy  阅读(272)  评论(0编辑  收藏  举报