Android Settings(Preferences)开发

Android settings命令讲解和实战 在Android系统中,settings命令用于管理设备设置。这些命令可以与`Settings`提供者(`Settings provider`)交互,后者是一个用于存储和检索系统设置的系统服务。Settings provider在Android系统中可以被看作是一个特殊的数据库,它用于存储和检索系统设置。这个数据库是为系统和应用程序提供的键值对存储服务,用于保存用户的偏好设置、系统配置和其他各种参数。Settings provider 的设计允许它高效地处理大量的设置项,并且能够确保设置的一致性和安全性。此 阅读详情

在Android的app开发中,很多时候我们的app需要提供用户一个用户体验统一的,友好的setting界面,也就是设置界面。在android系统中,就有一个settings设置的系统应用,专门用户设置系统的一些用户属性。那么这样的setting界面我们怎么开发呢?android为我们提供了一个程序员非常友好的preferences开发包:android.preference。这个开发包中,包含了众多我们在开发app的设置界面时需要的类,这个包的详情页:
https://developer.android.com/reference/android/preference/package-summary.html
下面我们结合google的开发指导文档,讲解一下android中的preferences设置界面的开发。Google的开发知道文档:
https://developer.android.com/guide/topics/ui/settings.html
另外,在开发setting界面的时候,这个界面的设计也是有一定的设置哲学的,在进行自定义开发的时候最好遵循这些设置哲学,不至于使你的app界面显得太过于突兀。Google关于Setting界面设置的建议文档:
https://material.google.com/patterns/settings.html
如果你想打造更好HMI的app以及线上web站点的话,那么你最好遵循这些设计原则。
我的demo代码地址:
https://github.com/CreateChance/AndroidSettingsDemo

为什么使用preferences来开发?

这是一个好问题,人们在做一些事情之前总是喜欢问下为什么。在通常app的开发过程中,我们都会为我们的app提供一个设置界面,易方便用户对我们的应用做一些必要的个性化的设置。但是很多时候,我们需要提供的设置项很多,关系也有些复杂,如果自己通过布局文件的形式去做的话,会比较麻烦,会使得UI布局的层级不够清晰,不容易日后维护和升级。因此,Google为了减轻广大开发者在开发setting界面时的困苦,google推出了preferences包。preferences包,顾名思义,就是使用android中的sharedpreferences技术来将我们的设置数据进行本地持久化,并且提供了内部封装的自动数据同步逻辑,使得我们的开发者只关心自己的app需要有那些设置,这些设置项的位置在哪里等业务逻辑,并不用关系数据怎么存储,数据怎么同步的非业务逻辑,这样一来,就大大减少了。但是由于这里使用的是sharedpreferences技术,也就是xml技术来存储数据的,因此如果你的数据结构和逻辑比较复杂的话那么你最好使用sqlite数据库来存储。这里我们总结一下preferences包的好处:
1. 简化setting界面开发,使得界面和逻辑解耦
2. 简化需要保存的数据结构和逻辑比较简单的情况下的轻量级存储的开发

开发的步骤

使用preferences包来开发基本不需要开发者了解sharedpreferences持久化技术,但是如果你了解的话,可以帮助你更好地理解preferences setting的开发。
在开始之前,我们先看下android.preference包中有哪些类:
这里写图片描述
这些类中,PreferenceActivity和PreferenceFragment是我们界面开发重点关注的类,他们是构建设置界面的基础。这里需要说明一下,从android 3.0(api 11)之后,google一直建议开发使用fragment开发不要使用activity开发,因为fragment的开发使得界面编程更加灵活,代码更加清晰易懂。因此在设置界面开发过程中,google也是推荐使用PreferenceActivity内嵌PreferenceFragment方式进行开发。其中PreferenceActivity只是负责设置选项的设置,具体的设置界面和逻辑需要使用PreferenceFragment完成。

android提供的设置界面组件

android提供了很多用于构建设置界面的ui组件,这些组件就在上面给出的包图中,那些以常用view组件名开头的preference就是android提供的设置界面组件。下面3个是最常用的组件:
1. CheckBoxPreference
这是一个提供check box的设置界面组件,使得用户可以通过勾选的方式进行设置。
2. ListPreference
这个组件当用户单击的时候会弹出一个对话框让用户以单选的形式进行选择。
3. EditTextPreference
这个组件当用户单击的时候会弹出一个对话框,对话框上有一个edit text组件,让用户输入。
下面我给出的demo中就会演示这3个组件的使用,其他的组件使用方式大同小异。

