20190401_16.04
来电监听:补充完成 2、3、4处的逻辑即可
package com.sc.broad;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import com.sc.call.CallProcess;
/* AndroidManifest.xml添加配置
*/
/** 来电、去电广播监听 */
public class CallReceiver extends BroadcastReceiver
{
private Context context;
@Override
public void onReceive(Context context, Intent intent)
{
this.context = context;
String action = intent.getAction();
// Toast.makeText(context, "action" + action, Toast.LENGTH_SHORT).show();
if (action.equals("android.intent.action.NEW_OUTGOING_CALL"))
{ // 接收到去电广播,执行去电处理逻辑
// IntentFilter intentFilter = new IntentFilter(Intent.ACTION_NEW_OUTGOING_CALL);
// context.registerReceiver(this, intentFilter);
// String phoneNumber = getResultData();
String phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
phoneNumber = phoneNumber.replace("-", "").replace(" ", ""); // 剔除号码中的分隔符
//1、// CallProcess.OutCall(context, phoneNumber); // 去电处理逻辑
}
else if (action.equals("android.intent.action.PHONE_STATE"))
{ // 接收到来电广播,执行来电监听处理逻辑
TelephonyManager tm = (TelephonyManager) context.getSystemService(Service.TELEPHONY_SERVICE);
tm.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);
}
}
private PhoneStateListener listener = new PhoneStateListener()
{
@Override
public void onCallStateChanged(int state, String phoneNumber)
{
super.onCallStateChanged(state, phoneNumber);
phoneNumber = phoneNumber.replace("-", "").replace(" ", ""); // 剔除号码中的分隔符
switch (state)
{
case TelephonyManager.CALL_STATE_IDLE:
//2、// CallProcess.HungUp(context, phoneNumber); // 空闲/挂断处理逻辑
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
//3、// CallProcess.OffHook(context, phoneNumber); // 接听处理逻辑
break;
case TelephonyManager.CALL_STATE_RINGING: // 来电处理逻辑
//4、// CallProcess.Ringing(context, phoneNumber);
break;
}
}
};
}
来电 接听、挂断
以下内容忽略:
电话状态(来电、接听、挂断、拨打电话)监听逻辑:
package com.sc.call;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
/**
* CallListener.java: 来电状态监听、去电监听。
* 用法:创建CallListener实例,并重写电话相关的四个abstract抽象函数即可。
* new CallListener(context){...};
*
* 需要添加权限:
* uses-permission android:name="android.permission.READ_PHONE_STATE"
* uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"
* -----
* 2019-1-9 上午10:16:06
* scimence
*/
public abstract class CallListener
{
CallListener Instance;
CallInListener callin; // 来电监听
OutCallListener callout; // 拨出监听
public CallListener(Context context)
{
Instance = this;
callin = new CallInListener(context)
{
@Override
public void Ringing(String phoneNumber)
{
Instance.Ringing(phoneNumber);
}
@Override
public void OffHook(String phoneNumber)
{
Instance.OffHook(phoneNumber);
}
@Override
public void HungUp(String phoneNumber)
{
Instance.HungUp(phoneNumber);
}
};
callout = new OutCallListener(context)
{
@Override
public void OutCall(String phoneNumber)
{
Instance.OutCall(phoneNumber);
}
};
}
/** 响铃时执行逻辑 */
public abstract void Ringing(String phoneNumber);
/** 接听时执行逻辑 */
public abstract void OffHook(String phoneNumber);
/** 挂断时执行逻辑 */
public abstract void HungUp(String phoneNumber);
/** 去电时执行逻辑 */
public abstract void OutCall(String phoneNumber);
}
/**
* 来电状态监听。
*
*
* */
abstract class CallInListener extends PhoneStateListener
{
TelephonyManager phoneManager;
public CallInListener(Context context)
{
phoneManager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
Listen();
}
/** 监听来电状态 */
public void Listen()
{
phoneManager.listen(this, PhoneStateListener.LISTEN_CALL_STATE); // 在系统服务上,为当前Listener注册CALL_STATE状态监听
}
/** 不再监听 */
public void ClearListen()
{
phoneManager.listen(this, PhoneStateListener.LISTEN_NONE);
}
/** 重写监听来电状态 */
public void onCallStateChanged(int state, String phoneNumber)
{
if(state == TelephonyManager.CALL_STATE_IDLE) // 空闲/挂断
{
HungUp(phoneNumber);
}
else if(state == TelephonyManager.CALL_STATE_RINGING) // 响铃
{
Ringing(phoneNumber);
}
else if(state == TelephonyManager.CALL_STATE_OFFHOOK) // 接听
{
OffHook(phoneNumber);
}
}
/** 响铃时执行逻辑 */
public abstract void Ringing(String phoneNumber);
/** 接听时执行逻辑 */
public abstract void OffHook(String phoneNumber);
/** 挂断时执行逻辑 */
public abstract void HungUp(String phoneNumber);
}
/**
* 去电监听。
*
*
* */
abstract class OutCallListener extends BroadcastReceiver
{
Context context;
public OutCallListener(Context context)
{
this.context = context;
Listen();
}
/** 监听来电状态 */
public void Listen()
{
IntentFilter intentFilter = new IntentFilter(Intent.ACTION_NEW_OUTGOING_CALL);
context.registerReceiver(this, intentFilter);
}
/** 不再监听 */
public void ClearListen()
{
context.unregisterReceiver(this);
}
/** 重写监听去电事件 */
public void onReceive(Context context, Intent intent)
{
String phoneNumber = getResultData();
OutCall(phoneNumber);
}
/** 去电时执行逻辑 */
public abstract void OutCall(String phoneNumber);
}
简易调用:(引入CallProcess.jar,改写CallProcess.java)
{
CallProcess.jar下载
package com.sc.call;
//import java.util.ArrayList;
import android.content.Context;
import android.widget.Toast;
//
// 整体调用逻辑:
// (1)从BroadCast_Start广播接收到的系统事件(开机、锁屏等)启动服务CallService;
// (2)在CallService中添加来电、拨出事件监听,在监听到电话事件(来电、接听、挂断、拨打电话)后进行事件处理
// (3)在CallService中调用CallProcess中编写好的逻辑
//-----
// 2019-1-9 上午10:16:06
// scimence
/** 接入逻辑(在AndroidManifest.xml中)
*
* 1、添加权限:
* uses-permission android:name="android.permission.READ_PHONE_STATE"
* uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"
*
* 2、添加receiver和service
....
*
*
* 3、电话事件处理逻辑:改写该类中的处理逻辑(实现来电、接听、挂断、拨出 事件逻辑)
*
* 备注:若改变当前类名、路径,请在CallService.CallLogic()中修改调用
* */
public class CallProcess
{
/** 添加来电处理逻辑 */
public static void Ringing(Context context, String phoneNumber)
{
// TODO 添加来电相关处理逻辑
Toast.makeText(context, "来电相关处理逻辑!", Toast.LENGTH_SHORT).show();
}
/** 添加接听处理逻辑 */
public static void OffHook(Context context, String phoneNumber)
{
// TODO 添加接听相关处理逻辑
Toast.makeText(context, "接听相关处理逻辑!", Toast.LENGTH_SHORT).show();
}
/** 添加挂断处理逻辑 */
public static void HungUp(Context context, String phoneNumber)
{
// TODO 添加挂断相关处理逻辑
Toast.makeText(context, "挂断相关处理逻辑!", Toast.LENGTH_SHORT).show();
}
/** 添加拨出处理逻辑 */
public static void OutCall(Context context, String phoneNumber)
{
// TODO 添加拨出相关处理逻辑
Toast.makeText(context, "拨出相关处理逻辑!", Toast.LENGTH_SHORT).show();
}
}
}简易调用结束
相关源码附录:
package com.sc.broad;
//import java.util.HashMap;
import com.sc.service.CallService;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
/* 需在AndroidManifest.xml添加广播静态配置,中添加需要监听的广播类型
...
*/
/** AndroidManifest.xml的静态注册广播(安装app时会自动注册,app未运行时也可正常接收广播 )
*
* 用法:无需调用,通过开启、锁屏 广播启动电话监听Service */
public class BroadCast_Start extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent)
{
String action = intent.getAction();
Broad(action, context, intent);
}
/** 广播回调,action为广播类型 */
public void Broad(String action, Context context, Intent intent)
{
// if(action.equals("android.intent.action.BOOT_COMPLETED"))
// {
// CallService.GetInstance().start(context, CallService.class);
CallService.GetInstance().start(context, CallService.class, 500);
// }
}
// ------------
// /** 发送自定义广播,action广播名称 如:"com.sc.broad.actionDemo"; extData广播附带的数据; extName广播数据对应的名称 */
// public void SendBroadCast(Context context, String action, String extName, String extData)
// {
// BroadCastTool.SendBroadCast(context, action, extName, extData);
// }
//
// /** 发送自定义广播,action广播名称 如:"com.sc.broad.actionDemo"; ext为广播附带的数据 */
// public void SendBroadCast(Context context, String action, HashMap ext)
// {
// BroadCastTool.SendBroadCast(context, action, ext);
// }
}
package com.sc.service;
import com.sc.call.CallListener;
import com.sc.call.CallProcess;
import android.widget.Toast;
/* 在AndroidManifest.xml
*
* 添加权限:
* uses-permission android:name="android.permission.READ_PHONE_STATE"
* uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"
*
* 添加
....
*/
/**
* 定义:继承BaseService,重写自定义服务逻辑serviceLogic()
*
* 1、获取服务:CallService.GetInstance()
*
* 2、启动服务:CallService.GetInstance().start(context, CallService.class);
* 3、停止服务:CallService.GetInstance().stop();
* */
public class CallService extends BaseService
{
/** 在service中待执行的逻辑(在service未停止时,会一直执行)*/
public void serviceLogic()
{
CheckListener(); // 检测电话监听状态
CallLogic(); // 执行对应电话状态逻辑
}
public static boolean isRinging = false;
public static boolean isOutCall = false;
public static boolean isOffHook = false;
public static boolean isHungUp = false;
public static String Number = "";
CallListener callListen;
// 检测并自动创建来电、去电监听
private void CheckListener()
{
if(callListen == null)
{
callListen = new CallListener(this)
{
@Override
public void Ringing(String phoneNumber)
{
isRinging = true;
Number = phoneNumber;
}
@Override
public void OutCall(String phoneNumber)
{
isOutCall = true;
Number = phoneNumber;
}
@Override
public void OffHook(String phoneNumber)
{
isOffHook = true;
Number = phoneNumber;
}
@Override
public void HungUp(String phoneNumber)
{
isHungUp = true;
Number = phoneNumber;
}
};
}
}
/** 电话状态处理逻辑 */
private void CallLogic()
{
if(isRinging)
{
isRinging = false;
CallProcess.Ringing(this, Number);
}
else if(isOffHook)
{
isOffHook = false;
CallProcess.OffHook(this, Number);
}
else if(isHungUp)
{
isHungUp = false;
CallProcess.HungUp(this, Number);
}
else if(isOutCall)
{
isOutCall = false;
CallProcess.OutCall(this, Number);
}
}
// /** 电话状态处理逻辑 */
// private void CallLogic()
// {
//
// // 执行定义在CallProcess中的逻辑
// for(CallProcess proccesser : CallProcess.ProcessList())
// {
// if(isRinging)
// {
// isRinging = false;
// proccesser.Ringing(this, Number);
// }
// else if(isOffHook)
// {
// isOffHook = false;
// proccesser.OffHook(this, Number);
// }
// else if(isHungUp)
// {
// isHungUp = false;
// proccesser.HungUp(this, Number);
// }
// else if(isOutCall)
// {
// isOutCall = false;
// proccesser.OutCall(this, Number);
// }
// }
//
// }
// public void Ringing(String phoneNumber)
// {
// // TODO 添加来电处理逻辑
// }
//
// public void OffHook(String phoneNumber)
// {
// // TODO 添加接听处理逻辑
// }
//
// public void HungUp(String phoneNumber)
// {
// // TODO 添加挂断处理逻辑
// }
//
// public void OutCall(String phoneNumber)
// {
// // TODO 添加拨出处理逻辑
// }
}
package com.sc.service;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.widget.Toast;
/* 在AndroidManifest.xml添加
....
*/
/** Service类,简化Service调用:
* 子类可继承BaseService,重写函数serviceLogic()实现自定义服务逻辑
*
* 1、获取服务单例对象 BaseService.GetInstance()
* 2、启动服务 .start(Context context, Class> service_cls)(一次启动,持续运行)
* 3、停止服务 .stop() */
public class BaseService extends Service
{
protected BaseService()
{}
@Override
public IBinder onBind(Intent intent)
{
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
if (!isrunning)
{
// if (BaseService.intent == null) BaseService.intent = intent;
// if (context == null) context = this.getBaseContext();
isrunning = true;
// Log.i(this.getClass().getSimpleName(), "onStartCommand");
// 执行服务处理逻辑
doServicesLogic(IntervalMillis);
}
return super.onStartCommand(intent, flags, startId);
}
/** service执行间隔时间(毫秒) */
public static long IntervalMillis = 2000;
Runnable runable;
/** 循环执行服务处理逻辑 */
private void doServicesLogic(final long delayMillis)
{
if(runable == null)
{
runable = new Runnable()
{
@Override
public void run()
{
if (isrunning)
{
// Toast.makeText(context, "doServicesLogic is running !", Toast.LENGTH_SHORT).show();
serviceLogic(); // 执行服务处理逻辑
doServicesLogic(delayMillis); // 处理逻辑执行完成1秒后再次执行
}
}
};
}
new Handler().postDelayed(runable, delayMillis);
}
/** 在service中待执行的逻辑(在service未停止时,会一直执行,每轮逻辑执行间隔IntervalMillis毫秒) */
public void serviceLogic()
{};
static BaseService Instance;
/** 获取当前服务的单例对象 */
public static BaseService GetInstance()
{
if (Instance == null) Instance = new BaseService();
return Instance;
}
// ------------
private static boolean isrunning = false;
// private static Intent intent;
// private static Context context;
/** 启动服务, service_cls当前服务对应的类, Millis指定服务逻辑serviceLogic()执行间隔毫秒数 */
public void start(Context context, Class> service_cls, long Millis)
{
IntervalMillis = Millis;
if (!isrunning)
{
// BaseService.context = context;
Intent intent = new Intent(context, service_cls);
context.startService(intent);
Toast.makeText(context, this.getClass().getSimpleName() + " 服务已启动 !", Toast.LENGTH_SHORT).show();
}
}
/** 启动服务, service_cls当前服务对应的类 */
public void start(Context context, Class> service_cls)
{
start(context, service_cls, 2000);
}
/** 停止服务(暂时停止服务,服务逻辑会在应用退出后自行重启,并一直运行) */
public void stop()
{
if (isrunning)
{
stopSelf();
// context.stopService(intent);
isrunning = false;
// Toast.makeText(context, this.getClass().getSimpleName() + " 服务已停止 !", Toast.LENGTH_SHORT).show();
}
}
}