kotlin_08:wlan直连/wifi_p2p的页面跳转以及实时获取连接状态

前言之前一段时间一直加班,淦。五一,有点时间,简单的陈述一下,wlan直连页面的跳转和状态获取以及监听。

1. 先看效果

在这里插入图片描述

2. 布局文件

2.1 wifi_p2p_actvity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/btn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        android:text="点击手动获取wlan直连连接状态"/>

    <TextView
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:hint="请点击上方按钮获取最新状态值"
        android:gravity="center"
        android:id="@+id/txt"/>

    <TextView
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:text="@string/hyper_link_tip_direct"
        android:gravity="center"
        android:id="@+id/hyper_link_tip_direct"/>
    
</LinearLayout>

2.2 strings.xml

<resources>
    <string name="app_name">系统跳转</string>
    <string name="hyper_link_tip_direct">请点击:wlan直连 实现跳转</string>
    <string name="hyper_link_wlan_direct">wlan直连</string>
</resources>

3. WiFiP2pActivity.kt

3.1 跳转到wlan直连页面方式

    // wlan direct页面
    private fun startWlanDirectActivity() {
        val intent = Intent()
        intent.addCategory(Intent.CATEGORY_DEFAULT)
        intent.action = "android.intent.action.MAIN"
        val cn = ComponentName(
            "com.android.settings",
            "com.android.settings.Settings\$WifiP2pSettingsActivity" // 华为 nova6 wlanDirect页面(亲测)
        )
        intent.component = cn
        startActivity(intent)
    }

3.2 定位服务权限检查

如果想获取或者监听wlan直连的设备信息和状态,就必须让你写的activity拥有位置定位信息的权限,否则监听或者获取不到设备信息。

    private fun checkLocationPermission(){
        // 需要动态检查定位服务的权限是否开启
        if (ActivityCompat.checkSelfPermission(
                this,
                Manifest.permission.ACCESS_FINE_LOCATION
            ) != PackageManager.PERMISSION_GRANTED
        ) {
            ActivityCompat.requestPermissions(
                this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
                PERMISSION_LOCATION_CODE
            )
            return
        }
    }
    /**
     * 请求权限结果
     */
    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if (requestCode == PERMISSION_LOCATION_CODE) {
            if (grantResults.isNotEmpty() && grantResults[0] != PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(
                    context,
                    "请授予该应用定位服务权限,否则无法获取wifi p2p 连接状态",
                    Toast.LENGTH_SHORT
                ).show()
            }
        }
    }

3.3 广播监听

想要实时监听wlan直连的连接状态的话,自然少不了广播,而wlan直连的广播监听以后很多,这里只监听设备连接和断开。

//1. 定义一个WiFiDirectBroadcastReceiver 广播
    private inner class WiFiDirectBroadcastReceiver : BroadcastReceiver() {

        override fun onReceive(p0: Context?, intent: Intent?) {
            when (intent?.action) {
                WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION -> {
                    Log.e(TAG, "intent = ${intent.extras.toString()}")
                    val networkInfo =
                        intent.getParcelableExtra<NetworkInfo>(WifiP2pManager.EXTRA_NETWORK_INFO)
                    val wifiP2pDevice =
                        intent.getParcelableExtra<WifiP2pDevice>(WifiP2pManager.EXTRA_WIFI_P2P_DEVICE)
                    connectState = if (networkInfo?.isConnected == true) {
                        Log.d(TAG, "Connect to wifi p2p. ${wifiP2pDevice?.deviceName}")
                        true
                    } else {
                        Log.d(TAG, "DisConnect to wifi p2p.")
                        false
                    }
                    updatePage()
                }
            }
        }
    }
//2.在onCreate()中注册
    private fun registerReceiver() {
        if (broadcastReceiver != null) return
        broadcastReceiver = WiFiDirectBroadcastReceiver()
        val intentFilter = IntentFilter()
        intentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION)
        context?.registerReceiver(broadcastReceiver, intentFilter)
    }
