Recently, for project reasons, we need to implement an incoming call listener and generate a floating window to prompt relevant information (which is inconvenient to disclose ).
Now let me give a rough picture of my ideas and implementation methods.
To listen for incoming calls, you must first declare "android. Permission. read_phone_state" permission in manifest.
XML Code
- <Uses-Permission Android: Name = "android. Permission. read_phone_state"/>
<Uses-Permission Android: Name = "android. Permission. read_phone_state"/>
You also need to register an incoming call listener. Currently, my solution is to receive the incoming call broadcast and register the incoming call listener after receiving the broadcast. "Android. Permission. receive_boot_completed" permission is required to receive the boot broadcast. The manifest statement is as follows:
Java code
- <Uses-Permission Android: Name = "android. Permission. receive_boot_completed"/>
<Uses-Permission Android: Name = "android. Permission. receive_boot_completed"/>
Then register the broadcast receiving Class
XML Code
- <Cycler Android: Name = ". phonebootreceiver">
- <Intent-filter>
- <Action Android: Name = "android. Intent. Action. boot_completed"/>
- </Intent-filter>
- </Cycler>
<Cycler Android: Name = ". phonebootreceiver "> <intent-filter> <action Android: Name =" android. intent. action. boot_completed "/> </intent-filter> </Cycler>
Register a listener in phonebootreceiver. First, you must obtain the System Service "telephony_service"
Java code
- Telephonymanager telm = (telephonymanager) getsystemservice (context. telephony_service );
Telephonymanager telm = (telephonymanager) getsystemservice (context. telephony_service );
Then add a listener
Java code
- Telm. Listen (New tellistener (context), phonestatelistener. listen_call_state );
Telm. Listen (New tellistener (context), phonestatelistener. listen_call_state );
Tellistener is a custom phone status listener class inherited from phonestatelistener. To listen to incoming calls, you only need to implement the oncallstatechanged (INT state, string incomingnumber) method.
In the title, the floating window is displayed. In fact, the floating window is added to the windowmanager. This function is also implemented in tellistener. To implement a floating window, you must first have the "android. Permission. system_alert_window" permission and declare it in manifest as follows:
XML Code
- <Uses-Permission Android: Name = "android. Permission. system_alert_window"/>
<Uses-Permission Android: Name = "android. Permission. system_alert_window"/>
Windowmanager needs to use context. getapplicationcontext (). getsystemservice (context. window_service );
.
First, release the tellistener source code, and then explain it in detail.
XML Code
- Public class tellistener extends phonestatelistener {
- Private context;
- Private windowmanager WM;
- Private textview TV;
- Public tellistener (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 ("this is a floating window, call number:" + incomingnumber );
- WM. addview (TV, Params );
- } Else if (State = telephonymanager. call_state_idle ){
- If (WM! = NULL ){
- WM. removeview (TV );
- }
- }
- }
- }
Public class tellistener extends phonestatelistener {private context; private windowmanager WM; private textview TV; Public tellistener (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 = (invalid Wm Anager) 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 = Win Dowmanager. layoutparams. wrap_content; Params. format = pixelformat. rgba_8888; TV = new textview (context); TV. settext ("this is a floating window, call number:" + incomingnumber); WM. addview (TV, Params);} else if (State = telephonymanager. call_state_idle) {If (WM! = NULL) {WM. removeview (TV );}}}}
State = telephonymanager. call_state_ringing indicates a new call, and state = telephonymanager. call_state_idle indicates that the call is interrupted (the call may not be accurate. The state will be equal to telephonymanager. call_state_idle)
Define window layout
Java code
- Windowmanager. layoutparams Params = new windowmanager. layoutparams ();
Windowmanager. layoutparams Params = new windowmanager. layoutparams ();
Set the Window Type above all windows
Java code
- Params. type = windowmanager. layoutparams. type_system_overlay;
Params. type = windowmanager. layoutparams. type_system_overlay;
Don't forget
Java code
- 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;
If there is no such sentence, after the floating window is generated, the interface after the floating window cannot be clicked in the east or west. The purpose of this sentence is to make the floating window lose focus.
Transparent background
Java code
- Params. format = pixelformat. rgba_8888;
Params. format = pixelformat. rgba_8888;
In this example, the floating window only displays a textview whose content is "this is a floating window, call number: xxxxxx", and finally adds textview to the form.
Java code
- WM. addview (TV, Params );
WM. addview (TV, Params );
Remove textview after the phone is disconnected, otherwise it will be displayed all the time...
Java code
- WM. removeview (TV );
WM. removeview (TV );
This article is here...
"What? To be movable ?"
If you want to drag it, add setontouchlistener to textview to implement the ontouchlistener method of ontouchlistener.
By the way, do not forget
Java code
- Params. type = windowmanager. layoutparams. type_system_overlay;
Params. type = windowmanager. layoutparams. type_system_overlay;
Change
Java code
- Params. type = windowmanager. layoutparams. type_phone;
Params. type = windowmanager. layoutparams. type_phone;
Because type_system_overlay cannot obtain the input focus of textview, it cannot be dragged.