驳回Android上的自定义来电屏幕时,电话被接听或电话停止振铃 [英] Dismissing a custom incoming call screen on Android when the call is answered or the phone stops ringing
问题描述
我想有一个自定义来电屏幕,显示了当有来电时,如果呼叫被应答或得到驳回了电话停止振铃。
我搜索#2几个职位给我看我如何可以实现,到目前为止,我几乎没有和屏幕被如何快速显示方面检查每一种方法的利弊后,我已经谈妥在窗口管理器的方法。
每当我称之为 wm.removeView(LY)
我得到以下
20 07-08:36:41.002 27547-27547 / com.testtelephoney.customincomingcall E / AndroidRuntime:致命异常:主要
工艺:com.testtelephoney.customincomingcall,PID:27547
java.lang.IllegalArgumentException异常:查看= {android.widget.LinearLayout 7e63aae V.E ..... ......我。 0,0-0,0}不附着于窗口管理
在android.view.WindowManagerGlobal.findViewLocked(WindowManagerGlobal.java:402)
在android.view.WindowManagerGlobal.removeView(WindowManagerGlobal.java:328)
在android.view.WindowManagerImpl.removeViewImmediate(WindowManagerImpl.java:84)
在com.testtelephoney.customincomingcall.MyPhoneStateListener.onCallStateChanged(MyPhoneStateListener.java:43)
在android.telephony.PhoneStateListener $ 2.handleMessage(PhoneStateListener.java:392)
在android.os.Handler.dispatchMessage(Handler.java:102)
在android.os.Looper.loop(Looper.java:145)
在android.app.ActivityThread.main(ActivityThread.java:5832)
在java.lang.reflect.Method.invoke(本机方法)
在java.lang.reflect.Method.invoke(Method.java:372)
在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:1399)
下面是我的code:
MyPhoneStateListener.java
进口android.content.Context;
进口android.graphics.PixelFormat;
进口android.telephony.PhoneStateListener;
进口android.telephony.TelephonyManager;
进口android.util.Log;
进口android.view.Gravity;
进口android.view.LayoutInflater;
进口android.view.View;
进口android.view.WindowManager;
进口android.widget.LinearLayout;
进口android.widget.RelativeLayout;
公共类MyPhoneStateListener扩展PhoneStateListener {
上下文mContext;
公共MyPhoneStateListener(上下文CT){
mContext =克拉;
}
公共无效onCallStateChanged(INT状态,弦乐incomingNumber){ 窗口管理WM =(窗口管理器)mContext.getSystemService(Context.WINDOW_SERVICE);
WindowManager.LayoutParams PARAMS =新WindowManager.LayoutParams(WindowManager.LayoutParams.MATCH_PARENT,WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.TYPE_SYSTEM_ALERT|WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL|WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSPARENT); params.height = WindowManager.LayoutParams.MATCH_PARENT;
params.width = WindowManager.LayoutParams.MATCH_PARENT;
params.format = PixelFormat.TRANSPARENT;
params.gravity = Gravity.TOP; LY的LinearLayout; 最后LayoutInflater吹气=(LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
LY =(的LinearLayout)inflater.inflate(R.layout.activity_ic,NULL);
开关(州){
案例TelephonyManager.CALL_STATE_IDLE:
Log.d(调试,空闲);
如果(ly.getVisibility()== View.VISIBLE){
wm.removeView(LY);
}
打破;
案例TelephonyManager.CALL_STATE_OFFHOOK:
Log.d(调试,摘机);
打破;
案例TelephonyManager.CALL_STATE_RINGING:
Log.d(调试,振铃);
wm.addView(LY,则params);
打破;
}
}
}
ServiceReceiver
进口android.content.BroadcastReceiver;
进口android.content.Context;
进口android.content.Intent;
进口android.telephony.PhoneStateListener;
进口android.telephony.TelephonyManager;公共类ServiceReceiver扩展广播接收器{
公共ServiceReceiver(){
} @覆盖
公共无效的onReceive(上下文的背景下,意图意图){
// TODO:当广播接收器接收这种方法被称为
//一个Intent广播。
MyPhoneStateListener phoneListener =新MyPhoneStateListener(背景);
TelephonyManager电话=(TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
telephony.listen(phoneListener,PhoneStateListener.LISTEN_CALL_STATE);
}
}
AndroidManifest
<使用许可权的android:NAME =android.permission.GET_ACCOUNTS/>
<使用许可权的android:NAME =android.permission.READ_PROFILE/>
<使用许可权的android:NAME =android.permission.READ_CONTACTS/>
<使用许可权的android:NAME =android.permission.SYSTEM_ALERT_WINDOW/>
<接收机器人:名字=。ServiceReceiver>
&所述;意图滤光器>
<作用机器人:名字=android.intent.action.PHONE_STATE/>
&所述; /意图滤光器>
< /接收器>
我添加了一个标志,以纪念该视图已被添加。它确实需要关闭过程改进。
开关(州){
案例TelephonyManager.CALL_STATE_IDLE:
Log.d(调试,空闲);
如果(viewCreated){
wm.removeView(LY);
viewCreated = FALSE;
}
打破;
案例TelephonyManager.CALL_STATE_OFFHOOK:
Log.d(调试,摘机);
打破;
案例TelephonyManager.CALL_STATE_RINGING:
Log.d(调试,振铃);
如果(!viewCreated){
WindowManager.LayoutParams PARAMS =新WindowManager.LayoutParams(WindowManager.LayoutParams.MATCH_PARENT,WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.TYPE_SYSTEM_ALERT|WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL|WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSPARENT);
params.height = WindowManager.LayoutParams.MATCH_PARENT;
params.width = WindowManager.LayoutParams.MATCH_PARENT;
params.format = PixelFormat.TRANSPARENT;
params.gravity = Gravity.TOP; LY =(的LinearLayout)inflater.inflate(R.layout.activity_login,NULL);
wm.addView(LY,则params);
viewCreated = TRUE;
}
打破;
}
I want to have a custom incoming call screen that shows up when there is an incoming call, and get dismissed if the call is answered or the phone stops ringing.
I've searched several posts on Stackoverflow to show me how can I implement that, and so far I am nearly there and after checking pros and cons of each approach in terms of how fast the screen gets shown, I've settled on the WindowManager approach.
Whenever I call wm.removeView(ly)
I get the stack below
07-08 20:36:41.002 27547-27547/com.testtelephoney.customincomingcall E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.testtelephoney.customincomingcall, PID: 27547
java.lang.IllegalArgumentException: View=android.widget.LinearLayout{7e63aae V.E..... ......I. 0,0-0,0} not attached to window manager
at android.view.WindowManagerGlobal.findViewLocked(WindowManagerGlobal.java:402)
at android.view.WindowManagerGlobal.removeView(WindowManagerGlobal.java:328)
at android.view.WindowManagerImpl.removeViewImmediate(WindowManagerImpl.java:84)
at com.testtelephoney.customincomingcall.MyPhoneStateListener.onCallStateChanged(MyPhoneStateListener.java:43)
at android.telephony.PhoneStateListener$2.handleMessage(PhoneStateListener.java:392)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:5832)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
Here is my code:
MyPhoneStateListener.java
import android.content.Context;
import android.graphics.PixelFormat;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
public class MyPhoneStateListener extends PhoneStateListener{
Context mContext;
public MyPhoneStateListener(Context ct) {
mContext = ct;
}
public void onCallStateChanged(int state,String incomingNumber){
WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.TYPE_SYSTEM_ALERT|WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL|WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSPARENT);
params.height= WindowManager.LayoutParams.MATCH_PARENT;
params.width= WindowManager.LayoutParams.MATCH_PARENT;
params.format=PixelFormat.TRANSPARENT;
params.gravity= Gravity.TOP;
LinearLayout ly;
final LayoutInflater inflater = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ly=(LinearLayout)inflater.inflate(R.layout.activity_ic,null);
switch (state){
case TelephonyManager.CALL_STATE_IDLE:
Log.d("DEBUG","IDLE");
if(ly.getVisibility()== View.VISIBLE){
wm.removeView(ly);
}
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
Log.d("DEBUG","OFFHOOK");
break;
case TelephonyManager.CALL_STATE_RINGING:
Log.d("DEBUG","RINGING");
wm.addView(ly,params);
break;
}
}
}
ServiceReceiver
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
public class ServiceReceiver extends BroadcastReceiver {
public ServiceReceiver() {
}
@Override
public void onReceive(Context context, Intent intent) {
// TODO: This method is called when the BroadcastReceiver is receiving
// an Intent broadcast.
MyPhoneStateListener phoneListener = new MyPhoneStateListener(context);
TelephonyManager telephony = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
telephony.listen(phoneListener, PhoneStateListener.LISTEN_CALL_STATE);
}
}
AndroidManifest
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_PROFILE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<receiver android:name=".ServiceReceiver" >
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
I've added a flag to mark that the view has been added. It does need to be improved off course.
switch (state){
case TelephonyManager.CALL_STATE_IDLE:
Log.d("DEBUG","IDLE");
if (viewCreated) {
wm.removeView(ly);
viewCreated = false;
}
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
Log.d("DEBUG","OFFHOOK");
break;
case TelephonyManager.CALL_STATE_RINGING:
Log.d("DEBUG","RINGING");
if (!viewCreated){
WindowManager.LayoutParams params = new WindowManager.LayoutParams(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.TYPE_SYSTEM_ALERT|WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL|WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSPARENT);
params.height= WindowManager.LayoutParams.MATCH_PARENT;
params.width= WindowManager.LayoutParams.MATCH_PARENT;
params.format=PixelFormat.TRANSPARENT;
params.gravity= Gravity.TOP;
ly=(LinearLayout)inflater.inflate(R.layout.activity_login,null);
wm.addView(ly, params);
viewCreated=true;
}
break;
}
这篇关于驳回Android上的自定义来电屏幕时,电话被接听或电话停止振铃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!