Android 系统拨号界面实现自定义悬浮布局

首先看一下效果图:
1.首先提示是否需要开始个性化拨号界面

2.如果需要,跳转进入设置界面:

这里写图片描述

3.进入拨打电话界面:

这里写图片描述

中间的就是自定义显示出来的界面

实现过程:
1.布局:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="340dp"
    android:layout_height="184dp"
    android:background="@color/colorWhite">

    <RelativeLayout
        android:id="@+id/rl_phone_head"
        android:layout_width="match_parent"
        android:layout_height="92dp">
        <ImageView
            android:id="@+id/iv_close"
            android:layout_width="20dp"
            android:layout_height="20dp"
            android:layout_alignParentEnd="true"
            android:layout_marginEnd="12dp"
            android:layout_marginTop="12dp"
            android:src="@mipmap/close"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <ImageView
            android:id="@+id/iv_user"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:layout_alignParentStart="true"
            android:layout_marginStart="16dp"
            android:layout_marginTop="16dp"
            android:background="@drawable/phone_user_bg"
            android:src="@mipmap/xxx1"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@+id/tv_username"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_toEndOf="@+id/iv_user"
            android:layout_marginStart="16dp"
            android:layout_marginTop="36dp"
            android:text="用户名"
            android:textSize="16sp"
            android:textColor="@color/colorText"
            android:textStyle="bold"
            />
    </RelativeLayout>



    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="92dp"
        android:background="@color/colorOrangeRed"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/rl_phone_head"
       >

        <TextView
            android:id="@+id/tv_department"
            android:text="所属部门"
            android:textSize="16sp"
            android:textColor="@color/colorWhite"
            android:layout_margin="16dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

        <TextView
            android:id="@+id/tv_school"
            android:text="学校"
            android:textSize="16sp"
            android:textColor="@color/colorWhite"
            android:layout_alignParentBottom="true"
            android:layout_marginBottom="16dp"
            android:layout_marginStart="16dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

    </RelativeLayout>


</android.support.constraint.ConstraintLayout>

布局可以由自己的需求实现,怎么写都可以

2.使用WindowManager控制布局:

public void showFloatView() {
        final WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);

        final View inflate = LayoutInflater.from(getApplicationContext()).inflate(R.layout.window_over_flow, null);
        final ImageView close = (ImageView) inflate.findViewById(R.id.iv_close);

        final WindowManager.LayoutParams params = new WindowManager.LayoutParams();
        params.type = WindowManager.LayoutParams.TYPE_PHONE;
        params.format = PixelFormat.RGBA_8888;
        params.gravity = Gravity.CENTER;
        params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
        //这边控制悬浮框的大小
        params.height = SizeUtils.dp2px(184);
        params.width = SizeUtils.dp2px(340);

        params.x = 0;
        params.y = 0;
        close.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                windowManager.removeViewImmediate(inflate);
            }
        });
        windowManager.addView(inflate, params);
    }

showFloatView方法用于显示该布局,close按钮用于布局的消失

3.权限申请:
这里有两个地方要用到申请权限。
第一个地方是打开系统界面设置可以在其他应用上显示,第二个地方是拨打电话需要申请权限。

首先需要在清单文件中声明一下:

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="android.permission.CALL_PHONE"/>

在代码中:
当需要拨打电话时:对相应按钮的点击事件设置监听:

if (Build.VERSION.SDK_INT >= 23) {
    if (ActivityCompat.shouldShowRequestPermissionRationale(CallPhoneActivity.this,
                            Manifest.permission.CALL_PHONE)) {
//  如果app之前请求过该权限,被用户拒绝, 这个方法就会返回true.
//  如果用户之前拒绝权限的时候勾选了对话框中”Don’t ask again”的选项,那么这个方法会返回false.
//   如果设备策略禁止应用拥有这条权限, 这个方法也返回false.
// 弹窗需要解释为何需要该权限,再次请求授权
        Toast.makeText(CallPhoneActivity.this, "请授权!", Toast.LENGTH_LONG).show();
// 帮跳转到该应用的设置界面,让用户手动授权
        Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                        Uri uri = Uri.fromParts("package",getPackageName(), null);
                        intent.setData(uri);
                        startActivity(intent);
                    }
    else {
         // 不需要解释为何需要该权限,直接请求授权
         EasyPermissions.requestPermissions(CallPhoneActivity.this,
                                "需要拨打电话权限",
                                1,
                                Manifest.permission.CALL_PHONE);
           }

} else {
     showFloatView();
     CallPhone();
}

在图二中弹出dialog,点击需要的时候:

if (Build.VERSION.SDK_INT >= 23) {
    if (Settings.canDrawOverlays(getApplicationContext())) {
        showFloatView();
        CallPhone();
    } else {
       Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
       startActivity(intent);
    }
}

else判断用于开启跳转去系统设置界面

如果点击不需要直接去拨号界面就好了

另外之前不是申请了拨打电话权限嘛,在申请权限回调的方法里:

if (Settings.canDrawOverlays(getApplicationContext())) {
   showFloatView();
   CallPhone();
} else {
   showSaveDialog();
}

需要完整代码可以留言跟我说。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值