Android 14 变更及适配攻略

请添加图片描述

准备工作

首先将我们项目中的 targetSdkVersioncompileSdkVersion 升至 34。

影响Android 14上所有应用

1.最低可安装的目标 API 级别

从 Android 14 开始,targetSdkVersion 低于 23 的应用无法安装。要求应用满足这些最低目标 API 级别要求有助于提高用户的安全性和隐私性。

恶意软件通常会以较旧的 API 级别为目标平台,以绕过在较新版本 Android 中引入的安全和隐私保护机制。例如,有些恶意软件应用使用 targetSdkVersion 22,以避免受到 Android 6.0 Marshmallow(API 级别 23)在 2015 年引入的运行时权限的约束。这项 Android 14 变更使恶意软件更难以规避安全和隐私权方面的改进限制。

注意在升级到 Android 14 的设备上,targetSdkVersion 低于 23 的所有应用都将继续保持安装状态。

2.默认拒绝设定精确的闹钟

精确闹钟适用于用户指定的通知,或是在确切时间需要执行的操作。

SCHEDULE_EXACT_ALARM 是 Android 12 中引入的可让应用安排精确闹钟的权限,不再预先授予以 Android 13 和更高版本为目标平台的最新安装应用(默认情况下,设置为“拒绝”)。如果用户通过备份和恢复操作将应用数据转移到搭载 Android 14 的设备,则该权限仍然会被拒绝。如果现有应用已拥有此权限,则当设备升级到 Android 14 时,系统会预先授予此权限。

需要 SCHEDULE_EXACT_ALARM 权限才能通过以下 API 启动精确闹钟,否则系统会抛出 SecurityException

  • setExact()
  • setExactAndAllowWhileIdle()
  • setAlarmClock()

注意:如果使用 OnAlarmListener 对象设置精确闹钟(例如在 setExact API 中),则不需要 SCHEDULE_EXACT_ALARM 权限。

官方建议开发者评估其使用场景,并确定精确闹钟是否仍然适用于他们。如果可以使用不精确闹钟,可以使用WorkManager或者AlarmManagersetAndAllowWhileIdle() , setWindow()set() API。

如果继续使用精确闹钟,首先使用AlarmManagercanScheduleExactAlarms() 检查权限。没有权限时,可以引导用户跳动系统设置页 startActivity(Intent(Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM))去开启权限。最后在onResume()或者监听用户授予权限时系统发送的AlarmManager.ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED广播来设置精确闹钟。

最后记得添加权限到AndroidManifest.xml中:

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

3.关于不可关闭通知用户体验方式的变更

通过 setOngoing(true) 或设置 Notification.FLAG_ONGOING_EVENT 来阻止用户关闭前台通知的应用。在Android 14上用户实际上能够关闭此类通知。

在以下情况下,此类通知仍不可关闭:

  • 当手机处于锁屏状态时。
  • 如果用户选择全部清除通知操作(有助于防止意外关闭)。
  • 使用 CallStyle 绑定到呼叫的通知。
  • 使用 NotificationCompat.MediaStyle 创建的媒体通知。
  • 企业设备政策控制器 (DPC) 和支持软件包
  • 默认的搜索选择器软件包。

4.获得照片和视频的部分访问权限

Android 14 引入了“选定照片访问”,允许用户授予应用对其库中特定图像和视频的访问权限,而不是授予对给定类型的所有媒体的访问权限。

请添加图片描述

如果您在应用中使用了照片选择器,就无需请求任何存储权限,不受此变更影响。

如果您使用存储权限维护自己的图库选择器,请调整您的应用以使用新的READ_MEDIA_VISUAL_USER_SELECTED权限。如果您的应用不使用新权限,系统将以兼容模式运行您的应用。

兼容模式:如果应用不使用新权限,应用请求READ_MEDIA_IMAGESREAD_MEDIA_VIDEO权限,则系统会自动添加READ_MEDIA_VISUAL_USER_SELECTED权限到你的应用。当您的应用程序移动到后台时,或者当用户主动杀死您的应用程序时,系统最终会拒绝这些权限。这种行为就像其他一次性权限一样。

因为没有适配新权限,所以当用户选定了部分照片的访问权限后,如果用户想修改可见范围,无法做主动修改。因为对于此时的应用来说,是有READ_MEDIA_IMAGESREAD_MEDIA_VIDEO权限的。不可能每次都询问用户指定访问范围。