//3. 在onDestroy()中反注册
    private fun unregisterReceiver() {
        if (broadcastReceiver == null) return
        context?.unregisterReceiver(broadcastReceiver)
        broadcastReceiver = null
    }

3.4 判断wlan直连是否有设备的API

仅仅通过监听只能解决动态变化的场景,如果wlan直连一直是连接的状态,此时想获取到信息的话,只能通过调用api来判断了。在android官网上关于wlan Direct 的api都是有介绍的,此处不在赘述。

  1. 当然想要这个api,你需要在onCreate()中做以下几件事
    private var context: Context? = null
    private var manager: WifiP2pManager? = null
    private var channel: WifiP2pManager.Channel? = null
    private var broadcastReceiver: BroadcastReceiver? = null
    private var connectState = false
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.wifi_p2p_activity_main)
        checkLocationPermission()
        context = this
        manager = getSystemService(Context.WIFI_P2P_SERVICE) as WifiP2pManager
        channel = manager?.initialize(this, mainLooper, null)
        registerReceiver()
        updatePage()
  1. requestPeers用来扫描发现已连接的设备
    @SuppressLint("MissingPermission")
    private fun startSearch() {
        manager?.requestPeers(channel, object : WifiP2pManager.PeerListListener {
            override fun onPeersAvailable(p0: WifiP2pDeviceList?) {
                connectState = false
                p0?.deviceList?.forEach {
                    if (WifiP2pDevice.CONNECTED == it.status) {
                        Log.d(TAG, "One device connected.${it?.deviceName}")
                        connectState = true
                        updatePage(it?.deviceName)
                        return
                    }
                }
            }
        })
    }

4 页面跳转和刷新

4.1 在onCtreate()中添加页面跳转逻辑

        findViewById<Button>(R.id.btn).setOnClickListener {
            startSearch()
        }

        // wlan直连
        setHyperLinkTips(
            findViewById<TextView>(R.id.hyper_link_tip_direct),
            getString(R.string.hyper_link_tip_direct),
            getString(R.string.hyper_link_wlan_direct),
            "android.settings.WIFI_P2P_SETTINGS",
            this
        )
        
   /**
     * 设置超链接
     * @tipsView: 超链接设置的TextView
     * @content:文本所有的内容
     * @hyperText:超链接文字
     * @action:intent跳转的action
     * @context:Context
     * Tips:超链接文字hyperText要在content中包含
     */
    private fun setHyperLinkTips(
        tipsView: TextView?,
        content: String,
        hyperText: String,
        action: String,
        context: Context
    ) {
        val spannableString = SpannableStringBuilder(content)
        val span = object : ClickableSpan() {

            override fun onClick(p0: View) {
                Log.i(TAG, "Go to $hyperText page.")
                try {
                    startWlanDirectActivity()
                } catch (e: Exception) {
                    Log.i(TAG, "Go to $hyperText page fail.")
                }
            }
        }
        val startIndex = content.indexOf(hyperText)
        if (startIndex == -1) {
            return
        }
        val endIndex = startIndex + hyperText.length
        spannableString.setSpan(span, startIndex, endIndex, Spannable.SPAN_INCLUSIVE_INCLUSIVE)
        tipsView?.movementMethod = LinkMovementMethod.getInstance()
        tipsView?.text = spannableString
        tipsView?.highlightColor = Color.parseColor("#36969696");
    }

4.2 页面刷新

    private fun updatePage(deviceName: String? = null) {
        Log.i(TAG, "updatePage...isConnected = ${isConnected()}")
        findViewById<TextView>(R.id.txt).text = "device: $deviceName state: ${isConnected()}"
    }

总结: 广播动态监听 + api 静态调用 = 无死角获取wlan直连连接的设备信息和状态。
(如有错误,欢迎批评指正,请大佬轻喷)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

诸葛榆木

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值