开发第一步:定义PreferenceActivity的header布局xml

前面我们说道,PreferenceActivity在3.0+系统上,只是负责设置界面的显示,不负责具体设置项的问题。因此,为了让PreferenceActivity显示我们的设置项,我们需要定义header文件,这个文件存放在res的xml目录下:
preference_headers.xml

<?xml version="1.0" encoding="utf-8"?>
<preference-headers xmlns:android="http://schemas.android.com/apk/res/android">
    <header
        android:fragment="com.createchance.androidsettingsdemo.PrefsFragmentOne"
        android:icon="@mipmap/ic_launcher"
        android:title="设置1"
        android:summary="第一个设置"/>

    <header
        android:fragment="com.createchance.androidsettingsdemo.PrefsFragmentTwo"
        android:icon="@mipmap/ic_launcher"
        android:title="设置2"
        android:summary="第二个设置"/>

</preference-headers>

这里我放了两个设置:设置1和设置2,并且每个设置下面都有一个summary描述。同时需要说明的是,上面的文件只是定义了两个选项,但是这两个选项中的内容是需要通过fragment来实现的,因此这里我指定了实际处理的fragment类。
定义完header文件后我们就可以在PreferenceActivity的子类中复写onBuildHeaders和isValidFragment这两个方法。onBuildHeaders方法是用来加载并且显示上面我们定义的header文件的,isValidFragment这个方法即使告诉是系统目前的这个fragment是不是一个有效的fragment,这两个方法都是强制必须实现的。下面是我的代码:

public class MainActivity extends PreferenceActivity {

    @Override
    public void onBuildHeaders(List<Header> target) {
        super.onBuildHeaders(target);

        loadHeadersFromResource(R.xml.preference_headers, target);
    }

    @Override
    protected boolean isValidFragment(String fragmentName) {
        Log.d("DEBUG", "isValidFragment, fragmentName: " + fragmentName);

        return true;
    }
}

可以看到,MainActivity根本都不用复写onCreate方法和调用setContentView方法设置布局。
运行之后可以看到这样的界面:
这里写图片描述

开发第二步:定义preference布局xml

上面的header只是定义了设置项,但是设置项中有什么我们还没有定义。现在我们就要定义这个布局文件,上面的header文件指定了处理的fragment,因此当用户点击上面的设置项的时候,就会实例化相应的fragment并且添加到当前的activity中显示。
preference布局文件必须以PreferenceScreen为根,其中的元素可以是上面我们提到的3个常见组件,并且preference提供了布局分组功能,也就是说可以让我们把几个设置归为一个类别进行分类显示,这个使用PreferenceCategory描述,下面是我的布局文件:

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <RingtonePreference
        android:ringtoneType="all"
        android:title="@string/ringtone_setting_title"
        android:summary="@string/ringtone_setting_summary"
        android:showDefault="false"
        android:defaultValue="true"
        android:key="ring_key"
        android:showSilent="true"/>

    <PreferenceCategory
        android:title="@string/category_setting_one">

        <CheckBoxPreference
            android:title="@string/g1_checkbox_setting_title"
            android:summaryOn="@string/checkbox_setting_summary_on"
            android:summaryOff="@string/checkbox_setting_summary_off"
            android:defaultValue="false"
            android:key="g1_checkbox_key"/>

        <ListPreference
            android:key="g1_list_key"
            android:title="@string/g1_list_setting_title"
            android:summary="@string/list_setting_summary"
            android:dialogIcon="@android:drawable/stat_sys_warning"
            android:dialogTitle="第一组列表设置"
            android:entries="@array/list_array_title"
            android:entryValues="@array/list_array_value"/>

        <EditTextPreference
            android:key="g1_edit_key"
            android:title="@string/g1_edit_setting_title"
            android:summary="@string/edit_setting_summary"
            android:dialogTitle="请输入:"/>

    </PreferenceCategory>

    <PreferenceCategory
        android:title="@string/category_setting_two">

        <CheckBoxPreference
            android:title="@string/g2_checkbox_setting_title"
            android:summaryOn="@string/checkbox_setting_summary_on"
            android:summaryOff="@string/checkbox_setting_summary_off"
            android:defaultValue="false"
            android:key="g2_checkbox_key"/>

        <ListPreference
            android:key="g2_list_key"
            android:title="@string/g2_list_setting_title"
            android:summary="@string/list_setting_summary"
            android:dialogIcon="@android:drawable/stat_sys_warning"
            android:dialogTitle="第二组列表设置"
            android:entries="@array/list_array_title"
            android:entryValues="@array/list_array_value"/>

        <EditTextPreference
            android:key="g2_edit_key"
            android:title="@string/g2_edit_setting_title"
            android:summary="@string/edit_setting_summary"
            android:dialogTitle="请输入:"/>

    </PreferenceCategory>

    <SwitchPreference
        android:key="show_advanced_setting"
        android:title="@string/show_advanced_setting_title"
        android:summary="@string/show_advanced_setting_summary"
        android:defaultValue="false"/>