其实整体看来,兼容模式影响不大,应用可以正常使用。如果想要一个良好的用户交互体验,需要做适配,具体适配方法我们下面再详细说明。

影响以Android 13或更高版本为目标平台的应用

1.必须声明前台服务类型

为了帮助开发者更有目的地定义面向用户的前台服务,Android 10 在 元素内引入了 android:foregroundServiceType 属性。如果您的应用以 Android 14(API 级别 34)或更高版本为目标平台,则必须为应用中的每项前台服务指定至少一个前台服务类型。您应该选择一个能够代表应用用例的前台服务类型。系统需要特定类型的前台服务满足特定用例。

Android 14 中新增了 health, remoteMessaging, shortService, specialUsesystemExempted 类型,加上之前的还有camera, connectedDevice, dataSync, location, mediaPlayback, mediaProjection, microphone, phoneCall类型。

以下代码段提供了一个清单中的前台服务类型声明示例:

<manifest ...>
  ...
  <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
  <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
  <uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />
    <application ...>
      <service
          android:name=".MyMediaPlaybackService"
          android:foregroundServiceType="location|mediaPlayback"
          android:exported="false">
      </service>
    </application>
</manifest>

如果以 Android 14 为目标平台的应用未在清单中定义给定服务的类型,系统会在调用 startForeground() 时引发 MissingForegroundServiceTypeException。如果应用中的用例与这些类型均不相关,强烈建议您迁移逻辑以使用 WorkManager 或用户发起的数据传输作业。

然后上面的代码中,你会发现多了一个FOREGROUND_SERVICE_MEDIA_PLAYBACK权限,因为Android14上必须声明所选前台服务类型所对应的权限,比如mediaPlayback就对应FOREGROUND_SERVICE_MEDIA_PLAYBACK。所有这些权限都定义为一般权限,并默认授予,且用户无法撤消这些权限。

如果没有声明适当的前台服务类型权限,系统会抛出 SecurityException

也可以在启动前台服务时声明类型,此时所声明的类型应是AndroidManifest中类型的子集:

ServiceCompat.startForeground(0, notification, notification, FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK);

如果调用中未指定前台服务类型,则该类型默认为清单中定义的值。如果您未在清单中指定服务类型,系统会抛出 MissingForegroundServiceTypeException

同时注意系统会检查前台服务类型的使用是否恰当,并确认应用是否已请求适当的运行时权限或使用所需的 API。例如,系统希望使用前台服务类型 FOREGROUND_SERVICE_TYPE_LOCATION 的应用请求 ACCESS_COARSE_LOCATIONACCESS_FINE_LOCATION。其他类型规则见每种前台服务类型的预期用例和强制执行。

2.BLUETOOTH_CONNECT

BluetoothAdapter 中强制执行 BLUETOOTH_CONNECT 权限,对于以 Android 14(API 级别 34)或更高版本为目标平台的应用,Android 14 会在调用 BluetoothAdapter getProfileConnectionState() 方法时强制执行 BLUETOOTH_CONNECT 权限。

此方法已需要 BLUETOOTH_CONNECT 权限,但未被强制执行。请确保您的应用在应用的 AndroidManifest.xml 文件中声明 BLUETOOTH_CONNECT,并在调用 getProfileConnectionState 之前检查用户是否已授予权限。

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

3.OpenJDK 17 更新

Android 14 将继续更新 Android 的核心库,以与最新 OpenJDK LTS 版本中的功能保持一致,包括适合应用和平台开发者的库更新和 Java 17 语言支持。

