当前位置: 首页 > news >正文

Android 应用添加系统签名权限的几种方式实现介绍

Android 应用添加系统签名权限的几种方式实现介绍

文章目录

  • Android 应用添加系统签名权限的几种方式实现介绍
    • 一、前言
    • 二、Android 应用添加系统签名权限的几种方式介绍
      • 1、在Android Studio添加系统签名文件
      • 2、源码编译apk添加系统签名
          • Android.mk
          • Android.bp
      • 3、源码编译app代码添加系统签名
          • Android.mk
          • Android.bp
    • 三、缺少系统权限报错示例
      • 1、设置Settings属性报错
      • 2、设置Wifi开关状态失败
      • 3、Settings属性设置为啥需要系统权限?
      • 4、设置Wifi开关状态为啥失败?
    • 四、其他
      • 1、系统权限介绍
        • (1)普通权限(normal)
        • (2)运行时权限(dangerous)
        • (3)签名权限(signature)
        • (4)特殊权限(privileged)
      • 2、如何查看一个应用的权限情况?
      • 3、系统权限级别总结
        • Android中不同应用权限级别从低到高总结场景
      • 4、Android APEX:系统新篇章的应用扁平化技术

一、前言

Android 应用添加系统签名就能获取到系统权限调用一些系统接口,

添加系统签名的方式主要包括:

在Android Studio中配置签名文件生成apk 和 在源码目录编译添加系统签名生成apk。

本文介绍的都是一些基础的签名知识,后续延伸介绍相关权限内容。有兴趣的可以进行了解。

二、Android 应用添加系统签名权限的几种方式介绍

1、在Android Studio添加系统签名文件

源码中生成 jks 签名文件:

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

Studio 在对应需要签名的module(默认是app)的build.gradle中添加如下代码:

android {compileSdkVersion 30buildToolsVersion "30.0.0"compileOptions {sourceCompatibility JavaVersion.VERSION_1_8targetCompatibility JavaVersion.VERSION_1_8}
。。。//证书信息在这里配置signingConfigs {main {storeFile file("./platform.jks") //签名文件路径,根目录storePassword "skg202302"keyAlias "skg"keyPassword "skg202302"}}buildTypes {release {minifyEnabled falsesigningConfig signingConfigs.main //添加这一行proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'}debug {minifyEnabled falsesigningConfig signingConfigs.main //添加这一行proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'}}}

只是添加了系统签名是不行的,还需要在AndroidManifest.xml中声明系统权限

AndroidManifest.xml 配置uid系统权限:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"coreApp="true"package="com.xxx.xxx"android:sharedUserId="android.uid.system">

2、源码编译apk添加系统签名

如果apk没有签名文件和为添加签名信息,那么添加uid.system后,该应用是无法安装到对应系统上的;

如果要安装可以在源码里面编译,生成的apk就会加入签名的信息的。

Android.mk
# 编译的目录,默认写法
include $(CLEAR_VARS)# 设置模块名
LOCAL_MODULE := mymodule# 设置预构建文件的源路径和目标路径
LOCAL_SRC_FILES := path/file.apk# 设置系统权限和目录
LOCAL_CERTIFICATE := platform
LOCAL_PRIVATE_PLATFORM_APIS := true
# 设置是否编译在 priv-app,如果没有指定目录默认为 system/priv-app
LOCAL_PRIVILEGED_MODULE := true include $(BUILD_PREBUILT)
Android.bp
android_app_import {name: "FileManager",apk: "FileManager.apk",//生成到priv-app目录下privileged: true,//使用系统签名certificate: "platform",
}

3、源码编译app代码添加系统签名

Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)# 设置模块名为myapp
LOCAL_MODULE := myapp
# 添加需要编译的Java源文件
LOCAL_SRC_FILES := $(wildcard *.java)
# 添加需要编译的资源文件
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
# 设置输出APK的路径和名称
LOCAL_PACKAGE_NAME := myapp# 设置系统权限和目录
LOCAL_CERTIFICATE := platform
LOCAL_PRIVATE_PLATFORM_APIS := true
# 设置是否编译在 priv-app,如果没有指定目录默认为 system/app
LOCAL_PRIVILEGED_MODULE := true include $(BUILD_PACKAGE)
Android.bp
android_app {name: "myapp",srcs: ["path/to/your/app/src/**/*.java",],resource_dirs: ["path/to/your/app/res",],manifest: "path/to/your/app/AndroidManifest.xml",//加载类库static_libs: ["mylibrary",],//是否系统签名certificate: "platform",platform_apis: true,//是否生成到priv-app目录privileged: true,}

上面是代码的情况,编译apk获取系统签名的

Android13或者更新的源代码,大多都是使用Android.bp进行编译。

上面就是本文的主要内容,下面是一些相关内容知识。

三、缺少系统权限报错示例

这里以Settings设置属性为示例讲解。

Settings属性获取是不需要权限的,Settings属性设置是需要权限的,为啥会这样?

其实是因为代码里面定义的,具体是哪个类的哪行代码限制的?有兴趣的可以往下看看:

//Settings 获取属性值,不用权限和签名
int value = Settings.Global.getInt(getContentResolver(), Settings.Global.WIFI_ON, -1);//Settings 设置属性值,需要系统签名或者系统权限,否则会异常
boolean value = Settings.Global.putInt(getContentResolver(), Settings.Global.WIFI_ON, 1);//Wifi开关控制,需要系统签名或者系统权限,否则返回false,但是不会异常
WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
boolean value =  wifiManager.setWifiEnabled(true);

1、设置Settings属性报错

设置wifi开关状态报错:

 Caused by: java.lang.SecurityException: Permission denial: writing to settings requires:android.permission.WRITE_SECURE_SETTINGSat android.os.Parcel.createExceptionOrNull(Parcel.java:3011)at android.os.Parcel.createException(Parcel.java:2995)at android.os.Parcel.readException(Parcel.java:2978)at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:190)at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:142)at android.content.ContentProviderProxy.call(ContentProviderNative.java:732)at android.provider.Settings$NameValueCache.putStringForUser(Settings.java:3021)at android.provider.Settings$Global.putStringForUser(Settings.java:16753)at android.provider.Settings$Global.putString(Settings.java:16594)at android.provider.Settings$Global.putInt(Settings.java:16824)at com.demo.systemapp.MainActivity.setSettingsValue(MainActivity.java:29)at java.lang.reflect.Method.invoke(Native Method) 