</PreferenceScreen>

我定义了一个铃声设置,两个demo分组设置,还有一个高级设置的switch按钮设置。高级设置也是一个preference的xml文件定义如下:

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <PreferenceCategory
        android:key="advanced_settings"
        android:title="@string/advanced_setting_title">
        <CheckBoxPreference
            android:key="advanced_checkbox_setting"
            android:title="高级勾选设置"
            android:summary="勾选确认"/>
    </PreferenceCategory>
</PreferenceScreen>

最后需要说明一下,前面我们定义了一个列表设置项,因此我们需要array来提供列表显示项和相应的值,我们可以把它定义在array资源文件中:
arrays.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="list_array_title">
        <item>item 1</item>
        <item>item 2</item>
        <item>item 3</item>
        <item>item 4</item>
        <item>item 5</item>
    </string-array>

    <string-array name="list_array_value">
        <item>value 1</item>
        <item>value 2</item>
        <item>value 3</item>
        <item>value 4</item>
        <item>value 4</item>
    </string-array>


</resources>

定义完毕preference文件之后,我们还需要定义PreferenceFragment的子类来显示这个布局文件。

开发第三步:定义PreferenceFragment的子类

我们只要新建一个类并且继承自PreferenceFragment类就可以,然后我们还需要复写它的onCreate方法,在这个方法中调用addPreferencesFromResource方法显示我们上面的布局文件。同时我们还需要监听高级设置的switch button的按下的值来决定是不是需要显示高级设置界面,因此需要在这个fragment启动的时候判断高级设置项的状态,如果发现高级设置被关闭了,那么就要隐藏高级设置,反之则要显示。
这里有几个问题需要处理:
1. 怎么监听高级设置的按下情况?
答:实现sharedpreference的OnSharedPreferenceChangeListener接口来实现数据监听,因为preference设置时使用sharedpreference存储的。
2. 怎么隐藏或者显示高级设置?
我们在启动fragment的时候调用addPreferencesFromResource显示我们定义的布局文件,这个方法是将参数中指定的resource文件添加到当前显示ui结构中,因此我们可以通过这个方法显示高级设置界面。那么怎么隐藏呢?我们通过addPreferencesFromResource添加了界面之后,fragment中就会有一个根preference,我们通过的这个根的removePreference方法来移除我们的高级设置界面,removePreference方法的参数是一个preference对象,这个可以通过PreferenceFragment的findPreference(String key)方法来获得目前已经添加到该fragment中显示的preference。这样我们就可以控制高级界面的显示和隐藏了。PreferenceFragment子类代码如下:

public class PrefsFragmentOne extends PreferenceFragment
        implements SharedPreferences.OnSharedPreferenceChangeListener{

    private PreferenceScreen screen = null;

    public PrefsFragmentOne() {
        // Required empty public constructor
    }


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        addPreferencesFromResource(R.xml.preference_settings);

        screen = getPreferenceScreen();
    }

    @Override
    public void onResume() {
        super.onResume();
        getPreferenceScreen().getSharedPreferences()
                .registerOnSharedPreferenceChangeListener(this);

        SwitchPreference switchPreference = (SwitchPreference) findPreference("show_advanced_setting");
        if (switchPreference.isChecked()) {
            addPreferencesFromResource(R.xml.preference_advanced_setting);
        }
    }

    @Override
    public void onPause() {
        super.onPause();
        getPreferenceScreen().getSharedPreferences()
                .unregisterOnSharedPreferenceChangeListener(this);
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);

        getActivity().setTitle("设置1");
    }

    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
        Log.d("DEBUG", "key: " + key);
        if ("show_advanced_setting".equals(key)) {
            boolean enabled = sharedPreferences.getBoolean(key, false);

            if (enabled) {
                // show advanced setting here.
                addPreferencesFromResource(R.xml.preference_advanced_setting);
            } else {
                // remove advanced setting here.
                PreferenceCategory preferenceCategory = (PreferenceCategory) findPreference("advanced_settings");
                if (preferenceCategory != null) {
                    screen.removePreference(preferenceCategory);
                }
            }
        }
    }
}