以下变更可能会影响应用兼容性:

  • 对正则表达式的更改:现在,为了更严格地遵循 OpenJDK 的语义,不允许无效的组引用。您可能会看到 java.util.regex.Matcher 类抛出 IllegalArgumentException 的新情况,因此请务必测试应用中使用正则表达式的情形。如需在测试期间启用或停用此变更,请使用兼容性框架工具切换 DISALLOW_INVALID_GROUP_REFERENCE 标志。
  • UUID 处理:现在,验证输入参数时,java.util.UUID.fromString() 方法会执行更严格的检查,因此您可能会在反序列化期间看到 IllegalArgumentException。如需在测试期间启用或停用此变更,请使用兼容性框架工具切换 ENABLE_STRICT_VALIDATION 标志。
  • ProGuard 问题:有时,在您尝试使用 ProGuard 缩减、混淆和优化应用时,添加 java.lang.ClassValue 类会导致问题。问题源自 Kotlin 库,该库会根据 Class.forName("java.lang.ClassValue")是否会返回类更改运行时行为。如果您的应用是根据没有 java.lang.ClassValue 类的旧版运行时开发的,则这些优化可能会将computeValue 方法从派生自 java.lang.ClassValue 的类中移除。

4.对隐式 Intent 和PendingIntent 的限制

对于以 Android 14(API 级别 34)或更高版本为目标平台的应用,隐式Intent或PendingIntent只能打开设置了android:exported="true"的组件,如果android:exported="false",系统会抛出异常。

例如,下面是可以在应用的清单文件中声明的 intent 过滤器:

<activity
    android:name=".AppActivity"
    android:exported="false">
    <intent-filter>
        <action android:name="com.example.action.APP_ACTION" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

如果应用尝试使用隐式 intent 启动此 activity,则系统会抛出异常:

context.startActivity(new Intent("com.example.action.APP_ACTION"));

如需启动非导出的 activity,应用应改用显式 intent:

Intent explicitIntent =new Intent("com.example.action.APP_ACTION")
explicitIntent.setPackage(context.getPackageName());
context.startActivity(explicitIntent);

5.动态注册的广播接收器必须指定导出行为

以 Android 14(API 级别 34)或更高版本为目标平台并使用上下文注册的接收器的应用和服务必须指定一个标志,以指明接收器是否应导出到设备上的所有其他应用:分别为 RECEIVER_EXPORTEDRECEIVER_NOT_EXPORTED

这点去年的Android 13中就有相关介绍,当时不是强制适配,到Android 14开始就必须要适配了。如果不适配,会有如下崩溃信息:

java.lang.SecurityException: xxx.xxx: One of RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED should be specified when a receiver isn't being registered exclusively for system broadcasts

适配方法:

// 接收来自其他应用程序的广播
context.registerReceiver(sharedBroadcastReceiver, intentFilter, ContextCompat.RECEIVER_EXPORTED);

// 私有广播接收器
context.registerReceiver(privateBroadcastReceiver, intentFilter, ContextCompat.RECEIVER_NOT_EXPORTED);

如果应用利用Context#registerReceiver方法注册了一个系统广播接收器,那么不需要声明以上标志。如果你使用的是LocalBroadcastManager,那么也可以忽略此条变更。

6.后台启动 activity 限制

对于以 Android 14(API 级别 34)或更高版本为目标平台的应用,在原有的基础上增加了两条限制:

  • 当应用使用 PendingIntent#send() 或类似方法发送 PendingIntent 时,,其相关的参数ActivityOptions应该设置setPendingIntentBackgroundActivityStartMode(MODE_BACKGROUND_ACTIVITY_START_ALLOWED)
// A app创建pendingIntent
PendingIntent pendingIntent = PendingIntent.getActivity(this,
        0,
        notificationIntent,
        PendingIntent.FLAG_MUTABLE,
        null);
//通过将pendingIntent发送到B app
//B app收到创建的pendingcontent,然后执行send()方法发送,同时构建ActivityOptions,
//设置相应的模式
PendingIntent pendingIntent = intent.getParcelableExtra("pending");
ActivityOptions options = ActivityOptions.makeBasic()
 .setPendingIntentBackgroundActivityStartMode(ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED)
 .setPendingIntentCreatorBackgroundActivityStartMode(ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED);
pendingIntent.send(context, 0, null, null, null, null, options.toBundle());  
  • 当一个可见应用程序使用bindService()方法绑定另一个后台应用程序的服务时,如果想要授予绑定的后台服务所在应用启动Activity,必须要在绑定服务的时候,即调用bindService()方法的时候包含BIND_ALLOW_ACTIVITY_STARTS
targetSdk<34,前台应用绑定后台服务启动Activity需要BIND_AUTO_CREATE
bindService(intent, coon, BIND_AUTO_CREATE);
    
