Android 14 解決打開app出現不兼容彈窗的問題

應用安裝到 Android 14 上,出現如下提示

This app isn’t compatible with the latest version of Android. Check for an update or contact the app’s developer.

在這里插入圖片描述
通過源碼找原因。

提示的字符

根據字符找到 ./frameworks/base/core/res/res/values/strings.xml

<!-- Message displayed in dialog when app is 32 bit on a 64 bit system. [CHAR LIMIT=NONE] -->
<string name="deprecated_abi_message">This app isn\'t compatible with the latest version of Android. Check for an update or contact the app\'s developer.</string>

對應的中文 ./frameworks/base/core/res/res/values-zh-rCN/strings.xml

<string name="deprecated_abi_message" msgid="6820548011196218091">"此應用與最新版 Android 不兼容。請檢查是否有更新,或與應用開發者聯系。"</string>

DeprecatedAbiDialog

彈窗UI在 ./frameworks/base/services/core/java/com/android/server/wm/DeprecatedAbiDialog.java

package com.android.server.wm;import android.app.AlertDialog;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageItemInfo;
import android.content.pm.PackageManager;
import android.view.Window;
import android.view.WindowManager;import com.android.internal.R;class DeprecatedAbiDialog extends AppWarnings.BaseDialog {DeprecatedAbiDialog(final AppWarnings manager, Context context,ApplicationInfo appInfo) {super(manager, appInfo.packageName);final PackageManager pm = context.getPackageManager();final CharSequence label = appInfo.loadSafeLabel(pm,PackageItemInfo.DEFAULT_MAX_LABEL_SIZE_PX,PackageItemInfo.SAFE_LABEL_FLAG_FIRST_LINE| PackageItemInfo.SAFE_LABEL_FLAG_TRIM);final CharSequence message = context.getString(R.string.deprecated_abi_message);final AlertDialog.Builder builder = new AlertDialog.Builder(context).setPositiveButton(R.string.ok, (dialog, which) ->manager.setPackageFlag(mPackageName, AppWarnings.FLAG_HIDE_DEPRECATED_ABI, true)).setMessage(message).setTitle(label);// Ensure the content view is prepared.mDialog = builder.create();mDialog.create();final Window window = mDialog.getWindow();window.setType(WindowManager.LayoutParams.TYPE_PHONE);// DO NOT MODIFY. Used by CTS to verify the dialog is displayed.window.getAttributes().setTitle("DeprecatedAbiDialog");}
}

AppWarnings

調用到 DeprecatedAbiDialog 的是 ./frameworks/base/services/core/java/com/android/server/wm/AppWarnings.java

showDeprecatedAbiDialogIfNeeded

很顯然,如果設備是64位的,但是app只有32位的so庫,就會出現這個彈窗。

還可以看到,可以通過調試的方法,關閉這個彈窗檢測。
setprop debug.wm.disable_deprecated_abi_dialog true

    /*** Shows the "deprecated abi" warning, if necessary. This can only happen is the device* supports both 64-bit and 32-bit ABIs, and the app only contains 32-bit libraries. The app* cannot be installed if the device only supports 64-bit ABI while the app contains only 32-bit* libraries.** @param r activity record for which the warning may be displayed*/public void showDeprecatedAbiDialogIfNeeded(ActivityRecord r) {final boolean isUsingAbiOverride = (r.info.applicationInfo.privateFlagsExt& ApplicationInfo.PRIVATE_FLAG_EXT_CPU_OVERRIDE) != 0;if (isUsingAbiOverride) {// The abiOverride flag was specified during installation, which means that if the app// is currently running in 32-bit mode, it is intended. Do not show the warning dialog.return;}// The warning dialog can also be disabled for debugging purposefinal boolean disableDeprecatedAbiDialog = SystemProperties.getBoolean("debug.wm.disable_deprecated_abi_dialog", false);if (disableDeprecatedAbiDialog) {return;}final String appPrimaryAbi = r.info.applicationInfo.primaryCpuAbi;final String appSecondaryAbi = r.info.applicationInfo.secondaryCpuAbi;final boolean appContainsOnly32bitLibraries =(appPrimaryAbi != null && appSecondaryAbi == null && !appPrimaryAbi.contains("64"));final boolean is64BitDevice =ArrayUtils.find(Build.SUPPORTED_ABIS, abi -> abi.contains("64")) != null;if (is64BitDevice && appContainsOnly32bitLibraries) {mUiHandler.showDeprecatedAbiDialog(r);}}

showDeprecatedAbiDialogUiThread

handle 的處理,調用到 showDeprecatedAbiDialogUiThread

	/*** Handles messages on the system process UI thread.*/private final class UiHandler extends Handler {private static final int MSG_SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG = 1;private static final int MSG_HIDE_UNSUPPORTED_DISPLAY_SIZE_DIALOG = 2;private static final int MSG_SHOW_UNSUPPORTED_COMPILE_SDK_DIALOG = 3;private static final int MSG_HIDE_DIALOGS_FOR_PACKAGE = 4;private static final int MSG_SHOW_DEPRECATED_TARGET_SDK_DIALOG = 5;private static final int MSG_SHOW_DEPRECATED_ABI_DIALOG = 6;public UiHandler(Looper looper) {super(looper, null, true);}@Overridepublic void handleMessage(Message msg) {switch (msg.what) {//...case MSG_SHOW_DEPRECATED_ABI_DIALOG: {final ActivityRecord ar = (ActivityRecord) msg.obj;showDeprecatedAbiDialogUiThread(ar);} break;}}//...}/*** Shows the "deprecated abi" warning for the given application.* <p>* <strong>Note:</strong> Must be called on the UI thread.** @param ar record for the activity that triggered the warning*/@UiThreadprivate void showDeprecatedAbiDialogUiThread(ActivityRecord ar) {if (mDeprecatedAbiDialog != null) {mDeprecatedAbiDialog.dismiss();mDeprecatedAbiDialog = null;}if (ar != null && !hasPackageFlag(ar.packageName, FLAG_HIDE_DEPRECATED_ABI)) {mDeprecatedAbiDialog = new DeprecatedAbiDialog(AppWarnings.this, mUiContext, ar.info.applicationInfo);mDeprecatedAbiDialog.show();}}

拓展

來都來的,順道看到了 DeprecatedTargetSdkVersionDialog 的邏輯處理,

    /*** Shows the "deprecated target sdk" warning, if necessary.** @param r activity record for which the warning may be displayed*/public void showDeprecatedTargetDialogIfNeeded(ActivityRecord r) {if (r.info.applicationInfo.targetSdkVersion < Build.VERSION.MIN_SUPPORTED_TARGET_SDK_INT) {mUiHandler.showDeprecatedTargetDialog(r);}}/*** Shows the "deprecated target sdk version" warning for the given application.* <p>* <strong>Note:</strong> Must be called on the UI thread.** @param ar record for the activity that triggered the warning*/@UiThreadprivate void showDeprecatedTargetSdkDialogUiThread(ActivityRecord ar) {if (mDeprecatedTargetSdkVersionDialog != null) {mDeprecatedTargetSdkVersionDialog.dismiss();mDeprecatedTargetSdkVersionDialog = null;}if (ar != null && !hasPackageFlag(ar.packageName, FLAG_HIDE_DEPRECATED_SDK)) {mDeprecatedTargetSdkVersionDialog = new DeprecatedTargetSdkVersionDialog(AppWarnings.this, mUiContext, ar.info.applicationInfo);mDeprecatedTargetSdkVersionDialog.show();}}

如果 app 的 targetSdkVersion 版本低于平臺支持的最小sdk版本(ro.build.version.min_supported_target_sdk),就會提示:

此應用專為舊版 Android 系統打造。它可能無法正常運行,也不包含最新的安全和隱私保護功能。請檢查是否有更新,或與應用開發者聯系。

對應的字符是 ./frameworks/base/core/res/res/values/strings.xml 里的 deprecated_target_sdk_message

android$ cat ./frameworks/base/core/res/res/values-zh-rCN/strings.xml | grep deprecated_target_sdk_message<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"此應用專為舊版 Android 系統打造。它可能無法正常運行,也不包含最新的安全和隱私保護功能。請檢查是否有更新,或與應用開發者聯系。"</string>
android$
android$ cat ./frameworks/base/core/res/res/values/strings.xml | grep deprecated_target_sdk_message<string name="deprecated_target_sdk_message">This app was built for an older version of Android. It might not work properly and doesn\'t include the latest security and privacy protections. Check for an update, or contact the app\'s developer.</string>

最終顯示dialog

    /*** Shows the "deprecated abi" warning for the given application.* <p>* <strong>Note:</strong> Must be called on the UI thread.** @param ar record for the activity that triggered the warning*/@UiThreadprivate void showDeprecatedAbiDialogUiThread(ActivityRecord ar) {if (mDeprecatedAbiDialog != null) {mDeprecatedAbiDialog.dismiss();mDeprecatedAbiDialog = null;}if (ar != null && !hasPackageFlag(ar.packageName, FLAG_HIDE_DEPRECATED_ABI)) {mDeprecatedAbiDialog = new DeprecatedAbiDialog(AppWarnings.this, mUiContext, ar.info.applicationInfo);mDeprecatedAbiDialog.show();}}

解決辦法

使 app 支持64位的庫。

修改 app 的 build.gradle , 添加 “arm64-v8a” ,

      externalNativeBuild {cmake {//abiFilters "armeabi-v7a"abiFilters "armeabi-v7a","arm64-v8a"cppFlags "-std=c++11 -frtti -fexceptions"arguments "-DANDROID_STL=c++_static"}}ndk {//abiFilters "armeabi-v7a"abiFilters "armeabi-v7a","arm64-v8a"stl "stlport_shared"}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/81740.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/81740.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/81740.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Linux句柄數過多問題排查

以下是Linux句柄數過多問題的排查與解決方法整理&#xff1a; 一、檢測句柄使用情況 1?.查看系統限制? 單個進程限制&#xff1a;ulimit -n 系統級總限制&#xff1a;cat /proc/sys/fs/file-max 2?.統計進程占用量? 查看指定進程&#xff1a;lsof -p <PID> | wc -…

matlab插值方法(簡短)

在MATLAB中&#xff0c;可以使用interp1函數快速實現插值。以下代碼展示了如何使用spline插值方法對給定數據進行插值&#xff1a; x1 [23,56]; y1 [23,56]; X 23:1:56*4; Y interp1(x1,y1,X,spline);% linear、 spline其中&#xff0c;x1和y1是已知數據點&#xff0c;X是…

時間篩掉了不夠堅定的東西

2025年5月17日&#xff0c;16~25℃&#xff0c;還好 待辦&#xff1a; 《高等數學1》重修考試 《高等數學2》備課 《物理[2]》備課 《高等數學2》取消考試資格學生名單 《物理[2]》取消考試資格名單 職稱申報材料 2024年稅務申報 5月24日、25日監考報名 遇見&#xff1a;敲了一…

hexo博客搭建使用

搭建 Hexo 演示主題為&#xff1a;Keep 使用 文章 創建新文章 ? zymore-blog-keep git:(main) ? hexo new "告別H5嵌入&#xff01;uniApp小程序文件下載與分享完整解決方案" INFO Validating config INFO Created: ~/Desktop/HelloWorld/zymore-blog-k…

React組件開發流程-03.1

此章先以一個完整的例子來全面了解下React組件開發的流程&#xff0c;主要是以代碼為主&#xff0c;在不同的章節中會把重點標出來&#xff0c;要完成的例子如下&#xff0c;也可從官網中找到。 React組件開發流程 這只是一個通用流程&#xff0c;在熟悉后不需要完全遵從。 …

Cloudflare防火墻攔截谷歌爬蟲|導致收錄失敗怎么解決?

許多站長發現網站突然從谷歌搜索結果中“消失”&#xff0c;背后很可能是Cloudflare防火墻誤攔截了谷歌爬蟲&#xff08;Googlebot&#xff09;&#xff0c;導致搜索引擎無法正常抓取頁面。 由于Cloudflare默認的防護規則較為嚴格&#xff0c;尤其是針對高頻訪問的爬蟲IP&…

Ubuntu系統安裝VsCode

在Linux系統中&#xff0c;可以通過.deb文件手動安裝Visual Studio Code&#xff08;VS Code&#xff09;。以下是詳細的安裝步驟&#xff1a; 下載.deb文件 訪問Visual Studio Code的官方網站。 在下載頁面中&#xff0c;找到適用于Linux的.deb文件。 根據你的系統架構&…

降本增效雙突破:Profinet轉Modbus TCP助力包布機產能與穩定性雙提升

在現代工業自動化領域&#xff0c;ModbusTCP和Profinet是兩種常見的通訊協議。它們在數據傳輸、設備控制等方面有著重要作用。然而&#xff0c;由于這兩種協議的工作原理和應用環境存在差異&#xff0c;直接互聯往往會出現兼容性問題。此時&#xff0c;就需要一種能夠實現Profi…

Python對JSON數據操作

在Python中&#xff0c;對JSON數據進行增刪改查及加載保存操作&#xff0c;主要通過內置的json模塊實現。 一、基礎操作 1. 加載JSON數據 ? 從文件加載 使用json.load()讀取JSON文件并轉換為Python對象&#xff08;字典/列表&#xff09;&#xff1a; import json with open…

Linux詳解基本指令(一)

?? 歡迎大家來到小傘的大講堂?? &#x1f388;&#x1f388;養成好習慣&#xff0c;先贊后看哦~&#x1f388;&#x1f388; 所屬專欄&#xff1a;LInux_st 小傘的主頁&#xff1a;xiaosan_blog 制作不易&#xff01;點個贊吧&#xff01;&#xff01;謝謝喵&#xff01;&a…

Node-Red通過Profinet轉ModbusTCP采集西門子PLC數據配置案例

一、內容簡介 本篇內容主要介紹Node-Red通過node-red-contrib-modbus插件與ModbusTCP設備進行通訊&#xff0c;這里Profinet轉ModbusTCP網關作為從站設備&#xff0c;Node-Red作為主站分別從0地址開始讀取10個線圈狀態和10個保持寄存器&#xff0c;分別用Modbus-Read、Modbus-…

React方向:react的基本語法-數據渲染

1、安裝包(js庫) yarn add babel-standalone react react-dom 示例圖.png 2、通過依賴包導入js庫文件 <script src"../node_modules/babel-standalone/babel.js"></script> <script src"../node_modules/react/umd/react.development.js"&g…

k8s部署grafana

部署成功截圖&#xff1a; 要在 Kubernetes (K8s) 集群中拉取 Grafana 鏡像并創建 Grafana 容器&#xff0c;您可以按照以下步驟使用命令行完成操作。下面是完整的命令步驟&#xff0c;包括如何創建 Deployment 和 Service&#xff0c;以及如何將 Grafana 容器暴露給外部。1. 創…

基于注意力機制與iRMB模塊的YOLOv11改進模型—高效輕量目標檢測新范式

隨著深度學習技術的發展,目標檢測在自動駕駛、智能監控、工業質檢等場景中得到了廣泛應用。針對當前主流目標檢測模型在邊緣設備部署中所面臨的計算資源受限和推理效率瓶頸問題,YOLO系列作為單階段目標檢測框架的代表,憑借其高精度與高速度的平衡優勢,在工業界具有極高的應…

uniapp運行到微信開發者工具報錯“更改appid失敗touristappidError:tourist appid”

原因分析 因為項目還沒配置自己的 小程序 AppID&#xff0c;導致微信開發者工具拒絕運行。 解決辦法&#xff1a;在 HBuilderX 中設置 AppID 打開你的項目 在左側找到并點擊 manifest.json 文件 切換到上方的 tab&#xff1a;「小程序配置」標簽頁 找到微信小程序區域&#…

使用Thrust庫實現異步操作與回調函數

文章目錄 使用Thrust庫實現異步操作與回調函數基本異步操作插入回調函數更復雜的回調示例注意事項 使用Thrust庫實現異步操作與回調函數 在Thrust庫中&#xff0c;你可以通過CUDA流(stream)來實現異步操作&#xff0c;并在適當的位置插入回調函數。以下是如何實現的詳細說明&a…

mysql-Java手寫分布式事物提交流程

準備 innodb存儲引擎開啟支持分布式事務 set global innodb_support_axon分布式的流程 詳細流程&#xff1a; XA START ‘a’; 作用&#xff1a;開始一個新的XA事務&#xff0c;并分配一個唯一的事務ID ‘a’。 說明&#xff1a;在這個命令之后&#xff0c;所有后續的SQL操…

算法練習:19.JZ29 順時針打印矩陣

錯誤原因 總體思路有&#xff0c;但不夠清晰&#xff0c;一直在邊調試邊完善。這方面就養成更好的構思習慣&#xff0c;以及漲漲經驗吧。 分析&#xff1a; 思路&#xff1a;找規律 兩個坑&#xff1a; 一次循環的后半段是倒著遍歷的是矩陣不是方陣&#xff0c;要考慮行列…

計算機組成與體系結構:緩存設計概述(Cache Design Overview)

目錄 Block Placement&#xff08;塊放置&#xff09; Block Identification&#xff08;塊識別&#xff09; Block Replacement&#xff08;塊替換&#xff09; Write Strategy&#xff08;寫策略&#xff09; 總結&#xff1a; 高速緩存設計包括四個基礎核心概念&#xf…

Tomcat多應用部署與靜態資源路徑問題全解指南

&#x1f9d1; 博主簡介&#xff1a;CSDN博客專家、CSDN平臺優質創作者&#xff0c;高級開發工程師&#xff0c;數學專業&#xff0c;10年以上C/C, C#, Java等多種編程語言開發經驗&#xff0c;擁有高級工程師證書&#xff1b;擅長C/C、C#等開發語言&#xff0c;熟悉Java常用開…