如何實現android中監聽來電並生成懸浮窗體提示
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow
也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!
http://www.iteye.com/topic/1118711
最近因為專案的原因需要實現一個來電監聽,且生成一個懸浮視窗提示相關資訊(具體什麼資訊不方便透露哈)。
現把我的思路及實現方法大致說下哈。
想要監聽來電首先需要要manifest中申明"android.permission.READ_PHONE_STATE"許可權
Xml程式碼
- <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
還需要註冊來電監聽,目前我的處理方式是接收開機廣播,然後在接收到廣播後註冊來電監聽。接收開機廣播需要有“android.permission.RECEIVE_BOOT_COMPLETED”許可權,manifest中申明如下
Java程式碼
- <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
然後註冊廣播接收類
Xml程式碼
- <receiver android:name
- <intent-filter>
- <action android:name="android.intent.action.BOOT_COMPLETED" />
- </intent-filter>
- </receiver>
PhoneBootReceiver中註冊監聽來電,首先得獲取系統服務“TELEPHONY_SERVICE”
Java程式碼
- TelephonyManager telM = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
然後新增監聽
Java程式碼
- telM.listen(new TelListener(context), PhoneStateListener.LISTEN_CALL_STATE);
TelListener是自己定義的電話狀態監聽類,繼承自PhoneStateListener,監聽來電只需要實現onCallStateChanged(int state, String incomingNumber)方法。
咳咳...標題上說了彈出懸浮視窗,其實懸浮視窗就是在WindowManager中新增一個View,這個功能我也是在TelListener實現的。要想實現懸浮視窗,首先得有“android.permission.SYSTEM_ALERT_WINDOW”的許可權,在manifest中申明如下:
Xml程式碼
- <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
WindowManager需要通過context.getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
來獲取。
先把TelListener原始碼放出來,再詳解
Xml程式碼
- public class TelListener extends PhoneStateListener {
- private Context context;
- private WindowManager wm;
- private TextView tv;
- public TelListener(Context context){
- this.context = context;
- }
- @Override
- public void onCallStateChanged(int state, String incomingNumber) {
- // TODO Auto-generated method stub
- super.onCallStateChanged(state, incomingNumber);
- if(state == TelephonyManager.CALL_STATE_RINGING){
- wm = (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 | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
- params.width = WindowManager.LayoutParams.WRAP_CONTENT;
- params.height = WindowManager.LayoutParams.WRAP_CONTENT;
- <span style="white-space: pre;"> </span>params.format = PixelFormat.RGBA_8888;
- tv = new TextView(context);
- tv.setText("這是懸浮視窗,來電號碼:" + incomingNumber);
- wm.addView(tv, params);
- }else if(state == TelephonyManager.CALL_STATE_IDLE){
- if(wm != null){
- wm.removeView(tv);
- }
- }
- }
- }
state = TelephonyManager.CALL_STATE_RINGING表示有新的來電,state = TelephonyManager.CALL_STATE_IDLE表示電話中斷(可能理解不是很準確,電話結束通話的時候state會和TelephonyManager.CALL_STATE_IDLE相等)
定義窗口布局
Java程式碼
- WindowManager.LayoutParams params = new WindowManager.LayoutParams();
設定視窗型別在所有視窗之上
Java程式碼
- params.type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
別忘了
Java程式碼
- params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
如果沒有這句話的話,在生成懸浮視窗後,懸浮視窗後的介面上東西都不能點。這句話的目的是讓懸浮視窗失去焦點。
背景透明
Java程式碼- params.format = PixelFormat.RGBA_8888;
本例中懸浮視窗只是顯示一個TextView其內容為“這是懸浮視窗,來電號碼:xxxxxx”,最後將TextView新增到窗體中
Java程式碼
- wm.addView(tv, params);
在電話中斷後將TextView移除,否則會一直顯示的...
Java程式碼
- wm.removeView(tv);
啦..本文就到這兒了...
“啥?要可移動的?”
要想可以拖動的話,那給TextView新增setOnTouchListener,實現OnTouchListener的onTouchListener方法。
對了,別忘了將
Java程式碼- params.type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
修改為
Java程式碼- params.type = WindowManager.LayoutParams.TYPE_PHONE;
因為TYPE_SYSTEM_OVERLAY的話是TextView獲取不到輸入焦點,也就沒法拖動了哈。
http://blog.csdn.net/l_serein/article/details/7475678
參考:
android 呼入電話的監聽(來電監聽)
http://stephen830.iteye.com/blog/1181010
android 撥出電話的監聽(去電監聽)
http://stephen830.iteye.com/blog/1181452
android-輕鬆監聽來電和去電
http://www.eoeandroid.com/thread-8994-1-1.html
android 呼入電話的監聽(來電監聽)
需要許可權:
Xml程式碼- <uses-permission android:name="android.permission.READ_PHONE_STATE" />
方式一:通過廣播接收來電
定義來電廣播接收類
Java程式碼- package com.zhouzijing.android.demo;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- import android.telephony.TelephonyManager;
- import android.util.Log;
- public class BroadcastReceiverMgr extends BroadcastReceiver {
- private final String TAG = MyBroadcastReceiver.TAG;
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- Log.i(TAG, "[Broadcast]"+action);
- //呼入電話
- if(action.equals(MyBroadcastReceiver.B_PHONE_STATE)){
- Log.i(TAG, "[Broadcast]PHONE_STATE");
- doReceivePhone(context,intent);
- }
- }
- /**
- * 處理電話廣播.
- * @param context
- * @param intent
- */
- public void doReceivePhone(Context context, Intent intent) {
- String phoneNumber = intent.getStringExtra(
- TelephonyManager.EXTRA_INCOMING_NUMBER);
- TelephonyManager telephony =
- (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
- int state = telephony.getCallState();
- switch(state){
- case TelephonyManager.CALL_STATE_RINGING:
- Log.i(TAG, "[Broadcast]等待接電話="+phoneNumber);
- break;
- case TelephonyManager.CALL_STATE_IDLE:
- Log.i(TAG, "[Broadcast]電話結束通話="+phoneNumber);
- break;
- case TelephonyManager.CALL_STATE_OFFHOOK:
- Log.i(TAG, "[Broadcast]通話中="+phoneNumber);
- break;
- }
- }
- }
定義Actitvity類
Java程式碼- package com.zhouzijing.android.demo;
- import android.app.Activity;
- import android.content.Context;
- import android.content.Intent;
- import android.content.IntentFilter;
- import android.os.Bundle;
- import android.telephony.PhoneStateListener;
- import android.telephony.TelephonyManager;
- import android.util.Log;
- import android.view.View;
- public class MyBroadcastReceiver extends Activity {