targetSdk≥34,前台应用绑定后台服务要启动Activity,需要在之前的基础上添加BIND_ALLOW_ACTIVITY_STARTS标志。
bindService(intent, coon, BindServiceFlags.of(BIND_ALLOW_ACTIVITY_STARTS|BIND_AUTO_CREATE));

7.压缩路径遍历

对于以 Android 14(API 级别 34)或更高版本为目标平台的应用,Android 会通过以下方式防止 Zip 路径遍历漏洞:如果 zip 文件条目名称包含..或以/开头,则 ZipInputStream.getNextEntry()ZipFile(String)会抛出ZipException

应用可以通过调用 dalvik.system.ZipPathValidator.clearCallback() 选择停用此验证。

8.获得照片和视频的部分访问权限

上面已经说明了相关情况,这里就不赘述了,下面直接说如何适配。

首先Android 13的基础上添加新权限:

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

请求权限时,根据版本区分请求的权限,Android 14上需要同时请求READ_MEDIA_IMAGESREAD_MEDIA_VISUAL_USER_SELECTED,如果你需要视频,那就再加上READ_MEDIA_VIDEO

private val permissionLauncher =
    registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { _ ->
        // 处理权限请求结果
    }

private fun requestPermissions() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
        permissionLauncher.launch(
            arrayOf(READ_MEDIA_IMAGES,
                READ_MEDIA_VIDEO,
                READ_MEDIA_VISUAL_USER_SELECTED)
        )
    } else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.TIRAMISU) {
        permissionLauncher.launch(arrayOf(READ_MEDIA_IMAGES, READ_MEDIA_VIDEO))
    } else {
        permissionLauncher.launch(arrayOf(READ_EXTERNAL_STORAGE))
    }
}

授权结果检查判断:

private fun checkPermissionResult() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU
        && (ContextCompat.checkSelfPermission(this, READ_MEDIA_IMAGES) == PERMISSION_GRANTED
                || ContextCompat.checkSelfPermission(this, READ_MEDIA_VIDEO) == PERMISSION_GRANTED)
    ) {
        // Android 13及以上完整照片和视频访问权限
    } else if (
        Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE &&
        ContextCompat.checkSelfPermission(this, READ_MEDIA_VISUAL_USER_SELECTED) == PERMISSION_GRANTED
    ) {
        // Android 14及以上部分照片和视频访问权限
    } else if (ContextCompat.checkSelfPermission(this, READ_EXTERNAL_STORAGE) == PERMISSION_GRANTED) {
        // Android 12及以下完整本地读写访问权限
    } else {
        // 无本地读写访问权限
    }
}

如果READ_MEDIA_IMAGESREAD_MEDIA_VIDEO权限都有了,那就获取了所有的照片视频的访问权限,就和之前版本的交互一样。

如果只有READ_MEDIA_VISUAL_USER_SELECTED权限,说明用户之前指定看可见范围。那么可以添加一个入口让用户修改可见的照片和视频范围,具体可以参考下面的交互流程。
在这里插入图片描述
点击按钮可以重新请求权限,让用户修改可见范围。


其他还有安全的全屏 intent 通知,每个 MediaProjection 拍摄会话均需要征得用户同意等行为变更,因为我涉及不多,这里就不说了,有需要可以直接看文末的官方文档。

其他新功能及API

1.非线性字体放大至 200%

从 Android 14 开始,系统支持字体放大高达 200%,为弱视用户提供了符合网络内容无障碍指南 (WCAG) 的其他无障碍选项。

为防止屏幕上的大文本元素放大过大,系统会采用非线性放大曲线。这种放大策略意味着大号文本的放大比例不会与较小的文本相同。非线性字体缩放有助于保持不同大小元素之间的比例层次结构,同时缓解高级别线性文本缩放的问题(例如文本被截断或文本因超大显示大小而难以阅读)。

如果你的应用字体使用的dp为单位,那么不会受次影响,否则需要测试一下ui是否可以正常显示。但是需要注意一点,使用 TypedValue.applyDimension()sp 单位转换为像素,并使用 TypedValue.deriveDimension() 将像素转换为 sp。这些方法会自动应用适当的非线性缩放曲线。