从报错日志看是缺少了权限:WRITE_SECURE_SETTINGS。这个权限是需要签名或者系统应用才能拥有的权限。

如果要规避应用崩溃,可以通过try {}catch捕获异常,避免崩溃。

2、设置Wifi开关状态失败

调用wifi开关接口日志:

2024-01-20 17:09:04.193 638-1052/system_process I/WifiService: setWifiEnabled packageName = com.demo.systemapp, enable = true
2024-01-20 17:09:04.195 638-1052/system_process I/WifiService: setWifiEnabled not allowed for uid=10084

上面的日志都是 WifiServiceImpl.java 里面的日志。

显示了是哪个应用,调用了wifi开关的什么状态,后续显示not allowed ,因为uid = 100084,相当于啥都没做。

这种情况没有报错,也不会崩溃,但是就是调用了没效果。

所以大概可以猜测出需要设置Settings属性或者调用Wifi开关状态的接口都是要系统权限或者系统签名。

3、Settings属性设置为啥需要系统权限?

看看代码就知道了:

frameworks\base\core\java\android\provider\Settings.java

//Settings.XXX.Put属性需要权限的原因,代码这里定义了的。
@SystemApi
@RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
public static boolean putString(ContentResolver resolver,String name,String value,。。。){return putStringForUser(resolver, name, value, tag, makeDefault,resolver.getUserId(), DEFAULT_OVERRIDEABLE_BY_RESTORE);
}

代码这里已经声明了,必须要系统应用和 WRITE_SECURE_SETTINGS权限,

才能调用后续的put方法,所以未获取到权限就会抛出异常。

4、设置Wifi开关状态为啥失败?

根据下面代码的具体判断就可以看得出:

packages\modules\Wifi\service\java\com\android\server\wifi\WifiServiceImpl.java

