Android xml的Preference设置visibility=“gone“ 无效分析解决

Android xml的Preference设置visibility="gone" 无效分析解决

文章目录

  • [Android xml的Preference设置visibility="gone" 无效分析解决](#Android xml的Preference设置visibility="gone" 无效分析解决)
  • [PS: 梦想不会平白无故地变为现实,奋斗是连接梦想与现实的桥梁](#PS: 梦想不会平白无故地变为现实,奋斗是连接梦想与现实的桥梁)

一、前言

Android 原生Settings的查看当前连接的Wifi信息里面有个"添加设备"的选项;

但是实际场景中并没有作用,想去隐藏一下,xml中添加 visibility="gone"但是没有用;

如下图的"Add device" 选项:

这个选项确实没啥用!虽然Google手机也有这样选项。

这个并不是本机设备扫描连接其他热点二维码连接上Wifi,而是扫描其他二维码让其他设备连接本机的网络;

但是实际并不可行,产品需求隐藏。

相关布局如下代码:

packages\apps\Settings\res\xml\wifi_network_details_fragment2.xml

复制代码
<PreferenceScreen
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:settings="http://schemas.android.com/apk/res-auto">

	<!-- Add device Preference -->
    <Preference
        android:key="add_device_to_network"
        android:title="@string/wifi_dpp_add_device"
        android:visibility="gone"
        android:summary="@string/wifi_dpp_connect_network_using_qr_code"/>
...

</PreferenceScreen>

本来以为是 visibility="gone" 没有作用,后面研究发现是Java代码中多个地方控制了是否可见。

所以如果xml界面设置无效可以看看Java代码实现控制的地方;

本文主要分享一下隐藏 Wifi信息的"添加设备"的选项的简单知识。

二、分析

1、AddDevicePreferenceController2.java

这个是关联"添加设备"的xml布局的代码

packages\apps\Settings\src\com\android\settings\wifi\details2\AddDevicePreferenceController2.java

复制代码
public class AddDevicePreferenceController2 extends BasePreferenceController {

    private static final String TAG = "AddDevicePreferenceController2";
    private static final String KEY_ADD_DEVICE = "add_device_to_network"; //添加设备key

	private WifiEntry mWifiEntry; //某个Wifi的配置对象

    public AddDevicePreferenceController2(Context context) {
        super(context, KEY_ADD_DEVICE); //在父类绑定的,Settings 有些代码就是这么框架!
    }

	//控制添加设备是否可见的关键方法,虽然本类中没有使用这个方法,但是父类的父类中有判断这个方法
    @Override
    public int getAvailabilityStatus() {    
        return mWifiEntry.canEasyConnect() ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
    }
}

WifiEntry.canEasyConnect() 是Wifi添加设备是否显示的关键:

复制代码
mWifiEntry.canEasyConnect() 返回true的情况,添加设备可见,返回false不可见。

所以隐藏只需要返回false的 CONDITIONALLY_UNAVAILABLE 即可。

WifiEntry.canEasyConnect()的意义是啥?

Easy Connect 是一种简化 Wi-Fi 连接的技术,允许设备通过扫码或广播信息快速连接到网络,无需手动输入密码。

验证连接条件:确认当前设备是否满足连接该网络的条件(如权限、配置等)。

难道无需密码的wifi符合这个条件?

但是通过对比发现有密码的wifi对象,canEasyConnect() 返回true,无密码的wifi对象返回false。

这个和最初的猜想是相反的!为啥会这样呢?只能追踪一下源码了。

2、WifiEntry.canEasyConnect() 的分析

源码位置:frameworks/opt/net/wifi/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiEntry.java

复制代码
/**
 * Base class for an entry representing a Wi-Fi network in a Wi-Fi picker/settings.
 * Subclasses should override the default methods for their own needs.
 *
 * Clients implementing a Wi-Fi picker/settings should receive WifiEntry objects from classes
 * implementing BaseWifiTracker, and rely on the given API for all user-displayable information and
 * actions on the represented network.
 */
public class WifiEntry {
    public static final String TAG = "WifiEntry";

	/** Returns whether the network can be shared via QR code */
    public boolean canShare() {
        return false;
    }

    /** Returns whether the user can use Easy Connect to onboard a device to the network */
    public boolean canEasyConnect() {
        return false;
    }

}

这里直接返回false,明显是不对的,那么只能找找它子类的实现了;

3、StandardWifiEntry.java

WifiEntry.canEasyConnect() 的具体实现在 StandardWifiEntry.java

frameworks\opt\net\wifi\libs\WifiTrackerLib\src\com\android\wifitrackerlib\StandardWifiEntry.java

复制代码
/**
 * WifiEntry representation of a logical Wi-Fi network, uniquely identified by SSID and security.
 *
 * This type of WifiEntry can represent both open and saved networks.
 */
public class StandardWifiEntry extends WifiEntry {
    static final String TAG = "StandardWifiEntry";

	/**
     * Returns whether the user can use Easy Connect to onboard a device to the network.
     * See https://www.wi-fi.org/discover-wi-fi/wi-fi-easy-connect
     */
    @Override
    public synchronized boolean canEasyConnect() {

        if (!mWifiManager.isEasyConnectSupported()) {
            return false;
        }
...
        // DPP 1.0 only supports WPA2 and WPA3.
        return mTargetSecurityTypes.contains(SECURITY_TYPE_PSK)
                || mTargetSecurityTypes.contains(SECURITY_TYPE_SAE);
    }
}

看最后一个就可以了,说明该wifi只能是WPA2 and WPA3的类型,看only!

无密码的是open类型,还有企业网的是EAP类型获取其他类型的wifi网络,都是不符合规定的。

所以 canEasyConnect() 并不完全值容易连接的类型,泛指 WPA2、WPA3 类型的wifi。

这也我或者大部分人想不到的吧,一切解释归Google为准,哈哈。

三、其他

1、Android xml的Preference设置visibility="gone" 无效小结

下面是部分经验:

复制代码
(1)xml 布局中 添加 visibility="gone" 无效 的情况需要分析绑定Preference对应可以的具体类;
(2)可以在绑定key的地方添加隐藏:但是可有可能无效;
(3)需要在整个绑定类里面搜索看看 setVisible 关键字,有可能存在动态设置属性的情况;
(4)还有其他特殊情况,比如是上面添加设备的情况,是在父类或者父类的父类判断是否隐藏的;
需要分析查看子类的相关方法来确定是否隐藏该选项。

2、普通的demo中Preference设置visibility写法会有差异

上面是系统源码编译的Settings 代码;

如果在Android Studio 创建的demo要应用

复制代码
<PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto">

...
    <Preference
        app:key="add_device_to_network"
        app:title="wifi_dpp_add_device"
        android:visibility="gone" //编译报错
        app:visibility="gone" //编译报错
        app:isPreferenceVisible="false" //正确写法
</PreferenceScreen>

不确定是不是编译环境的差别导致需要不同的写法才可以正常使用。

有尝试过和原生Settings 一样添加命名空间还是会报错:

复制代码
<PreferenceScreen 
	xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:settings="http://schemas.android.com/apk/res-auto">
    
    android:visibility="gone" //Android Studio中 编译还是报错

这个不上重点内容,所以不继续进行分析研究了。

3、Android Preference简单介绍

Android 原生Settings应用用到了大量的Preference显示界面和处理相应是事件,

如果要修改Settings界面了解Preference是非常必要的。

本文带大家伙一起简单入门一下Android Preference的简单使用。

https://blog.csdn.net/wenzhi20102321/article/details/136902514

4、Android Settings应用 PreferenceScreen 条目隐藏实现和简单分析

Android 原生设置Settings应用很多界面都是使用xml的 PreferenceScreen 形式进行显示,

PreferenceScreen 里面包含很多条目,如果要隐藏某个条目就要修改xml或者Java代码,

有些情况修改xml是无效的,修改Java代码才有作用。

本文简单记录一下Settings PreferenceScreen 某个条目隐藏实现。

https://blog.csdn.net/wenzhi20102321/article/details/140360299

PS: 梦想不会平白无故地变为现实,奋斗是连接梦想与现实的桥梁

相关推荐
雨白8 小时前
Jetpack系列(二):Lifecycle与LiveData结合,打造响应式UI
android·android jetpack
kk爱闹9 小时前
【挑战14天学完python和pytorch】- day01
android·pytorch·python
每次的天空11 小时前
Android-自定义View的实战学习总结
android·学习·kotlin·音视频
恋猫de小郭11 小时前
Flutter Widget Preview 功能已合并到 master,提前在体验毛坯的预览支持
android·flutter·ios
断剑重铸之日12 小时前
Android自定义相机开发(类似OCR扫描相机)
android
随心最为安12 小时前
Android Library Maven 发布完整流程指南
android
岁月玲珑12 小时前
【使用Android Studio调试手机app时候手机老掉线问题】
android·ide·android studio
还鮟17 小时前
CTF Web的数组巧用
android
小蜜蜂嗡嗡18 小时前
Android Studio flutter项目运行、打包时间太长
android·flutter·android studio
aqi0018 小时前
FFmpeg开发笔记(七十一)使用国产的QPlayer2实现双播放器观看视频
android·ffmpeg·音视频·流媒体