避免使用 Configuration.fontScaleDisplayMetrics.scaledDensity 。由于字体缩放是非线性的,因此 scaledDensity 字段不再准确。fontScale 字段应仅用于提供信息,因为字体不再使用单个标量值进行缩放。

比如我们常使用scaledDensity用作像素转sp:

public static int px2sp(Context context, float pxValue) {
	final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
	return (int) (pxValue / fontScale + 0.5f);
}

修改为:

public static int px2sp(Context context, float pxValue) {
	if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
		return (int) TypedValue.deriveDimension(TypedValue.COMPLEX_UNIT_SP, pxValue, context.getResources().getDisplayMetrics());
	}
	final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
	return (int) (pxValue / fontScale + 0.5f);
}

比如我同一设备调到最大字号时,计算了100px等于多少sp,两种方法结果如下:

scaledDensity:17
deriveDimension:21

可以看到就有误差了,如果是标准字号,结果如下:

scaledDensity:35
deriveDimension:34

差1是因为我们加了0.5f,实际浮点值都是34.72222。

当然更推荐使用的core库(1.12.0版本以上)的TypedValueCompat类,里面有pxToSp等方法,里面已经帮我们做了以上适配。

2.语法性别API

有 30 亿人在使用区分性别的语言,此类语言的语法类别(例如名词、动词、形容词和介词)会根据您交谈所涉及的人或物的性别而变化。传统上,许多区分性别的语言使用阳性语法性别作为默认或通用性别。

以错误的语法性别来称呼用户,例如以阳性语法性别来称呼女性,可能会对她们的表现和态度产生负面影响。相比之下,界面语言如果能正确反映用户的语法性别,就可以提高用户互动度,并提供更个性化、更自然的用户体验。

为帮助您针对区分性别的语言构建以用户为中心的界面,Android 14 引入了语法变化 API,让您无需重构应用便能添加对语法性别的支持。

比如首选语法性别设为阴性,通过以下API指定:

GrammaticalInflectionManager gIM = mContext.getSystemService(GrammaticalInflectionManager.class);
gIM.setRequestedApplicationGrammaticalGender(Configuration.GRAMMATICAL_GENDER_FEMININE);

string.xml需要相应的配置,比如法语:

  • 阴性:res/values-fr-feminine/strings.xml
  • 阳性:res/values-fr-masculine/strings.xml
  • 中性:res/values-fr-neuter/strings.xml
  • 默认:res/values-fr/strings.xml

因为我做的是出海项目,所以我会特别注意这点。因为之前我们遇到过用户反馈的相关问题,所以针对不同性别显示不同的文案。

3.各应用语言偏好设定

去年在Android 13的新功能上就看到了这条,当时发现此功能被阉割了,所以没有过多的尝试。这次在我的手机上(Origin OS 4)发现了几款海外应用支持了此功能,没有被阉割了。

位置位于应用信息页,有个语言入口:

请添加图片描述

Android 14 扩展了 Android 13中引入的按应用设定语言功能,并包含以下额外功能:

  • 自动生成应用的 localeConfig:从 Android Studio Giraffe Canary 7 和 AGP 8.1.0-alpha07 开始,您可以将应用配置为自动支持各应用语言偏好设定。Android Gradle 插件会根据您的项目资源生成 LocaleConfig 文件,并在最终清单文件中添加对该文件的引用,这样您就不再需要手动创建或更新该文件。AGP 使用应用模块的 res 文件夹中的资源以及任何库模块依赖项来确定要在 LocaleConfig 文件中添加的语言区域。

  • 动态更新应用的 localeConfig:使用 LocaleManager方法中的 setOverrideLocaleConfig()getOverrideLocaleConfig() 可以在设备的系统设置中动态更新应用的受支持语言列表。有了这种灵活性,您可以按区域自定义支持的语言列表、运行 A/B 实验,或者如果您的应用通过服务器端推送进行本地化,则可以提供更新后的语言区域列表。

  • 输入法 (IME) 的应用语言可见性:IME 可以利用 getApplicationLocales() 方法查看当前应用的语言,并将 IME 语言与该语言进行匹配。

详细使用方法参考:按应用设定语言偏好。说句题外话,这些新功能我发现一般谷歌自家的Gmail都支持的比较快,比如各应用语言偏好设定,预测性返回手势,应用启动画面等都可以在Gmail上体验。