这里是PrefsFragmentOne的代码,PrefsFragmentTwo的代码和它一样。同时需要说明一下,当fragment resume的时候我们添加了监听器,在fragment pause的时候我们需要反注册监听器。另外如果你不是像我那样使用fragment来实现OnSharedPreferenceChangeListener,而是使用单独的一个类(内部或者外部类)来实现它的话,你需要在你的代码中明确持有一份这个监听器的强引用,否则这个监听器对象会被GC的,原因是preference manager不会包含这个监听器的任何引用。如下代码是有问题的代码:

prefs.registerOnSharedPreferenceChangeListener(
  // Bad! The listener is subject to garbage collection!
  new SharedPreferences.OnSharedPreferenceChangeListener() {
  public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
    // listener implementation
  }
});

应该使用下面的代码:

SharedPreferences.OnSharedPreferenceChangeListener listener =
    new SharedPreferences.OnSharedPreferenceChangeListener() {
  public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
    // listener implementation
  }
};
prefs.registerOnSharedPreferenceChangeListener(listener);

运行上面的代码可以看到这样的界面:
这里写图片描述
当用户点击“设置铃声”时,界面如下:
这里写图片描述
当用户点击“第一组列表设置”时,界面如下:
这里写图片描述
当用户点击“第一组输入设置”时,界面如下:
这里写图片描述
当用户点击“显示高级设置”时,界面如下:
这里写图片描述
同时我们将这个应用运行于平板上的时候界面如下:
这里写图片描述
我们看到了这个时候自动做了屏幕大小的适配,分屏显示以充分利用屏幕(这个真的很方便)。
前面我们说道,这里的数据会存储在sharedpreference中,因此我们这里进入平板模拟器(普通设备是需要root权限的)的/data/data/com.createchance.androidsettingsdemo/shared_prefs(这是android app的私有数据目录)这个目录下看下有什么:
这里写图片描述
我们打开com.createchance.androidsettingsdemo_preferences.xml文件看下:
这里写图片描述
我们看到我们所有的设置全部保存在这里!!并且下次我们再次进入设置界面的时候,会自动根据之前设置的值,同步界面组件的显示。
大家有没有感觉这个界面的风格和系统的settings应用很像?是的,settings的界面也是使用这个技术开发的,因此你的app的设置风格可以和系统的设置风格一致,这就满足人机交互设计学上所讲的“一致性”原则了!!这也是为什么google鼓励开发使用它开发的原因!!!

诠视MR眼镜Unity开发设置_Unity2020.3.38 请按照如下设置Android SDK 和 Gradle。打包前先将Unity切换到Android模式。Preferences 设置。 阅读详情

相关推荐

Unity 2020安卓打包配置全攻略:从JDK、SDK、NDK到避坑指南

在移动应用开发中,构建与打包是连接开发与部署的关键环节,其核心在于工具链的协同与版本管理。Unity引擎的安卓打包流程,本质上是一个由Java开发工具包(JDK)、安卓软件开发工具包(SDK)和原生开发工具包(NDK)共同构成的复杂构建系统。理解其原理,关键在于掌握各组件(如JDK 8、Gradle)的版本兼容性与环境配置逻辑。这套技术方案的价值在于将游戏或应用的C#/C++代码与资源,通过IL2CPP等后端,高效、稳定地编译为可在安卓设备上运行的APK或AAB包,是实现跨平台发布的技术基石。其应用场景广泛

weixin_33860553的博客 360

Android settings

setting数据库主要使用 SettingsProvider+DatabaseHelper 实现,类似的实现还有 通讯录、通话记录frameworks\base\packages\SettingsProvider\src\com\android\providers\settings\SettingsProvider.javaframeworks\base\packages\SettingsProvider\src\com\android\providers\settings\DatabaseHelper.

