拦截来电消息的方式有两种:
1、通过接收广播消息。需要Context.registerReceiver(..., TelephonyManager.ACTION_PHONE_STATE_CHANGED);
2、通过注册监听器。需要TelephonyManager.listen(PhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
下面用第一种方法,进行演示!
AndroidManifest.xml
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<receiver android:name=".MyReceiver">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE"/>
</intent-filter>
</receiver>
<pre style="font-family: 宋体; font-size: 9pt; background-color: rgb(255, 255, 255);">
注册监听器
mMyReceiver = new MyReceiver();
Log.e(TAG, "registerReceiver() mMyReceiver=" + mMyReceiver);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
intentFilter.setPriority(Integer.MAX_VALUE);
Intent intent = registerReceiver(mMyReceiver, intentFilter);
Log.e(TAG, "registerReceiver() intent=" + intent);
注销监听器
unregisterReceiver(mMyReceiver);
Log.e(TAG, "unregisterReceiver() mMyReceiver=" + mMyReceiver);
实现监听器
public class MyReceiver extends BroadcastReceiver {
public final String TAG = "MyReceiver";
private WindowManager mWinMgr;
private TextView mTxtView;
public MyReceiver() {
}
@Override
public void onReceive(Context context, Intent intent) {
Log.e(TAG, "intent.action=" + intent.getAction());
if (intent.getAction().equals(TelephonyManager.ACTION_PHONE_STATE_CHANGED)) {
String phoneNumber = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
TelephonyManager telephony = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
int state = telephony.getCallState();
Log.e(TAG, "state=" + state + ",phoneNumber=" + phoneNumber);
switch (state) {
case TelephonyManager.CALL_STATE_RINGING:
Log.e(TAG, "CALL_STATE_RINGING=" + state);
mWinMgr = (WindowManager) context.getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
WindowManager.LayoutParams params = new WindowManager.LayoutParams();
params.type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
params.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
params.width = WindowManager.LayoutParams.WRAP_CONTENT;
params.height = WindowManager.LayoutParams.WRAP_CONTENT;
params.format = PixelFormat.RGBA_8888;
mTxtView = new TextView(context);
mTxtView.setText("悬浮窗,来电号码:" + phoneNumber);
//mTxtView.setBackgroundColor(0x00000000);
mTxtView.setTextColor(0xFFFFFFFF);
mWinMgr.addView(mTxtView, params);
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
Log.e(TAG, "CALL_STATE_OFFHOOK=" + state);
if (mWinMgr != null) {
mWinMgr.removeView(mTxtView);
}
break;
case TelephonyManager.CALL_STATE_IDLE:
Log.e(TAG, "CALL_STATE_IDLE=" + state);
if (mWinMgr != null) {
mWinMgr.removeView(mTxtView);
}
break;
default:
Log.e(TAG, "default state=" + state);
if (mWinMgr != null) {
mWinMgr.removeView(mTxtView);
}
break;
}
}
}
}
效果
额外说明
将TextView替换成VideoView,便可以将文本显示替换成视频播放了。示例代码如下:
String path = Environment.getExternalStorageDirectory().getPath();
Uri uri = Uri.parse(path + File.separator + "1.mp4");
mView = new VideoView(context);
mView.setVideoURI(uri);
mView.start();
如果商用,还需要再考虑如果几点:
1、来电视频,可以从网络上获取,本次如果获取不及,应该本次取,下次用。
2、来电视频,跟原有的来电铃声有重叠,应该将原有铃声停掉。
3、来电视频的位置和大小,需要产品的角度,仔细考虑下。
参考:http://blog.csdn.net/forlong401/article/details/19126875