无法移除覆盖视图

6

更新

我已经成功解决了这个问题, 问题是对话框和相关内容可以从广播接收器中启动,但不建议这样做,因为在视图结束之前活动结束。

正在尝试实现类似FB Messenger、Truecaller等的覆盖屏幕。

public class IncomingCall extends BroadcastReceiver
{
private Context pcontext;
private static final String TAG = "CustomBroadcastReceiver";
 TelephonyManager telephony;
 CustomPhoneStateListener customPhoneListener ;
@Override
public void onReceive(Context context, Intent intent) 
{
    pcontext = context;
    Bundle extras = intent.getExtras();
    if (extras != null) {
        String state = extras.getString(TelephonyManager.EXTRA_STATE);
        Log.w("DEBUG", state);

            telephony = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
            customPhoneListener = new   CustomPhoneStateListener();
            telephony.listen(customPhoneListener,   PhoneStateListener.LISTEN_CALL_STATE);
            Bundle bundle = intent.getExtras();
            String phoneNr= bundle.getString("incoming_number");


    }


}
public class CustomPhoneStateListener extends PhoneStateListener
{
    private static final String TAG = "CustomPhoneStateListener";
    Handler handler=new Handler();
    @Override
    public void onCallStateChanged(int state, String incomingNumber) 
    {

        WindowManager wm = (WindowManager) pcontext.getSystemService(Context.WINDOW_SERVICE);

        WindowManager.LayoutParams params = new WindowManager.LayoutParams(
            LayoutParams.MATCH_PARENT,
            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 = LayoutParams.MATCH_PARENT;
        params.width = LayoutParams.MATCH_PARENT;
        params.format = PixelFormat.TRANSLUCENT;

        params.gravity = Gravity.BOTTOM;

        RelativeLayout ly;
        final LayoutInflater inflater = (LayoutInflater) pcontext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        ly = (RelativeLayout) inflater.inflate(R.layout.dialog, null);

        switch (state) 
        {
        case TelephonyManager.CALL_STATE_RINGING:
            Log.d("Call","RINGING");

            wm.addView(ly, params);
            break;

        case TelephonyManager.CALL_STATE_IDLE:

                Log.d("Call","End");
                //WindowManager wm = (WindowManager) pcontext.getSystemService(Context.WINDOW_SERVICE);

                if(ly!=null)
                {
                    wm.removeView(ly);
                    ly = null;
                }
            break;
        default:
            break;
        }
        super.onCallStateChanged(state, incomingNumber);
        telephony.listen(customPhoneListener, PhoneStateListener.LISTEN_NONE);
    }


}       
}

addView函数运行正常, 以下为日志:
"View not attached to window manager"
08-24 20:05:56.404: W/DEBUG(28001): IDLE
08-24 20:05:56.424: D/Call(28001): End
08-24 20:05:56.424: D/AndroidRuntime(28001): Shutting down VM
08-24 20:05:56.424: W/dalvikvm(28001): threadid=1: thread exiting with uncaught exception (group=0x412982a0)
08-24 20:05:56.444: E/AndroidRuntime(28001): FATAL EXCEPTION: main
08-24 20:05:56.444: E/AndroidRuntime(28001): java.lang.IllegalArgumentException: View not attached to window manager
08-24 20:05:56.444: E/AndroidRuntime(28001):    at android.view.WindowManagerImpl.findViewLocked(WindowManagerImpl.java:673)
08-24 20:05:56.444: E/AndroidRuntime(28001):    at android.view.WindowManagerImpl.removeView(WindowManagerImpl.java:369)
08-24 20:05:56.444: E/AndroidRuntime(28001):    at android.view.WindowManagerImpl$CompatModeWrapper.removeView(WindowManagerImpl.java:160)
08-24 20:05:56.444: E/AndroidRuntime(28001):    at com.androidexample.broadcastreceiver.IncomingCall$CustomPhoneStateListener.onCallStateChanged(IncomingCall.java:105)
08-24 20:05:56.444: E/AndroidRuntime(28001):    at android.telephony.PhoneStateListener$2.handleMessage(PhoneStateListener.java:393)
08-24 20:05:56.444: E/AndroidRuntime(28001):    at android.os.Handler.dispatchMessage(Handler.java:99)
08-24 20:05:56.444: E/AndroidRuntime(28001):    at android.os.Looper.loop(Looper.java:137)
08-24 20:05:56.444: E/AndroidRuntime(28001):    at android.app.ActivityThread.main(ActivityThread.java:4898)
08-24 20:05:56.444: E/AndroidRuntime(28001):    at java.lang.reflect.Method.invokeNative(Native Method)
08-24 20:05:56.444: E/AndroidRuntime(28001):    at java.lang.reflect.Method.invoke(Method.java:511)
08-24 20:05:56.444: E/AndroidRuntime(28001):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1008)
08-24 20:05:56.444: E/AndroidRuntime(28001):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:775)
08-24 20:05:56.444: E/AndroidRuntime(28001):    at dalvik.system.NativeStart.main(Native Method)
08-24 20:08:22.669: I/Process(28001): Sending signal. PID: 28001 SIG: 9

我曾经尝试过以编程方式创建布局,但没有成功。
而且我无法确定生成的布局的ID。

我从未尝试过通过BroadcastReceiver直接实现它。我总是打开一个新的Activity,在那里显示悬浮视图。请尝试一下。这是我最近编写的如何显示顶部视图的片段:https://dev59.com/8nbZa4cB1Zd3GeqPBhJE#18433366 - android developer
但是它能够从广播接收器的另一个状态完成活动吗? - Ajmal M Sali
我知道在活动销毁时可以移除视图。 - Ajmal M Sali
我不明白。如果你想立即删除视图,为什么要在其上显示视图?如果你希望允许其周围的事物可点击,那就是你需要做的(并且你可以完成活动,它仍然会显示在顶部)。在任何其他情况下,你可以在活动中显示对话框,并在其关闭时结束活动。或者,你可以使活动看起来像一个对话框。 - android developer
在响铃状态下添加叠加层,在空闲状态下移除它。 - Ajmal M Sali
显示剩余2条评论
2个回答

3

问题在于,我们不能在广播接收器中使用对话框,而必须在另一个可以通过意图启动的活动中使用。


1
这个方法在 BroadcastReceiver 接收到 Intent 广播时被调用。在此期间,您可以使用 BroadcastReceiver 上的其他方法来查看/修改当前结果值。除非您使用 registerReceiver(BroadcastReceiver, IntentFilter, String, android.os.Handler) 显式要求将其安排在不同的线程上,否则此方法始终在其进程的主线程中调用。当它在主线程上运行时,您不应该在其中执行长时间运行的操作(系统允许 10 秒的超时时间,然后将考虑接收器被阻塞并成为被杀死的候选对象)。您不能在 onReceive() 实现中启动弹出对话框。
Android 文档清楚地说明了这一点。
Android Documentation on BroadcastReceiver: Android BroadcastReceiver 文档

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接