百度商桥代码怎么加到网站上,城阳网站开发公司电话,网站的营销方法有哪些,北京兼职做网站建设一、问题原因 1.安卓安全性变更
Android 12 的安全性变更#xff0c;Google 引入了更严格的 PendingIntent 安全管理#xff0c;强制要求开发者明确指定 PendingIntent 的可变性#xff08;Mutable#xff09;或不可变性#xff08;Immutable#xff09;。 但是#xf…一、问题原因 1.安卓安全性变更
Android 12 的安全性变更Google 引入了更严格的 PendingIntent 安全管理强制要求开发者明确指定 PendingIntent 的可变性Mutable或不可变性Immutable。 但是在从 Android 14 (API 34) 开始FLAG_MUTABLE 和隐式 Intent 的组合会被禁止。因此在使用静态的广播请求的时候FLAG_MUTABLE多余且违反安全规则。
2.关键点
关键在于安卓 14 版本的安全策略变化导致无法再继续使用 FLAG_MUTABLE。
二、解决办法
1.代码示例
先给出代码示例供大家参考然后解释关键点在哪。
MainActivity.ktKotlin class代码示例
package com.example.serialportdebugappimport android.app.PendingIntent
import android.content.Intent
import android.hardware.usb.UsbDevice
import android.hardware.usb.UsbManager
import android.os.Bundle
import android.widget.Button
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivityclass MainActivity : AppCompatActivity() {private lateinit var statusTextView: TextViewprivate lateinit var logTextView: TextViewprivate lateinit var checkPortButton: Buttonprivate lateinit var usbManager: UsbManageroverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)// 初始化视图statusTextView findViewById(R.id.statusTextView)logTextView findViewById(R.id.logTextView)checkPortButton findViewById(R.id.checkPortButton)// 获取 USB 管理器usbManager getSystemService(USB_SERVICE) as UsbManager// 按钮点击事件checkPortButton.setOnClickListener {detectUsbDevices()}}/*** 检测 USB 设备*/private fun detectUsbDevices() {val deviceList usbManager.deviceListif (deviceList.isEmpty()) {logTextView.append(No USB devices found\n)return}for ((_, device) in deviceList) {logTextView.append(Detected device: ${device.deviceName}\n)requestPermission(device)}}/*** 请求 USB 权限*/private fun requestPermission(device: UsbDevice) {val intent PendingIntent.getBroadcast(this, 0, Intent(com.android.example.USB_PERMISSION),PendingIntent.FLAG_IMMUTABLE)usbManager.requestPermission(device, intent)}
}UsbBroadcastReceiver.ktKotlin class代码示例
package com.example.serialportdebugappimport android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.hardware.usb.UsbDevice
import android.hardware.usb.UsbManager
import android.util.Logclass UsbBroadcastReceiver : BroadcastReceiver() {override fun onReceive(context: Context, intent: Intent) {val action intent.actionif (action com.android.example.USB_PERMISSION) {synchronized(this) {val device: UsbDevice? intent.getParcelableExtra(UsbManager.EXTRA_DEVICE)if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {device?.let {Log.d(UsbBroadcastReceiver, Permission granted for device: ${device.deviceName})}} else {Log.d(UsbBroadcastReceiver, Permission denied for device: ${device?.deviceName})}}}}
}AndroidManifest.xml 代码示例总配置文件
manifest xmlns:androidhttp://schemas.android.com/apk/res/androiduses-feature android:nameandroid.hardware.usb.host /uses-permission android:nameandroid.permission.INTERNET /uses-permission android:nameandroid.permission.MANAGE_EXTERNAL_STORAGE /uses-permission android:nameandroid.permission.WRITE_EXTERNAL_STORAGE /uses-permission android:nameandroid.permission.READ_EXTERNAL_STORAGE /applicationandroid:allowBackuptrueandroid:iconmipmap/ic_launcherandroid:labelstring/app_nameandroid:roundIconmipmap/ic_launcher_roundandroid:supportsRtltrueandroid:themestyle/Theme.SerialPortDebugAppactivityandroid:name.MainActivityandroid:exportedtrueintent-filteraction android:nameandroid.intent.action.MAIN /category android:nameandroid.intent.category.LAUNCHER //intent-filter/activity!-- 广播接收器处理 USB 权限 --receiver android:name.UsbBroadcastReceiver android:exportedfalseintent-filteraction android:namecom.android.example.USB_PERMISSION //intent-filter/receiver/application
/manifestbuild.gradle.kts(:app) 相关依赖代码示例
plugins {alias(libs.plugins.android.application)alias(libs.plugins.kotlin.android)alias(libs.plugins.kotlin.compose)
}android {namespace com.example.serialportdebugappcompileSdk 35defaultConfig {applicationId com.example.serialportdebugappminSdk 26targetSdk 35versionCode 1versionName 1.0testInstrumentationRunner androidx.test.runner.AndroidJUnitRunner}buildTypes {release {isMinifyEnabled falseproguardFiles(getDefaultProguardFile(proguard-android-optimize.txt),proguard-rules.pro)}}compileOptions {sourceCompatibility JavaVersion.VERSION_11targetCompatibility JavaVersion.VERSION_11}kotlinOptions {jvmTarget 11}buildFeatures {compose true}
}dependencies {implementation(libs.androidx.core.ktx)implementation(libs.androidx.lifecycle.runtime.ktx)implementation(libs.androidx.activity.compose)implementation(platform(libs.androidx.compose.bom))implementation(libs.androidx.ui)implementation(libs.androidx.ui.graphics)implementation(libs.androidx.ui.tooling.preview)implementation(libs.androidx.material3)implementation(libs.androidx.appcompat)testImplementation(libs.junit)androidTestImplementation(libs.androidx.junit)androidTestImplementation(libs.androidx.espresso.core)androidTestImplementation(platform(libs.androidx.compose.bom))androidTestImplementation(libs.androidx.ui.test.junit4)debugImplementation(libs.androidx.ui.tooling)debugImplementation(libs.androidx.ui.test.manifest)implementation(libs.purejavacomm)
}libs.versions.toml 代码示例
[versions]
agp 8.7.2
kotlin 2.0.0
coreKtx 1.15.0
junit 4.13.2
junitVersion 1.2.1
espressoCore 3.6.1
lifecycleRuntimeKtx 2.8.7
activityCompose 1.8.0
composeBom 2024.04.01
appcompat 1.7.0[libraries]
androidx-core-ktx { group androidx.core, name core-ktx, version.ref coreKtx }
junit { group junit, name junit, version.ref junit }
androidx-junit { group androidx.test.ext, name junit, version.ref junitVersion }
androidx-espresso-core { group androidx.test.espresso, name espresso-core, version.ref espressoCore }
androidx-lifecycle-runtime-ktx { group androidx.lifecycle, name lifecycle-runtime-ktx, version.ref lifecycleRuntimeKtx }
androidx-activity-compose { group androidx.activity, name activity-compose, version.ref activityCompose }
androidx-compose-bom { group androidx.compose, name compose-bom, version.ref composeBom }
androidx-ui { group androidx.compose.ui, name ui }
androidx-ui-graphics { group androidx.compose.ui, name ui-graphics }
androidx-ui-tooling { group androidx.compose.ui, name ui-tooling }
androidx-ui-tooling-preview { group androidx.compose.ui, name ui-tooling-preview }
androidx-ui-test-manifest { group androidx.compose.ui, name ui-test-manifest }
androidx-ui-test-junit4 { group androidx.compose.ui, name ui-test-junit4 }
androidx-material3 { group androidx.compose.material3, name material3 }
purejavacomm { group com.github.purejavacomm, name purejavacomm, version 1.0.2.RELEASE }
androidx-appcompat { group androidx.appcompat, name appcompat, version.ref appcompat }[plugins]
android-application { id com.android.application, version.ref agp }
kotlin-android { id org.jetbrains.kotlin.android, version.ref kotlin }
kotlin-compose { id org.jetbrains.kotlin.plugin.compose, version.ref kotlin }activity_main.xml 代码示例 APP界面UI用于测试USB串口调试APP的界面UI设计
?xml version1.0 encodingutf-8?
LinearLayoutxmlns:androidhttp://schemas.android.com/apk/res/androidandroid:layout_widthmatch_parentandroid:layout_heightmatch_parentandroid:orientationverticalandroid:padding16dpTextViewandroid:idid/statusTextViewandroid:layout_widthmatch_parentandroid:layout_heightwrap_contentandroid:textUSB Status: Not connectedandroid:textSize18sp /TextViewandroid:idid/logTextViewandroid:layout_widthmatch_parentandroid:layout_heightwrap_contentandroid:textLog output:\nandroid:padding8dpandroid:scrollbarsvertical /Buttonandroid:idid/checkPortButtonandroid:layout_widthmatch_parentandroid:layout_heightwrap_contentandroid:textCheck USB Devices /
/LinearLayout2.关键点
关键点在于MainActivity.kt 中的 这段代码 /*** 请求 USB 权限*/private fun requestPermission(device: UsbDevice) {val intent PendingIntent.getBroadcast(this, 0, Intent(com.android.example.USB_PERMISSION),PendingIntent.FLAG_IMMUTABLE)usbManager.requestPermission(device, intent)}能够看到在使用 PendingIntent 的时候我们告知了“FLAG_IMMUTABLE”这是关键回到文章最开始的时候我们说到过的 这是 Android 14 的特性我们只能使用 FLAG_IMMUTABLE也就是不可变的 PendingIntent。
只要这个写对了权限被拒绝:[android.permission.READ_EXTERNAL_STORAGE] 的 BUG基本就会被解决。
3.关于 Intent 和 PendingIntent
Intent 是 Android 中的一种消息对象用于描述应用程序要执行的操作。 作用是用来启动 活动Activity、服务Service 或 广播Broadcast。 可以携带数据以便被启动的组件可以接收到并使用这些数据。
分为显示和隐式 常见的 Intent 的用途 PendingIntent 是一种特殊类型的 Intent可以在 未来 的某个时间由系统或其他应用触发。 它充当一个 “授权”允许其他应用或系统在您的应用上下文中执行操作。
通常用于将操作 “延迟执行”而不是立即执行。 适用于一些 异步场景例如通知Notification的点击事件。定时任务。广播接收器。
说白了它就好像嵌入式和VUE中的 “监听”是用来等待消息的而不是主动出击。 而且重要的是Intent 是瞬发的使用后就销毁。 但是 PendingIntent 是持续的会一直存在到 被触发、被取消 为止。
Intent 和 PendingIntent 的对比 PendingIntent 的 3 种类型