如何?android中監聽來電並產生懸浮表單提示

來源:互聯網
上載者:User

 

最近因為項目的原因需要實現一個來電監聽,且產生一個懸浮視窗提示相關資訊(具體什麼資訊不方便透露哈)。

現把我的思路及實現方法大致說下哈。

 

想要監聽來電首先需要要manifest中申明"android.permission.READ_PHONE_STATE"許可權

 

Xml代碼  
  1. <uses-permission android:name="android.permission.READ_PHONE_STATE"/>  
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>

 

還需要註冊來電監聽,目前我的處理方式是接收開機廣播,然後在接收到廣播後註冊來電監聽。接收開機廣播需要有“android.permission.RECEIVE_BOOT_COMPLETED”許可權,manifest中申明如下

 

Java代碼  
  1. <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>  
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

 

 然後註冊廣播接收類

 

Xml代碼  
  1. <receiver android:name=".PhoneBootReceiver">  
  2.     <intent-filter>  
  3.         <action android:name="android.intent.action.BOOT_COMPLETED" />  
  4.     </intent-filter>  
  5. </receiver>  
<receiver android:name=".PhoneBootReceiver"><intent-filter><action android:name="android.intent.action.BOOT_COMPLETED" /></intent-filter></receiver>

 

 PhoneBootReceiver中註冊監聽來電,首先得擷取系統服務“TELEPHONY_SERVICE”

 

Java代碼  
  1. TelephonyManager telM = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);  
TelephonyManager telM = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);

 

 然後添加監聽

 

Java代碼  
  1. telM.listen(new TelListener(context), PhoneStateListener.LISTEN_CALL_STATE);  
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代碼  
  1. <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>  
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

 

WindowManager需要通過context.getApplicationContext().getSystemService(Context.WINDOW_SERVICE);

來擷取。

 

 先把TelListener源碼放出來,再詳解

 

Xml代碼  
  1. public class TelListener extends PhoneStateListener {   
  2.        
  3.        
  4.     private Context context;   
  5.     private WindowManager wm;   
  6.     private TextView tv;   
  7.     public TelListener(Context context){   
  8.         this.context = context;   
  9.     }   
  10.   
  11.     @Override   
  12.     public void onCallStateChanged(int state, String incomingNumber) {   
  13.         // TODO Auto-generated method stub   
  14.         super.onCallStateChanged(state, incomingNumber);   
  15.         if(state == TelephonyManager.CALL_STATE_RINGING){   
  16.                
  17.             wm = (WindowManager)context.getApplicationContext().getSystemService(Context.WINDOW_SERVICE);     
  18.             WindowManager.LayoutParams params = new WindowManager.LayoutParams();     
  19.             params.type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;     
  20.             params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;    
  21.                  
  22.             params.width = WindowManager.LayoutParams.WRAP_CONTENT;     
  23.             params.height = WindowManager.LayoutParams.WRAP_CONTENT;     
  24. <SPAN style="WHITE-SPACE: pre">         </SPAN>params.format = PixelFormat.RGBA_8888;
      
  25.             tv = new TextView(context);    
  26.             tv.setText("這是懸浮視窗,來電號碼:" + incomingNumber);   
  27.             wm.addView(tv, params);   
  28.                        
  29.         }else if(state == TelephonyManager.CALL_STATE_IDLE){   
  30.             if(wm != null){   
  31.                 wm.removeView(tv);   
  32.             }   
  33.         }   
  34.     }   
  35. }  
public class TelListener extends PhoneStateListener {private Context context;private WindowManager wm;private TextView tv;public TelListener(Context context){this.context = context;}@Overridepublic void onCallStateChanged(int state, String incomingNumber) {// TODO Auto-generated method stubsuper.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;  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代碼  
  1. WindowManager.LayoutParams params = new WindowManager.LayoutParams();   
WindowManager.LayoutParams params = new WindowManager.LayoutParams(); 

 

設定視窗類別型在所有視窗之上

 

Java代碼  
  1. params.type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;   
params.type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY; 

 

別忘了

 

Java代碼  
  1. params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;  
params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;

 如果沒有這句話的話,在產生懸浮視窗後,懸浮視窗後的介面上東西都不能點。這句話的目的是讓懸浮視窗失去焦點。

 

背景透明

Java代碼  
  1. params.format = PixelFormat.RGBA_8888;  
params.format = PixelFormat.RGBA_8888;

 

 

本例中懸浮視窗只是顯示一個TextView其內容為“這是懸浮視窗,來電號碼:xxxxxx”,最後將TextView添加到表單中

 

Java代碼  
  1. wm.addView(tv, params);  
wm.addView(tv, params);

 

在電話中斷後將TextView移除,否則會一直顯示的...

 

Java代碼  
  1. wm.removeView(tv);  
wm.removeView(tv);

 

啦..本文就到這兒了... 

“啥?要可移動的?”

要想可以拖動的話,那給TextView添加setOnTouchListener,實現OnTouchListener的onTouchListener方法。

對了,別忘了將

Java代碼  
  1. params.type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;   
params.type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY; 

修改為

Java代碼  
  1. params.type = WindowManager.LayoutParams.TYPE_PHONE;   
params.type = WindowManager.LayoutParams.TYPE_PHONE; 

因為TYPE_SYSTEM_OVERLAY的話是TextView擷取不到輸入焦點,也就沒法拖動了哈。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.