//WifiManager.setWifiEnabled 失败原因,这里判断后返回了false
public synchronized boolean setWifiEnabled(String packageName, boolean enable) {//这里判断的是三方应用,主要是uid,三方应用不具有系统签名,所以返回false,不往下走if (isThirdParty && !isTargetSdkLessThanQ) {mLog.info("setWifiEnabled not allowed for uid=%").c(callingUid).flush();return false;}//这里判断是否是飞行模式并且是否不是系统应用(priv-app目录下的应用)//如果是飞行模式,并且不是priv-app目录的系统应用,返回false// If Airplane mode is enabled, only privileged apps are allowed to toggle Wifiif (mSettingsStore.isAirplaneModeOn() && !isPrivileged) {mLog.err("setWifiEnabled in Airplane mode: only Settings can toggle wifi").flush();return false;}//如果不是priv-app目录应用,并且热点开启的情况,返回false// If SoftAp is enabled, only privileged apps are allowed to toggle wifiif (!isPrivileged && mTetheredSoftApTracker.getState() == WIFI_AP_STATE_ENABLED) {mLog.err("setWifiEnabled with SoftAp enabled: only Settings can toggle wifi").flush();return false;}...
}

上面是Android13 中wifi开关状态返回false的几种情况分析。

四、其他

1、系统权限介绍

framework 定义的所有 权限都是有定义包含 protectionLevel 等级的,主要权限等级有:普通,运行时,系统签名,特殊 。

(1)普通权限(normal)

此类权限允许访问超出应用沙盒的数据和执行超出应用沙盒的操作。但这些数据和操作对用户隐私及对其他应用的操作带来的风险非常小。

比如,上网权限,wifi 状态监听,蓝牙,获取后台任务等待,大概有一百多个。

(2)运行时权限(dangerous)

运行时权限也称为危险权限,此类权限授予应用对受限数据的额外访问权限,并允许应用执行对系统和其他应用具有更严重影响的受限操作。因此需要先在应用中请求运行时权限,然后才能访问受限数据或执行受限操作。当应用请求运行时权限时,系统会显示运行时权限弹窗提示。

比如,文件读写权限,日历读取和设置权限等待,总共不到一百个。

(3)签名权限(signature)

当应用声明了其他应用已定义的签名权限时,如果两个应用使用同一证书进行签名,系统会在安装时向前者授予该权限。否则,系统无法向前者授予该权限。(注意:有些签名权限不适合第三方应用使用。)

该权限只需要在manifest中声明使用,同时应用和这类权限定义者拥有一样的签名系统就会默认授予应用这类权限;系统授予这类权限后应用无需像运行时权限一样动态申请。

比如,Android11 新增的文件管理权限,对wifi,热点,Camera一些特殊操作权限,比较多,大概有五百多个。

(4)特殊权限(privileged)

特殊权限与特定的应用操作相对应。只有平台和原始设备制造商 (OEM) 可以定义特殊权限。此外,如果平台和 OEM 想要防止有人执行功能特别强大的操作(例如通过其他应用绘图),通常会定义特殊权限。系统设置中的特殊应用访问权限页面包含一组用户可切换的操作。其中的许多操作都以特殊权限的形式实现。每项特殊权限都有自己的实现细节。系统会为特殊权限分配“appop”保护级别。

比如本文的: 允许应用程序在所有用户之间进行交互 权限,启动前台服务权限,可通过overlay形式覆盖属性权限,应用主题更改监听等等,大概有三百多个。

一般情况下:特殊权限大部分与系统签名文件同时使用。

我们常用的广播都定义在framework\base\core\res\AndroidManifest.xml里面,如果要新增可以在里面新增

值得注意的是,系统签名文件是比系统应用权限大的,比如:

    //MANAGE_CAMERA 权限,必须要系统签名才能获取到<permission android:name="android.permission.MANAGE_CAMERA"android:protectionLevel="signature" />//CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS 权限,系统签名或者priv-app应用都可以获取到<permission android:name="android.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS"android:protectionLevel="signature|privileged" />

上面的是 Android13 上比较新的权限定义,有兴趣的可以看看。

在线查看权限定义网址:

http://aospxref.com/android-13.0.0_r3/xref/frameworks/base/core/res/AndroidManifest.xml

2、如何查看一个应用的权限情况?

dumpsys package XXX包名,可以查看apk信息:

E:\Studio\project\test\SystemApp>adb shell
rk3588_t:/ $ ^C
130|rk3588_t:/ $ dumpsys package com.demo.systemappPackages:Package [com.demo.systemapp] (6e1e98c): //1、应用包名userId=10083 //uid,system.uid = 10000pkg=Package{1a148d5 com.demo.systemapp}codePath=/system/app/SystemAppDemo //2、apk路径resourcePath=/system/app/SystemAppDemotimeStamp=2024-01-20 11:45:31lastUpdateTime=2024-01-20 11:45:31requested permissions:  //3、AndroidManifest中声明的权限android.permission.WRITE_SECURE_SETTINGSandroid.permission.POST_NOTIFICATIONSUser 0: ceDataInode=9991 installed=true hidden=false suspended=false distractionFlags=0 stopped=false notLaunched=false enabled=0 instant=false virtual=falseinstallReason=0firstInstallTime=2024-01-20 11:45:31uninstallReason=0runtime permissions:  //4、获取到的权限,granted=true 才算获取到!android.permission.POST_NOTIFICATIONS: granted=false, flags=[ USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED]rk3588_t:/ $
E:\Studio\project\test\SystemApp>

从dumpsys package XXX 命令的日志,可以看到包名应用对应的Uid信息,版本信息,apk安装位置,安装时间,AndroidManifest声明的权限,实际获取到的权限等等信息。

requested permissions 下面的权限是应用声明的权限,runtime permissions的权限是当前获取到的权限。

值得注意的是即使是系统应用或者系统签名应用也是要在 AndroidManifest 中声明需要的权限。

3、系统权限级别总结

Android中不同应用权限级别从低到高总结场景
(1)普通应用。只用到了普通权限,比如上网权限等等。
(2)system/app 系统应用,用来可以限制无法手动卸载,对系统权限没有要求的情况,无法调用系统api
(3)system/priv-app 系统应用(未设置uid.system),无法手动卸载,可以调用部分系统api
(4)系统签名应用普通安装的方式,可以调用系统相关api,同时也可以被手动卸载,可以添加privileged特殊权限
(5)system/priv-app 系统应用(设置uid.system),无法手动卸载,可以调用全部系统api,可以添加privileged特殊权限

了解到不同的权限需求,应用要安装/编译在什么目录心里就有个底了。

4、Android APEX:系统新篇章的应用扁平化技术

Android13 和更新的版本编译,你会发现package/modules下面的代码模块都是编译到了目录: /system/apex/XXXPackage/XXX.apk

这里面的apk有些是系统签名应用,有些是普通应用,这个和具体的bp里面的编译规则相关。

APEX 的相关介绍:

https://blog.csdn.net/u011897062/article/details/133122565

https://blog.csdn.net/u010164190/article/details/122324409

这块知识看起来还是比较复杂。

对于普通应用开发者,和一般的系统应用开发者其实没啥研究价值。

可以简单的理解一下模块化的概念:比如把一个apk的某些模块编译成一个apk,这些模块可以接收广播处理事务或者启动服务处理事务等功能。

这个和应用开发中的模块化是同样的原理,只是源码中Android13 以前很少这样开发,后续更新的源码应该是会更多这样的模块。

相关文章:

Android 应用添加系统签名权限的几种方式实现介绍

Android 应用添加系统签名权限的几种方式实现介绍 文章目录 Android 应用添加系统签名权限的几种方式实现介绍一、前言二、Android 应用添加系统签名权限的几种方式介绍1、在Android Studio添加系统签名文件2、源码编译apk添加系统签名Android.mkAndroid.bp 3、源码编译app代码…...

麒麟V10+飞腾处理器源码编译qt