其他新功能我就不一一介绍了,有需要可以直接看文末的官方文档。


整体来说,Android 14是在13的基础上做了更多的补充完善,适配上来说难度不大。

参考

  • 官方文档
  • 小米 - Android14 应用适配指南
  • Android 14新特性,选择性照片和视频访问授权

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/594956.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

跟TED演讲学英文:Is your partner “the one?“ Wrong question by George Blair-West

Is your partner “the one?” Wrong question Link: https://www.ted.com/talks/george_blair_west_is_your_partner_the_one_wrong_question Speaker: George Blair-West Date: December 2022 文章目录 Is your partner "the one?" Wrong questionIntroduction…

【Unity 组件思想-预制体】

【Unity 组件思想-预制体】 预制体&#xff08;Prefab&#xff09;是Unity中一种特殊的组件 特点和用途&#xff1a; 重用性&#xff1a; 预制体允许开发者创建可重复使用的自定义游戏对象。这意味着你可以创建一个预制体&#xff0c;然后在场景中多次实例化它&#xff0c;…

快速上手RabbitMQ

安装RabbitMQ 首先将镜像包上传到虚拟机&#xff0c;使用命令加载镜像 docker load -i mq.tar 运行MQ容器 docker run \-e RABBITMQ_DEFAULT_USERitcast \-e RABBITMQ_DEFAULT_PASS123321 \-v mq-plugins:/plugins \--name mq \--hostname mq \-p 15672:15672 \-p 5672:5672 …

图像识别——玩转YOLO网络

图像识别——玩转YOLO网络 YOLO&#xff0c;全称“You Only Look Once”&#xff0c;意为你只需要看一次&#xff0c;是一种快速、准确的目标检测算法。它由Joseph Redmon等人在2016年提出&#xff0c;其核心思想是将输入图像划分为SS个网格单元&#xff0c;每个网格预测B个边…

什么是脏读?幻读?不可重复读?

脏读(Drity Read)&#xff1a;某个事务 A 已更新一份数据&#xff0c;另一个事务 B 在此时读取了同一份数据&#xff0c;由于某些原因&#xff0c;事务 A 回滚&#xff0c;而事务B读取到事务 A 回滚前的数据。 例子:小明读取到小红提交的100数据.但是小红异常回滚了数据,100变…

STM32单片机实战开发笔记-PWM波输出频率及占空比配置【wulianjishu666】

单片机物联网开发资料&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1XzodQuML7CqZ4ZKinDGKkg?pwdbgep 提取码&#xff1a;bgep PWM模块测试 功能描述 脉冲宽度调制模式&#xff1a; PWM边沿对齐模式&#xff1a; 向上计数配置 当TIMX_CR1寄存器中的DIR为低的时…

Video2Game:革新游戏开发,重塑虚拟世界的未来

Video2Game&#xff1a;革新游戏开发&#xff0c;重塑虚拟世界的未来 一、Video2Game的提出与意义二、Video2Game的核心技术三、Video2Game的实现与应用四、代码实例与未来展望 在数字化和虚拟化日益盛行的今天&#xff0c;高质量的交互式虚拟环境&#xff0c;如游戏和模拟器&a…

TinTin Web3 Bounty 挑战杯第二期再启程,NEAR 生态邀请你来找 Bug!

对 Web3 来说&#xff0c;Bounty 任务应该是普通人获得行业“一杯羹”的重要捷径&#xff01; 通过深入学习各类 Web3 公链技术&#xff0c;凭借实战锻炼开发创新项目&#xff0c;或完善已有网络运行中出现的问题&#xff0c;就有机会更加快速了解其底层技术逻辑&#xff0c;更…

基于YOLOv8+PyQt5复杂场景下船舶目标检测系统

1. 应用场景 复杂场景下船舶目标检测系统的应用场景包括&#xff1a; 港口管理和安全&#xff1a;监控港口区域&#xff0c;确保船舶安全地进出港口&#xff0c;预防相撞事故的发生。 海洋交通监控&#xff1a;实时追踪海上交通流&#xff0c;并识别违规或异常航行行为&#x…

Python ValueError: bad transparency mask