xiaowang_lj的博客 5265

Unity2019安卓打包环境配置全攻略:从SDK、JDK到Gradle避坑指南

在移动应用开发中,构建环境的正确配置是项目成功打包部署的基础。其核心原理在于协调SDK、JDK、NDK和Gradle等工具链的版本与路径,确保各组件能协同工作。稳定的构建环境对于提升开发效率、保障团队协作至关重要,尤其在游戏开发、企业级应用打包等场景中。本文聚焦于Unity2019这一特定版本,针对其安卓打包过程中常见的“Gradle构建失败”、“JDK版本不兼容”等典型问题,提供了从组件选型、分步配置到高频错误排查的完整工程实践方案,旨在帮助开发者搭建一个可靠、可复现的安卓构建流水线。

weixin_30791095的博客 402

Android Settings中Preference的理解以及使用

Android Settings中Preference的理解以及自定义修改Preference

hhbstudy的博客 4248

Unity安卓开发环境搭建:手动配置SDK/NDK与镜像源解决模块下载失败

在移动应用开发中,Android SDK和NDK是构建安卓应用的核心工具链,它们提供了编译、调试和打包所需的底层库与命令行工具。其工作原理在于为Unity等游戏引擎或开发框架提供与安卓系统API交互的桥梁,并通过Gradle等构建系统管理依赖。对于国内开发者而言,直接访问Google官方服务器下载这些组件常因网络限制导致失败,严重影响开发效率。此时,技术价值体现在通过使用国内镜像源手动配置环境,能确保开发工具链的完整与稳定。这一实践在Unity引擎的安卓平台发布、跨平台游戏开发及持续集成流水线等场景中尤为重

weixin_34025151的博客 327

Unity项目一键生成安卓APK:从开发到真机测试的完整链路

本文详细介绍了Unity项目一键生成安卓APK的完整流程,从手机端准备到电脑端环境配置,再到构建配置与设备连接,最后生成APK并进行真机测试。内容涵盖Unity Remote 5应用安装、开发者模式开启、Android Studio环境配置、Unity编辑器设置、签名证书创建等关键步骤,帮助开发者高效完成安卓APK打包与测试。

361

IDEA中安装Android SDK

Preparing "Install Android Support Repository (revision: 47.0.0)". Downloading https://dl.google.com/android/repository/android_m2repository_r47.zip "Install Android Support Repository (revision: 47....

Amy的专栏 2801

Unity与Vuforia打造多图识别AR应用:从开发到安卓APK打包全流程

增强现实(AR)技术通过将虚拟信息叠加到现实世界,为用户创造了全新的交互体验。其核心原理在于计算机视觉的实时识别与跟踪,结合三维渲染引擎,实现虚实融合。在移动开发领域,这项技术能极大提升教育、营销、娱乐等场景的沉浸感和互动性。Vuforia作为成熟的AR开发平台,提供了稳定的图像识别能力,而Unity引擎则以其强大的跨平台渲染和资源管理功能,成为构建AR内容的首选工具。将两者结合,开发者可以高效创建出基于图像目标(Image Target)的AR应用。本文聚焦于如何利用Vuforia实现多图识别,并详细解析

weixin_30675247的博客 417

Android studio的preferences在哪

File+settings

qq_27494201的博客 8962

Android Preference隐藏,删除方式

隐藏 Preference 有两种方法: 一、先在xml布局里面删,然后在java里面删掉调用的相关部分,但如果很多地方都有调用,那么删除就很麻烦; 二、用removePreference(Preference preference) 方法 删除;//推荐方法 实例: testpreference.xml 代码: <?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.a

码点 4076

android 13.0 Settings主页动态显示和隐藏设置项(一级菜单显示和隐藏)

在13.0定制化开发Settings时,有产品需求要求对主页设置项需要动态控制显示和隐藏,这就需要用定义两个页面来区分加载不同settings页面 接下来分析下相关的实现流程

安卓兼职framework和app工程师的博客 1362

Pocket Casts Android设置与偏好配置:个性化你的播客聆听方式

Pocket Casts Android是一款功能强大的播客应用,它提供了丰富的设置和偏好配置选项,让用户可以根据个人喜好定制独特的播客收听体验。🎧 无论你是播客爱好者还是新手用户,了解这些设置都能帮助你更好地管理订阅、优化播放体验并个性化应用界面。在这篇完整指南中,我们将深入探讨Pocket Casts Android的设置系统,帮助你充分利用这个优秀的播客应用。 ## 📱 应用外观与主题