1.下载qt源码 2.百度解压命令,进行解压 3.cd进文件目录 4.使用./configure命令进行配置(重点:记得看说明) Usage: configure [-h] [-prefix <dir>] [-prefix-install] [-bindir <dir>] [-libdir <dir>][-docdir <dir>] [-headerdir <dir&g…...

MacOS 查AirPods 电量技巧:可实现低电量提醒、自动弹窗

要怎么透过macOS 来查询AirPods 电量呢&#xff1f;当AirPods 和Mac 配对后&#xff0c;有的朋友想通过Mac来查询AirPods有多少电量&#xff0c;这个里有几个技巧&#xff0c;下面我们来介绍一下。 透过Mac 查AirPods 电量技巧 技巧1. 利用状态列上音量功能查询 如要使用此功能…...

python介绍,安装Cpython解释器,IDE工具pycharm的使用

python介绍 官方的Python解释器本质是基于C语言开发的一个软件&#xff0c;该软件的功能就是读取以py.结尾的文件内容&#xff0c;然后按照Guido定义好的语法和规则去翻译并执行相应的代码。这种C实现的解释器被称为Cpython。 python解释器的种类&#xff1a;Jython IPyth…...

服务器安装Docker (centOS)

1. 卸载旧版本的Docker&#xff08;如果有&#xff09; 首先&#xff0c;如果您的系统上安装了旧版本的Docker&#xff0c;需要将其卸载。Docker的旧版本称为docker或docker-engine。使用以下命令来卸载旧版本&#xff1a; sudo yum remove docker \ docker-client \ docker-…...

解析spritf和sscanf与模拟常用字符串函数strchr,strtok(二)

今天又来继续我们的字符串函数的文章&#xff0c;这也是最后一篇了。希望这两篇文章能让各位理解透字符串函数。 目录 strchr strtok sprintf和sscanf strchr strchr 是一个用于在字符串中查找特定字符首次出现位置的函数。以下是解析和模拟实现 strchr 函数的示例&…...

备战蓝桥杯---搜索(进阶4)

话不多说&#xff0c;直接看题&#xff1a; 下面是分析&#xff1a; (ab)%c(a%cb%c)%c; (a*b)%c(a%c*b%c)%c; 因此&#xff0c;如果两个长度不一样的值%m为相同值&#xff0c;那就舍弃长的&#xff08;因为再加1位只不过是原来值*10那位值&#xff0c;因此他们得出的%m还是同…...

51单片机基础(C语言):定时器时钟

1.使用定时器 1 和LCD1602设计一个简易数字时钟。 main.c #include <REGX52.H> #include "Delay.h" #include "LCD1602.h" #include "Timer0.h"unsigned char Sec55,Min59,Hour23;void main() {LCD_Init();Timer0Init();LCD_ShowString(…...

单片机无线发射的原理剖析

目录 一、EV1527编码格式 二、OOK&ASK的简单了解 三、433MHZ 四、单片机的地址ID 五、基于STC15W104单片机实现无线通信 无线发射主要运用到了三个知识点&#xff1a;EV1527格式&#xff1b;OOk&#xff1b;433MHZ。下面我们来分别阐述&#xff1a; EV1527是数据的编…...

Redis的过期键的删除策略

我们都知道&#xff0c;Redis是key-value数据库&#xff0c;我们可以设置Redis中缓存的key的过期时间。Redis的过期策略就是指当Redis中缓存的key过期了&#xff0c;Redis如何处理。 过期策略通常有以下三种&#xff1a; 定时过期&#xff1a;每个设置过期时间的key都需要创建…...

放假--寒假自学版 day1(补2.5)

fread 函数&#xff1a; 今日练习 C语言面试题5道~ 1. static 有什么用途&#xff1f;&#xff08;请至少说明两种&#xff09; 1) 限制变量的作用域 2) 设置变量的存储域 2. 引用与指针有什么区别&#xff1f; 1) 引用必须被初始化&#xff0c;指针不必。 2) 引用初始…...

LLM(5) | Encoder 和 Decoder 架构

LLM(5) | Encoder 和 Decoder 架构 文章目录 LLM(5) | Encoder 和 Decoder 架构0. 目的1. 概要2. encoder 和 decoder 风格的 transformer (Encoder- And Decoder-Style Transformers)原始的 transformer (The original transformer)编码器 (Encoders)解码器 (Decoders)编码器和…...

CV | Medical-SAM-Adapter论文详解及项目实现

******************************* &#x1f469;‍⚕️ 医学影像相关直达&#x1f468;‍⚕️******************************* CV | SAM在医学影像上的模型调研【20240207更新版】-CSDN博客 CV | Segment Anything论文详解及代码实现 本文主要讲解Medical-SAM-Adapter论文及项…...

C++初阶:容器(Containers)vector常用接口详解

介绍完了string类的相关内容后&#xff1a;C初阶&#xff1a;适合新手的手撕string类&#xff08;模拟实现string类&#xff09; 接下来进入新的篇章&#xff0c;容器vector介绍&#xff1a; 文章目录 1.vector的初步介绍2.vector的定义&#xff08;constructor&#xff09;3.v…...

flink写入es的参数解析

ElasticsearchSink内部使用BulkProcessor一次将一批动作(ActionRequest)发送到ES集群。在发送批量动作前&#xff0c;BulkProcessor先缓存&#xff0c;再刷新。缓存刷新的间隔&#xff0c;支持基于Action数量、基于Action大小、基于时间间隔3种策略。BulkProcessor支持在同一次…...

逆向工程:揭开科技神秘面纱的艺术

在当今这个科技飞速发展的时代&#xff0c;我们每天都在与各种电子产品、软件应用打交道。然而&#xff0c;你是否想过&#xff0c;这些看似复杂的高科技产品是如何被创造出来的&#xff1f;今天&#xff0c;我们就来探讨一下逆向工程这一神秘而又令人着迷的领域。 一、什么是…...

决策树的相关知识点

&#x1f4d5;参考&#xff1a;ysu老师课件西瓜书 1.决策树的基本概念 【决策树】&#xff1a;决策树是一种描述对样本数据进行分类的树形结构模型&#xff0c;由节点和有向边组成。其中每个内部节点表示一个属性上的判断&#xff0c;每个分支代表一个判断结果的输出&#xff…...

【数据结构】单向链表实现 超详细

目录 一. 单链表的实现 1.准备工作及其注意事项 1.1 先创建三个文件 1.2 注意事项&#xff1a;帮助高效记忆和理解 2.链表的基本功能接口 2.0 创建一个 链表 2.1 链表的打印 3.链表的创建新节点接口 4.链表的节点插入功能接口 4.1 尾插接口 4.2 头插接口 4.3 指定位…...

Opencc4j 开源中文繁简体使用介绍

Opencc4j Opencc4j 支持中文繁简体转换&#xff0c;考虑到词组级别。 Features 特点 严格区分「一简对多繁」和「一简对多异」。 完全兼容异体字&#xff0c;可以实现动态替换。 严格审校一简对多繁词条&#xff0c;原则为「能分则不合」。 词库和函数库完全分离&#xff0c…...

vue 下载二进制文件

文章目录 概要技术细节 概要 vue 下载后端返回的二进制文件流 技术细节 import axios from "axios"; const baseUrl process.env.VUE_APP_BASE_API; //downLoadPdf("/pdf/download?pdfName" res .pdf, res); export function downLoadPdf(str, fil…...

数据结构之堆排序

对于几个元素的关键字序列{K1&#xff0c;K2&#xff0c;…&#xff0c;Kn}&#xff0c;当且仅当满足下列关系时称其为堆&#xff0c;其中 2i 和2i1应不大于n。 { K i ≤ K 2 i 1 K i ≤ K 2 i 或 { K i ≥ K 2 i 1 K i ≥ K 2 i {\huge \{}^{K_i≤K_{2i}} _{K_i≤K_{2i1}} …...

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之ScrollBar组件

鸿蒙&#xff08;HarmonyOS&#xff09;项目方舟框架&#xff08;ArkUI&#xff09;之ScrollBar组件 一、操作环境 操作系统: Windows 10 专业版、IDE:DevEco Studio 3.1、SDK:HarmonyOS 3.1 二、ScrollBar组件 鸿蒙&#xff08;HarmonyOS&#xff09;滚动条组件ScrollBar&…...

读论文:DiffBIR: Towards Blind Image Restoration with Generative Diffusion Prior

DiffBIR 发表于2023年的ICCV&#xff0c;是一种基于生成扩散先验的盲图像恢复模型。它通过两个阶段的处理来去除图像的退化&#xff0c;并细化图像的细节。DiffBIR 的优势在于提供高质量的图像恢复结果&#xff0c;并且具有灵活的参数设置&#xff0c;可以在保真度和质量之间进…...

基于微信小程序的新生报到系统的研究与实现,附源码

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…...

分享一下 uniapp 打包安卓apk

首先需要安装 Java 环境&#xff0c;这里就不做解释了 第二步&#xff1a;打开 mac 终端 / cmd 命令行工具 使用keytool -genkey命令生成证书 keytool -genkey -alias testalias -keyalg RSA -keysize 2048 -validity 36500 -keystore test.keystore *testalias 是证书别名&am…...

DevOps落地笔记-21|业务价值:软件发布的最终目的

上一课时介绍如何度量软件的内部质量和外部质量。在外部质量中&#xff0c;我们提到用户满意度是衡量软件外部质量的关键因素。“敏捷宣言”的第一条原则规定&#xff1a;“我们最重要的目标&#xff0c;是通过持续不断的及早交付有价值的软件使用户满意”。从这一点也可以看出…...

【动态规划】【前缀和】【数学】2338. 统计理想数组的数目

作者推荐 【动态规划】【前缀和】【C算法】LCP 57. 打地鼠 本文涉及知识点 动态规划汇总 C算法&#xff1a;前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频 LeetCode:2338. 统计理想数组的数目 给你两个整数 n 和 maxValue &#xff0c;用于描述一个 理想…...

【已解决】onnx转换为rknn置信度大于1,图像出现乱框问题解决

前言 环境介绍&#xff1a; 1.编译环境 Ubuntu 18.04.5 LTS 2.RKNN版本 py3.8-rknn2-1.4.0 3.单板 迅为itop-3568开发板 一、现象 采用yolov5训练并将pt转换为onnx&#xff0c;再将onnx采用py3.8-rknn2-1.4.0推理转换为rknn出现置信度大于1&#xff0c;并且图像乱框问题…...

多路服务器技术如何处理大量并发请求?

在当今的互联网时代&#xff0c;随着用户数量的爆炸性增长和业务规模的扩大&#xff0c;多路服务器技术已成为处理大量并发请求的关键手段。多路服务器技术是一种并行处理技术&#xff0c;它可以通过多个服务器同时处理来自不同用户的请求&#xff0c;从而显著提高系统的整体性…...

SpringBoot - 不加 @EnableCaching 标签也一样可以在 Redis 中存储缓存?

网上文章都是说需要在 Application 上加 EnableCaching 注解才能让缓存使用 Redis&#xff0c;但是测试发现不用 EnableCaching 也可以使用 Redis&#xff0c;是网上文章有问题吗&#xff1f; 现在 Application 上用了 EnableAsync&#xff0c;SpringBootApplication&#xff0…...

机构单位网站建设方案/地推团队

PB作为windows下的一个非常便捷的DB开发工具&#xff0c;有着和windows一样的消息触发机制 PB提供了相应event/function触发机制和触发方式&#xff0c;用户可以根据自己的实际需要选用不同方法。 触发机制 trigger/post 使用trigger会即时触发event/function&#xff1b; 使…...

php网站换服务器/百度竞价课程

概述 Redis高可用高性能缓存的应用系列的第二篇&#xff0c;主要介绍Redis事务机制和IO多路复用、和持久化的知识点。 Redis事务机制 Redis事务机制&#xff0c;和Mysql有大的不同&#xff0c;分为4步进行执行&#xff1a; 1.事务提交前&#xff0c;先检查命令语法是否正确…...

青岛免费建站/百度搜索引擎服务项目

在为虚机分配静态IP地址池的IP时&#xff0c;如果报错“没有从与 VMSubnet 相关的 IP 池中为虚拟网络适配器 9i [MAC: 001DD8B71C17] 分配 CA (客户地址)” 使用“动态获取”即可从相关的静态IP地址池获取一个IP&#xff0c;然后再进入系统后手工设置为静态IP。 只有在通过模板…...

wordpress建站如何制作微信/网站制作策划书

设置自定义类型文件的默认打开方式即是设置将一个exe程序与其建立关联&#xff0c;这可通过修改注册表完成&#xff0c;本文介绍用Qt的QSettings类来修改注册表。 注&#xff1a;本文末尾附有批处理来修改注册表的设置方法&#xff0c;此方法更为便捷。 示例 QString classN…...

群晖 建wordpress 500/手机推广平台有哪些

stripe-条带&#xff0c;最少需要一块硬盘&#xff0c;类似raid0 mirror-镜像&#xff0c;最少需要两块硬盘&#xff0c;类似raid1 raidz1-带有一个校验块&#xff0c;最少需要三块硬盘&#xff0c;类似raid5 raidz2-带有两个校验块&#xff0c;最少需要四块硬盘&#xff0c…...

鄂尔多斯网站制作 建设/宁波seo推广优化

一﹑ IBM服务器信息面板系统错误 LED信息面板系统错误?LED当检测到错误时&#xff0c;系统错误?LED?将变亮。如果系统错误?LED?变亮&#xff0c;请打开机箱门以检查诊断面板?LED?。下面完整地列出了所有的诊断面板?LED&#xff0c;其后列出的是用来解决问题的FRU/操作。…...