修改前 修复后 运行正常 from PIL import Image# 读取图片 #报错信息解决ValueError: bad transparency mask--相关文档地址https://blog.csdn.net/kalath_aiur/article/details/103945309 #1. 检查 alpha 通道是否是一个有效的掩码。如果不是&#xff0c;则需要对 alpha 通道…

《Boundary Smooth for NER》

来源&#xff1a; ACL2022, 作者&#xff1a;中科院 命名实体识别(NER)模型很容易遇到over-confidence的问题&#xff0c;从而降低了性能。 基于边界存在的问题&#xff0c;参考 Label Smoothing&#xff0c;作者提出了 boundary smoothing 的训练方法&#xff0c;即使用 biaff…

苍穹外卖,接入redis cache后,新增套餐有问题

终端报错&#xff1a; java.lang.IllegalArgumentException: Null key returned for cache operation (maybe you are using named params on classes without debug info?) Builder[public com.sky.result.Result com.sky.controller.admin.SetmealController.save(com.sky.d…

Stable Diffusion WebUI 中文提示词插件 sd-webui-prompt-all-in-one

本文收录于《AI绘画从入门到精通》专栏,订阅后可阅读专栏内所有文章,专栏总目录:点这里。 大家好,我是水滴~~ 今天为大家介绍 Stable Diffusion WebUI 的一款中文提示词插件 sd-webui-prompt-all-in-one,就像它的名字一样,该插件几乎涵盖了提示词相关的所有功能。 文章内…

3D模型格式转换工具HOOPS Exchange如何读取建筑工程中复杂庞多的数据?

在当今数字化时代&#xff0c;建筑行业正日益依赖于复杂的3D建模工具和软件&#xff0c;以便在设计、规划和建造过程中实现更高的效率和精确性。然而&#xff0c;这种效率的提升往往伴随着一个挑战&#xff1a;不同软件之间的3D模型格式可能不兼容&#xff0c;这导致了数据转换…

SpringBootWeb创建

创建spring项目 创建SpringBoot工程定义请求处理类运行常见问题java: 无效的源发行版: XXjava: 无法访问org.springframework.web.bind.annotation.RequestMapping类文件具有错误的版本 61.0, 应为 52.0 创建SpringBoot工程 定义请求处理类 RestController public class HelloC…

unity入门学习笔记

文章目录 unity学习笔记熟悉界面窗口页面快捷键视图特点移动、旋转、缩放快捷键聚焦和隐藏 一些基本概念模型模型的导入一些补充 资源文件资源包的导出资源包的导入 轴心物体的父子关系空物体Global与localpivot与center 组件脚本基础我的第一个脚本 获取脚本组件本地坐标播放模…

JVM调优--理论篇

在对Java应用进行性能优化时&#xff0c;JVM的调优是一个绕不开的话题。本文重点介绍下如何对JVM进行调优&#xff0c;以期提高Java应用的性能、稳定性、响应时间等性能目标。JVM的调优过程符合Java应用的调优过程&#xff0c;主要分为三步&#xff1a;性能监控、性能分析、性能…

8086 汇编学习 Part 8

移位指令 当 C N T > 1 CNT > 1 CNT>1 时&#xff0c;CNT 必须是 CL 寄存器 逻辑左移 SHL OPR , CNT 将寄存器或内存单元中的数据向左移 CNT 位&#xff0c;最后移除的一位写入 CF&#xff0c;最低位用 0 补充 循环左移 ROL OPR , CNT 将寄存器中的值的最高位存…

视频改字祝福 豪车装X系统源码uniapp前端小程序源码

视频改字祝福 豪车装X系统源码uniapp前端小程序源码&#xff0c;创意无限&#xff01;AI视频改字祝福&#xff0c;豪车装X系统源码开源&#xff0c;打造个性化祝 福视频不再难&#xff01; 想要为你的朋友或家人送上一份特别的祝福&#xff0c;让他们感受到你的真诚与关怀吗&am…

服务器数据恢复—ESXi虚拟机中MySQL数据库数据恢复案例

服务器数据恢复环境&#xff1a; 某品牌EVA某型号存储中部署VMware ESXi虚拟化平台&#xff0c;数据盘&#xff08;精简模式&#xff09;快照数据盘&#xff0c;虚拟机中有mysql数据库。 服务器故障&#xff1a; 机房意外断电导致该存储中的一台VMware虚拟机无法启动&#xff0…
最新文章