gitblog_00713的博客 1103

Unity采样器过多导致URP默认的Lit.Shader报错(shader error in ‘universal render pipeline/lit’: maximum ps_4_0 samp)

Shader中多个Sample Texture2D,Sample Texture3D或者类似节点的使用,该类节点都需要一个采样器,如果Shader使用超过了16个纹理采样器,如多个Base Color,Normal Map等,就容易超出。是因为每种Shader Model和GPU都有一个对纹理采样器数量的限制,是因为每个采样器都需要在显卡占用一个独立的寄存器,而寄存器的数量是有限的,当超过限制,显卡无法分配更多的寄存器给新的采样器,因此会导致编译错误。2.什么原因导致纹理采样器超出16个?

qq_41884036的博客 4233

Android学习笔记 92. Shared preferences && App settings

Android学习笔记 92. Shared preferences && App settings

代码改变世界 461

TI C2000 , .cmd文件,.TI.ramfunc,将程序分配为在RAM中运行/Flash运行的配置方法和原理讲解,(如28375S ,280049,28335等等芯片)

1 基础知识讲解 1.1 在RAM中运行还是在flash中运行指的是什么? 1.1.1 背景:程序编译完之后生成的.bin文件,.bin文件中包含代码段,代码段中全是汇编指令,而汇编指令中包含多个函数,各函数头的地址不同,如存在A函数和B函数,假设RAM地址区间是0x0000-0x8000,flash的地址区间是0xA000-0xF000,A函数要调用B函数,则A函数调用B函数的那段汇编指令中包含的是B函数头的存储地址,A函数和B函数都在flash中有存储 1.1.2 情况1:B函数是配置为在RAM中运行,

weixin_43776284的博客 8065

jetson nano网络配置(有线、无线、USB)

注意:本节内容使用Jetson nano B01 版本或Jetson nano ALT 版本安装方式相同,在安装无线网卡等设备时,由于线材和设备比较脆弱,需要轻拿轻放,接口连接不上时,需要重新对准接口在进行连接,不要强行连接。Jetson nano 需要连接网络来进行更多的操作,本节就来讲解Jetson nano 的三种网络连接方法。有线:我们可以使用网线连接Jetson nano 的RJ45 接口,实现联网。

m0_73841621的博客 1万+

Unity安卓开发环境一键配置:绕过Android Studio,极简搭建PICO G2 4K VR开发环境

在移动应用与XR(扩展现实)开发中,Android SDK与NDK是构建应用的核心工具链,它们为应用提供了系统接口与本地代码编译能力。传统上,开发者需通过安装完整的Android Studio来获取这些组件,但该IDE体积庞大、配置繁琐,尤其对专注于Unity引擎的VR/AR开发者而言,其中大部分功能冗余。通过解耦与自动化思路,利用轻量级的Android Command Line Tools和脚本技术,可以精准下载仅需的SDK Platform、Build-Tools及特定NDK版本,实现环境的一键部署。这

weixin_34121304的博客 322

基于51单片机的多功能智能路灯控制系统(仿真+代码+原理图)

智能路灯控制系统主要由51单片机最小系统+1602显示模块+DS1302时钟模块+光强检测模块+按键输入模块+声光报警模块+LED照明模块+状态检测电路+人体车辆红外检测模块组成。能实现以下功能: 1.能够按键设定系统时间、工作时间、光照阈值 2.工作时间内路灯点亮,凌晨12点后路灯关闭,有人或车通过是,路灯点亮10s 3.非工作时间光照强度低于阈值,路灯点亮 4.能够检测系统工作状态,路灯应亮未亮,声光报警 5.具备手动控制,能够切换自动/手动控制功能

u012759563的博客 8177

Unity安卓打包实战:从环境配置到真机调试的完整指南

在移动应用开发中,部署与打包发布是将创意转化为可运行应用的关键环节,它直接决定了应用在不同设备上的稳定性和性能表现。其核心原理在于通过项目配置、资源优化和平台适配,将开发环境中的项目转换为可在目标设备上执行的安装包。这一过程的技术价值在于打通了开发与交付的最后一公里,确保了应用在碎片化的硬件环境中仍能提供一致的用户体验。在Unity引擎的安卓开发场景中,这涉及到从环境准备、Player Settings配置、构建优化到真机调试的全链路工程实践。本文将结合APK构建与性能分析等热词,深入解析如何高效完成Uni

