来电界面弹出窗口,类似于Truecaller

4

我试图在来电屏幕上添加弹出窗口,就像真实的通话者一样,但是未能实现。请告诉我背后的逻辑以及如何实现它。

  public void onReceive(Context context, Intent intent) {

    try {
        // TELEPHONY MANAGER class object to register one listner
        TelephonyManager tmgr = (TelephonyManager) context
                .getSystemService(Context.TELEPHONY_SERVICE);


            }
    } catch (Exception e) {
        Log.e("Phone Receive Error", " " + e);
    }

}

一个重复的 https://dev59.com/2GUo5IYBdhLWcg3w5Syl?rq=1 - Fareya
谢谢您的建议,但是没有起作用。请给我另一个解决方案。 - Nirmal singh
@user3098271:请看下面我的回答。 - Basher51
2个回答

13

我已经为我的应用程序使用了以下方法,在其中我想要在拨号器应用程序启动时显示一个视图(类似于Truecaller中的那样)。为此,请创建一个广播接收器,它可以接受如下所述的各种设备事件。

广播接收器

        private WindowManager wm;
        private static LinearLayout ly1;
        private WindowManager.LayoutParams params1;

        // onReceive function of the Broadcast Receiver
        public void onReceive(Context arg0, Intent arg1) {
                String state = arg1.getStringExtra(TelephonyManager.EXTRA_STATE);

                // Adds a view on top of the dialer app when it launches.
                if(state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)){
                    wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
                    params1 = 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);

                    params1.height = 75;
                    params1.width = 512;
                    params1.x = 265; 
                    params1.y = 400;
                    params1.format = PixelFormat.TRANSLUCENT;

                    ly1 = new LinearLayout(context);
                    ly1.setBackgroundColor(Color.BLACK);
                    ly1.setOrientation(LinearLayout.VERTICAL);

                    wm.addView(ly1, params1);
                }

                // To remove the view once the dialer app is closed.
                if(arg1.getAction().equals("android.intent.action.PHONE_STATE")){
                    String state = arg1.getStringExtra(TelephonyManager.EXTRA_STATE);
                    if(state.equals(TelephonyManager.EXTRA_STATE_IDLE)){
                        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
                        if(ly1!=null)
                        {
                            wm.removeView(ly1);
                            ly1 = null;
                        }
                    }
                }
            }

注意: 上述示例生成了一个具有黑色背景和上文所示尺寸的布局视图。您可以在此视图中添加任何布局,例如:要在视图中包含布局,您可以修改上面的代码以包含以下内容:

        ly1 = new LinearLayout(getApplicationContext());
        ly1.setOrientation(LinearLayout.HORIZONTAL);


        View hiddenInfo = getLayoutInflater().inflate(R.layout.layout1, ly1, false);
        ly1.addView(hiddenInfo);

        wm.addView(ly1, params1);

PS : Layout1是一种布局,您需要在布局文件夹中创建它并在此处引用它。

此外 ,您需要在清单中包括以下权限。

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"></uses-permission>
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
<action android:name="android.intent.action.PHONE_STATE" /> (within intent filter of Broadcast Receiver)

1
这是针对此情况的最佳答案。谢谢。 - uniruddh
@I-droid:很高兴我的回答能够帮到你 :) - Basher51
@Basher51,我该如何将它放在屏幕顶部而不是底部?我尝试更改params.x和params.y变量,但没有结果。顺便说一句,这真是个好的解决方案。 - Slay
1
非常感谢你的创意。一旦我添加了一个挂断按钮,它为极简主义动作拨号器提供了完美的视图! - chksr
1
在 API < 24 上一切都运行良好。但是在 Android 7.0(API 24)上,弹出窗口不会出现。您知道如何解决吗? - aleksandrbel
显示剩余2条评论

2

试试这个

AlertDialog.Builder builder = new AlertDialog.Builder(context.getApplicationContext());
            LayoutInflater inflater = LayoutInflater.from(context);
            View dialogView = inflater.inflate(R.layout.caller_dialog, null);

            ImageView button = dialogView.findViewById(R.id.close_btn);

            builder.setView(dialogView);
            final AlertDialog alert = builder.create();
            alert.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
            alert.getWindow().setType(WindowManager.LayoutParams.TYPE_PHONE);
            alert.setCanceledOnTouchOutside(true);
            alert.show();
            WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
            Window window = alert.getWindow();
            window.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
            window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
            window.setGravity(Gravity.TOP);
            lp.copyFrom(window.getAttributes());
            //This makes the dialog take up the full width
            lp.width = WindowManager.LayoutParams.MATCH_PARENT;
            lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
            window.setAttributes(lp);
            button.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    //close the service and remove the from from the window
                    alert.dismiss();
                }
            });

在您的onCreate()中添加权限检查。

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.canDrawOverlays(getActivity())) {
        //If the draw over permission is not available open the settings screen
        //to grant the permission.
        Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                Uri.parse("package:" + getActivity().getPackageName()));
        startActivityForResult(intent, CODE_DRAW_OVER_OTHER_APP_PERMISSION);
    }

并且是在onActivityResult()中

private static final int CODE_DRAW_OVER_OTHER_APP_PERMISSION = 2084; 
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == CODE_DRAW_OVER_OTHER_APP_PERMISSION) {

        //Check if the permission is granted or not.
        if (resultCode == RESULT_OK) {

        }
        else
            {
                // Permission is not available
            }

    } else {
        super.onActivityResult(requestCode, resultCode, data);
    }
}

不要忘记在清单文件中添加权限。
<uses-permission android:name="android.permission.ACTION_MANAGE_OVERLAY_PERMISSION" />

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