IM使用的悬浮框和画中画功能

阅读 434
收藏 5
2019-02-21
原文链接:xiaozhuanlan.com

如果你在手机使用中,边播放视频,边聊天和各种操作,那么你就一定会接触到悬浮框和画中画功能。
悬浮框的功能是一直都存在的,而画中画功能是Android O后推出的新功能,在没有画中画功能之前,只能使用悬浮框的功能来实现画中画功能。
需要提示框权限

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

/**
     * 请求悬浮窗权限
     * @param activity
     * @param requestCode
     * @return true表示执行跳转,false表示没有
     */
    fun requestOverlaysPermission(activity: Activity, requestCode: Int): Boolean {
        try {
            return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                //如果不支持浮窗,需要授权
                val intent = Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + activity.packageName))
                activity.startActivityForResult(intent, requestCode)
                true

            } else {
                if (ContextCompat.checkSelfPermission(activity, Manifest.permission.SYSTEM_ALERT_WINDOW) != PackageManager.PERMISSION_GRANTED) {
                    ActivityCompat.requestPermissions(activity, arrayOf(Manifest.permission.SYSTEM_ALERT_WINDOW), requestCode)
                }
                true
            }
        } catch (ex: Exception) {
            Logger.e(ex, "requestOverlaysPermission error")
        }

        return false
    }
  悬浮框的实现,其实网上一早有教程,这里就给一个简单koltin的显示教程。

```

/**
* 获取window参数
* @param context
* @param isBottom
* @return
*/
private fun getWindowParams(context: Context, width: Long, height: Long): WindowManager.LayoutParams {
val mParams = WindowManager.LayoutParams()
val defaultWidth = 默认宽度
val defaultHeight = 默认高度
if (width <= 0 || height <= 0) { mParams.width = defaultWidth mParams.height = defaultHeight } else { //显示比例调整 mParams.width = defaultWidth val ratio = width.toDouble() / height.toDouble() mParams.height = (defaultWidth / ratio).toInt() } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { //Android O调整
mParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
} else {
mParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT
}
mParams.gravity = Gravity.START or Gravity.TOP
mParams.flags = (WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)
return mParams
}

/**
* 处理展示
*/
private fun handleShow(masterSecret: MasterSecret, message: AmeGroupMessageDetail, position: Long) {
try {
if (isShowing()) //正在播放,先隐藏,再重新创建
handleHide()
context = mContextReference?.get() ?: return
}
//获取window的参数
val wmParams = getWindowParams(context!!, width, height)
val windowManager = context!!.getSystemService(Context.WINDOW_SERVICE) as WindowManager
//获取屏幕宽度,从而获取定位位置
val dm = DisplayMetrics()
windowManager.defaultDisplay?.getMetrics(dm)
//显示window的位置
wmParams.x = dm.widthPixels - wmParams.width - context!!.resources.getDimensionPixelSize(R.dimen.chats_webrtc_call_mini_x)
wmParams.y = context!!.resources.getDimensionPixelSize(R.dimen.chats_webrtc_call_mini_y)
mWM = windowManager
//视频window
mScreen = VideoPlayer(context)
windowManager.addView(mScreen, wmParams)
mScreen?.setWindowManagerAndParams(windowManager, wmParams)

                val videoSlide = VideoSlide(context, uri, videoContent!!.size)
                mScreen?.setVideoSourceV2(masterSecret, videoSlide, false)
                mScreen?.seekTo(position)
                mScreen?.setPIPMode(true)
                mScreen?.setOnClickListener {
评论