weixin_34032621的博客 416

鲁棒优化 (Robust Optimization) 算法详解及案例分析

鲁棒优化是一种用于处理不确定性优化问题的方法。其目标是在不确定性参数的可能取值范围内,找到一个对不确定性具有鲁棒性的解。

闲人编程的博客 4328

【AUTOSAR-COM】-5.2-“Deadline Monitoring超时监控”-2-基于IPdu实现

目录 1 在CFG中配置Deadline Monitoring超时监控 1.1 参数说明 1.2 生成代码差异 2 通过一段测试代码看Deadline Monitoring超时监控 3 使用CAN盒观察Deadline Monitoring实际测试效果 3.1 Case 1:ECU开始工作时,没有收到Frame 3.2 Case 2:ECU工作中,接收的Frame丢失、 4 小结 5 结尾 关键字: DM=Deadline Monitoring超时监控 ComFirstTime...

「汽车电子助手」的博客 1788

Android7.0快捷图标:Quick Settings Tile

实现效果: 其实很简单,实现过程: 1、写一个服务继承TileService,里面实现四个方法: public class MyTileService extends TileService { final String LOG_TAG = "MyTileService"; @Override public void onTileAdded() { ...

侠亦狐的博客 3235

损失函数大汇总(四十五)(clDice Loss附公式推导与代码)

clDice Loss是一种针对细长结构分割任务的拓扑保持损失函数,通过比较预测区域和真实区域的中心线重叠情况来评估分割质量。与传统Dice Loss关注区域重叠不同,clDice Loss重点考察连通性和骨架拓扑结构,能有效避免血管断裂、分支错误连接等问题。该损失函数包含两个核心指标:预测骨架在真实区域中的覆盖比例(Topology Precision)和真实骨架被预测区域覆盖的比例(Topology Sensitivity),通过调和平均得到最终评估值。由于传统骨架提取算法不可导,实际实现采用可微的so

悦学共鸣,温柔以待,汇聚光芒,共同成长 451

Deep-Live-Cam 完整指南:单张照片实时换脸,5 分钟跑通直播级 AI 换脸

选一张照片、点一下 Live,几十秒后摄像头里的脸就换成了照片里的人,而且张嘴说话的动作还是你自己的。Deep-Live-Cam 是一个开源的单图实时换脸工具,跑在本机,支持 NVIDIA 显卡、Apple 芯片和纯 CPU,预览窗口可以直接推流直播。 ## 项目速览:先看清它能做什么 | 核心能力 | 一句话说明 | 典型场景 | |------|----------|----------|

gitblog_01005的博客 768

解读MTF曲线

怎样看MTF曲线 光学模量传递函数所表示的就是模量传递函数值随空间频率和像场位置变化的函数关系。它有很多种类型, 但最主要的两种类型就是MTF值与空间频率的关系和与像场半径(或像场角)之间的关系。 1、什么是空间频率 在讲清MTF曲线随空间频率的变化关系以前,我们先来弄明白什么叫“空间频率”。 空间频率(Spatial Frequency)的概念与分辨率的概念非常相似,单位都是“线对/毫米”(lp/mm)。但测试分辨率的标板是一组一组轮廓鲜明的黑白线条,每两条线条之间的距离,以及线条本身的宽度之比是.

camerall 1万+

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

Eclipse和Android Studio的偏好设置Preferences的导出与导入

很多同学都会碰到这样的问题,就是原先在自己的笔记本上进行项目开发,对于Eclipse和Android Studio中的各项设置已经非常熟悉和满意,如背景设置,快捷键设置,编码设置等等。如果此时需要到另一台公司电脑进行开发,必须重装Eclipse和Android Studio,如果现在对那些自定义设置重头开始配置的话,那就极为麻烦的,也是效率相当低下的。如果看到同事的IDE环境设置非常好,想要拿过来

乞力马扎罗的雪CYF的博客 8254

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

上一篇: Android 6.0指纹识别App开发demo
下一篇: Linux中的共享库之版本管理
createchance
博客等级 码龄15年 156粉丝 90原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值