Android14 への適応 - targetSdkVersion を 34 にアップグレードする際に注意すべき点は何ですか?

前回の記事によると、もう一ヶ月が経ちましたね、金、九、銀はあるものの、今年は本当に閑散とした雰囲気ですね、仕事があるといいですね。米ドル利上げが早く終わって、景気が早く良くなるといいですね〜

前回の記事ではAndroid14端末に全アプリをインストールした場合の影響や注意すべき内容を紹介しましたが、次回はtargetSdkVersionを34にバージョンアップした場合のアプリの注意点や修正点について紹介します。 。

1. コア機能の変更

1.1 フロントサービスの種類

targetSdkVersion >= 34 の場合、アプリケーション内のフォアグラウンド サービス (フォアグラウンド サービス) ごとに少なくとも 1 つのフォアグラウンド サービス タイプを指定する必要があります。

フロント デスク サービスとは何ですか?
フォアグラウンド サービスは、ユーザーの現在のアクティビティに関連する長時間実行タスクを実行するために使用される特別なタイプのサービスです。これらのサービスは、システム ステータス バーに通知を表示して、アプリが停止していることをユーザーに通知します。フォアグラウンドでタスクを実行し、システム リソースを使用しています。 Android12 (API レベル 31) 以降のデバイスでは、システムは実行時間の短いフォアグラウンド サービスを最適化しています。システムは、ユーザー エクスペリエンスを向上させ、即時の通知による干渉を減らすために、フォアグラウンド サービスに関連する通知を表示するまで 10 秒待機します。使用する場合はマニフェストファイルで android.permission.FOREGROUND_SERVICE 権限を申請する必要があります。

フロントエンド サービス タイプは Android10 で導入されました。android:foregroundServiceType を通じて <service> のサービス タイプを指定できます。使用可能なフロントエンド サービス タイプは次のとおりです:

  1. カメラ: マルチタスクをサポートするビデオ チャット アプリケーションなど、カメラがバックグラウンドにあるときは、カメラにアクセスし続ける必要があります。
  2. ConnectedDevice: Bluetooth、NFC、IR、USB、またはネットワーク接続を必要とする外部デバイスと通信します。
  3. dataSync: データのアップロードまたはダウンロード、バックアップとリカバリの操作、インポートまたはエクスポートの操作、データの取得、ローカル ファイルの処理、ネットワークを介したデバイスとクラウド間のデータ転送などのデータ転送操作。 (このタイプは、今後の Android バージョンでは非推奨になる可能性があります。代わりに WorkManager またはユーザーが開始したデータ転送ジョブを使用することをお勧めします)
  4. health: アクティビティ トラッカーなどのフィットネス アプリケーションをサポートするために、長期間の運用が必要なユースケースに使用されます。
  5. location: ナビゲーションや位置情報の共有など、位置情報へのアクセスが必要な長期実行のユースケース。
  6. mediaPlayback: バックグラウンドでのオーディオまたはビデオの連続再生、または Android TV でのデジタル ビデオ録画 (DVR) のサポートが必要です。
  7. mediaProjection: MediaProjection API を使用して、コンテンツを非プライマリ モニターまたは外部デバイスに投影します。このコンテンツは必ずしもメディア コンテンツのみである必要はありません。
  8. マイク: バックグラウンドで継続的にマイクをキャプチャする必要があります (ボイス レコーダーや通信アプリケーションなど)。
  9. phoneCall: ConnectionService API の継続的な使用が必要なシナリオ。
  10. remoteMessaging: あるデバイスから別のデバイスにテキスト メッセージを転送します。ユーザーがデバイスを切り替えた場合でも、ユーザー メッセージング タスクの継続性を確保できます。
  11. shortService: 中断または延期できない重要な作業は迅速に完了する必要があります。次の 5 つの特徴があります: 1) 短時間(約 3 分)しか実行できない; 2) スティッキー フォアグラウンド サービスをサポートしていない; 3) 実行できない他のフロントエンド サービスを開始する; 4) 特定のタイプのアクセス許可を申請する必要はありませんが、FOREGROUND_SERVICE アクセス許可は必須です; 5) 実行中のフロントエンド サービスは shortService タイプ間で切り替えることができません。タイムアウト後、 Service.onTimeout() が呼び出されます。この API は Android14 の新機能です。ANR を回避するには、 onTimeout コールバックを実装することをお勧めします。
  12. specialUse: 上記のすべてのタイプに含まれない場合は、このタイプを使用します。フォアグラウンド サービス タイプの宣言FOREGROUND_SERVICE_TYPE_SPECIAL_USEに加えて、マニフェストでユース ケースも宣言する必要があります。つまり、以下に示すように、
// code 1
<service android:name="fooService" android:foregroundServiceType="specialUse">
  <property android:name="android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE" android:value="foo"/>
</service>
  1. systemExempted: フォアグラウンド サービスを引き続き使用するために、システム アプリケーションおよび特定のシステム統合用に予約されています。通常のアプリ開発者は心配する必要はありません。

上記 13 種類のうち、做有彩色标记 は Android14 で新たに追加されたもので、その他は以前から存在していました。

バックグラウンド再生の一般的な例を挙げると、まずマニフェスト ファイルで権限を宣言し、設定しますforegroundServiceType:

// code 2
<manifest ...>
 <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
 <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
 <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
   <application ...>
     <service
         android:name=".MusicPlayerService"
         android:foregroundServiceType="mediaPlayback"
         android:exported="false">
     </service>
   </application>
</manifest>

次に、MusicPlayerService クラスを実装します。主に、onStartCommand コールバックで通知を開いて音楽の再生を開始します。

// code 3
class MusicPlayerService : Service() {
    
    
    private var mediaPlayer: MediaPlayer? = null

    override fun onBind(intent: Intent?): IBinder? {
    
    
        return null
    }

    @RequiresApi(Build.VERSION_CODES.O)
    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
    
    
        val NOTIFICATION_CHANNEL_ID = "com.example.foregroundservice"
        val notificationManager = NotificationManagerCompat.from(this)

        // If the notification supports a direct reply action, use
        // PendingIntent.FLAG_MUTABLE instead.
        val pendingIntent: PendingIntent =
            Intent(this, NotificationFullActivity::class.java).let {
    
     notificationIntent ->
                PendingIntent.getActivity(
                    this, 0, notificationIntent,
                    PendingIntent.FLAG_IMMUTABLE
                )
            }

        // 创建通知渠道
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    
    
            val name: CharSequence = "Notification Channel Name"
            val description = "Description of Notification Channel"
            val importance = NotificationManager.IMPORTANCE_DEFAULT
            val channel = NotificationChannel(NOTIFICATION_CHANNEL_ID, name, importance)
            channel.description = description
            notificationManager.createNotificationChannel(channel)
        }

        // 构建通知
        val builder: NotificationCompat.Builder =
            NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
                .setSmallIcon(android.R.drawable.ic_lock_idle_alarm)
                .setContentTitle("音乐播放中")
                .setContentText("艺术家 - 音乐")
                .setContentIntent(pendingIntent)
                .setPriority(NotificationCompat.PRIORITY_DEFAULT)

        // 启动通知
        val notificationId = 1 // 每个通知的唯一标识符
        if (ActivityCompat.checkSelfPermission(
                this,
                Manifest.permission.POST_NOTIFICATIONS
            ) == PackageManager.PERMISSION_GRANTED
        ) {
    
    
            notificationManager.notify(notificationId, builder.build())
        }
        // Notification ID cannot be 0.
        startForeground(notificationId, builder.build())

        // 播放音乐
        mediaPlayer = MediaPlayer.create(this, R.raw.music1)
        mediaPlayer?.isLooping = true
        mediaPlayer?.start()

        return START_STICKY
    }
}

最後に、サービスを開始します。

// code 4
requireActivity().startForegroundService(Intent(requireActivity(), MusicPlayerService::class.java))

マニフェスト ファイルでタイプが指定されていない場合、startForeground() メソッドが呼び出されたときに MissingForegroundServiceTypeException 例外がスローされます。

上記のサンプル コードに関する追加の注意事項は、Android 13 以降の携帯電話で通知通知がポップアップ表示される場合、android.permission.POST_NOTIFICATIONS アクセス許可を動的に適用する必要があることです。 NoticeChannel チャネルを作成する必要があります。これは Android8 以降ではすでに必要です。

フロントエンド サービスについて話しましょう。上記の各フロントエンド サービス タイプには異なるアクセス許可が必要で、これらのアクセス許可は通常のアクセス許可として定義されています。これらのアクセス許可はデフォルトで付与されており、ユーザーはこれらのアクセス許可を取り消すことはできません. .たとえば、カメラ サービス タイプは、マニフェスト ファイルで FOREGROUND_SERVICE_CAMERA アクセス許可を宣言し、実行時にカメラ アクセス許可を適用する必要があります。これは他のサービス タイプにも当てはまります。

フォアグラウンド サービスの種類 マニフェスト要件 実行時の要件
カメラ FOREGROUND_SERVICE_CAMERA カメラ
接続されたデバイス FOREGROUND_SERVICE_CONNECTED_DEVICE マニフェストで CHANGE_NETWORK_STATE または CHANGE_WIFI_STATE または CHANGE_WIFI_MULTICAST_STATE または NFC または TRANSMIT_IR を宣言するか、実行時権限をリクエストするか、BLUETOOTH_CONNECT、BLUETOOTH_ADVERTISE、BLUETOOTH_SCAN、または UWB_RANGING を要求するか、UsbManager.requestPermission() を呼び出します。
データ同期 FOREGROUND_SERVICE_DATA_SYNC -
健康 FOREGROUND_SERVICE_HEALTH マニフェストで HIGH_SAMPLING_RATE_SENSORS を宣言するか、実行時権限 (BODY_SENSORS または ACTIVITY_RECOGNITION) を申請します。
位置 FOREGROUND_SERVICE_LOCATION ACCESS_COARSE_LOCATION または ACCESS_FINE_LOCATION
メディア再生 FOREGROUND_SERVICE_MEDIA_PLAYBACK -
メディアプロジェクション FOREGROUND_SERVICE_MEDIA_PROJECTION CreateScreenCaptureIntent() はその前に呼び出す必要があります
マイクロフォン FOREGROUND_SERVICE_MICROPHONE レコードオーディオ
電話 FOREGROUND_SERVICE_PHONE_CALL マニフェストで MANAGE_OWN_CALLS を宣言する
リモートメッセージング FOREGROUND_SERVICE_REMOTE_MESSAGING -
ショートサービス - -
特殊用途 FOREGROUND_SERVICE_SPECIAL_USE -
システム免除 FOREGROUND_SERVICE_SYSTEM_EXEMPTED -

もちろん、特別な状況があるはずです。フロントエンド サービスが上記の 13 に関連していない場合、公式の推奨事項は、これらのサービスをWorkManager または ユーザーが開始したデータ転送ジョブに移行することです。 .

ユーザー開始のデータ転送ジョブは、ユーザーによって開始されるデータ転送タスクです。この API は Android 14 の新機能で、リモート サーバーからのファイルのダウンロードなど、ユーザーが開始する必要がある長時間のデータ転送に適しています。これらのタスクは、通知バーに通知が表示され、すぐに開始され、システム条件が許す限り実行される必要があります。ユーザーが開始した複数のデータ転送ジョブを同時に実行できます。

概要: フロントエンド サービスが現在アプリケーションで使用されており、targetSdkVersion を 34 に上げたい場合は、フロントエンド サービスのタイプを追加する必要があります。それ以外の場合は、そのままにしておきます。

1.2 Bluetooth接続の許可変更

Android 14 では、BluetoothAdaptergetProfileConnectionState() API を呼び出すときに BLUETOOTH_CONNECT 権限を申請する必要があります。これは必要ありませんでした。以前はありましたが、現在はこの権限をマニフェスト ファイルで宣言し、実行時にユーザーに適用する必要があります。

Android が近年、一部のシステム権限を徐々に取り戻していることは明らかです。これは開発者にとってはさらに面倒ですが、大多数のユーザーにとっては有益です。

1.3 OpenJDK 17 アップデート

Android14 では、Android のコア ライブラリを更新し続け、最新の OpenJDK LTS バージョンの特徴や機能に合わせます。これには、アプリケーションおよびプラットフォーム開発者向けのライブラリや Java17 言語サポートの更新も含まれます。次の変更の一部は、アプリケーションの互換性に影響を与える可能性があります。

  1. 正規表現の変更: 一部の正規表現が変更されました。アプリケーション内で正規表現が使用されている場所を確認して、エラーがないかどうかを確認してください。開発者向けオプションで互換性モードをオフにすると、問題のある領域を簡単に見つけることができます。特定の互換性モードのスイッチはシステム>詳細>開発者向けオプション>アプリケーション互換性の変更 ここ (ネイティブ システムはここにあります。他のメーカーについては言いにくいです) を選択し、リストから独自のアプリを選択して閉じるか開きます。ここで、リストの一番下にスライドして Enabled for targetSdkVersion >= 34 DISALLOW_INVALID_GROUP_REFERENCE オプション スイッチを見つける必要があります。
  2. UUID 処理: java.util.UUID.fromString() メソッドは、入力パラメータを検証するときにより厳密なチェックを実行するため、逆シリアル化中に異常な IllegalArgumentException をスローする可能性があります。セルフテスト方法は上記と同じですが、アプリケーションの互換性の変更で ENABLE_STRICT_VALIDATION オプションを切り替える必要があります。
  3. ProGuard の問題: ProGuard を使用してコードを圧縮、難読化、最適化すると、java.lang.ClassValue を追加した後に問題が発生する場合があります。この問題は、アプリケーションが古いバージョンで開発された を使用せずにクラスをターゲットにしている場合、 Class.forName("java.lang.ClassValue") の実行時にクラスが返されるかどうかのランタイム動作を変更する Kotlin ライブラリによって発生します。これらの最適化により、 派生クラスから メソッドが削除されます。 java.lang.ClassValuejava.lang.ClassValuecomputeValue

概要: JDK17 には下位互換性がありますが、新しい記述方法や最適化が多数あるため、時間があるときにアップグレードすることをお勧めします。

2. セキュリティ

Android14 ではセキュリティ要件も高くなりますが、これは Google が近年注力している方向でもあります。

2.1 暗黙的インテントと PendingIntent の制限

Implicit Intent (Implicit Intent) は、Android アプリケーションのコンポーネント間の通信の仕組みであり、どのコンポーネントを起動するかを明示的に指定するのではなく、実行する操作を宣言します。システムは、この操作を処理できるコンポーネントを探して開始します。暗黙的インテントは主に、アクティビティの開始、サービスの開始、ブロードキャストの送信など、アプリケーション内または他のアプリケーションとのさまざまな操作をトリガーするために使用されます。一般的な例は、まずマニフェスト ファイルのアクティビティにインテント フィルターのアクションを設定し、次にそのアクティビティと一致するように起動インテントにアクションを設定して起動します。

  1. 暗黙的インテントは、android:exported="true" のコンポーネント (4 つの主要なコンポーネント: アクティビティ、サービス...) にのみ渡すことができます。したがって、インテントを使用してアプリ内でデータを渡す場合は、明示的なインテントを使用して android:exported="false" のコンポーネントに渡すか、暗黙的なインテントを使用して のコンポーネントに渡す必要があります。 =3>。もちろん、明示的な Intent を exported="true" に渡すことは間違いなく可能です。 android:exported="true"
  2. 可変PendingIntent は packageName を設定する必要があります。設定しないと例外がスローされます。

栗をあげます:

// code 5
<!-- android:exported 设置为false,隐式 Intent 无法启动 -->
<activity
    android:name=".AppActivity"
    android:exported="false">
    <intent-filter>
        <action android:name="com.example.action.SEND" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>
// code 6
// Throws an exception when targeting Android 14.  直接用隐式的 Intent 调用不管用
context.startActivity(Intent("com.example.action.SEND"))

// This makes the intent explicit. 当设置了 intent 中的 package 参数时就可以了
val explicitIntent =
        Intent("com.example.action.SEND")
explicitIntent.apply {
    
    
    `package` = context.packageName
}
context.startActivity(explicitIntent)

概要: この変更、特に android:exported が false に設定されているコンポーネントに注意してください。これらのコンポーネントは起動時にクラッシュする可能性があるため、変更する必要があります。これらの変更により、悪意のあるアプリがアプリ内のコンポーネントで使用される暗黙的なインテントを傍受することが防止されるため、この更新はセキュリティのためでもあります。

2.2 動的ブロードキャスト受信機はエクスポートされた動作を指定する必要がある

動的に登録されたブロードキャスト レシーバーは、レシーバーがデバイス上のすべてのアプリにエクスポートされるかどうかを示すフラグを設定する必要があります。フラグ ビットは RECEIVER_EXPORTED または RECEIVER_NOT_EXPORTED です。 Android 13 以降に導入されたこの機能により、登録されたブロードキャスト レシーバーをエクスポートしてデバイス上の他のアプリケーションに表示するかどうかをアプリケーションで指定できるようになります。

Android14では「必須設定」になっただけです。以前のバージョンの Android では、受信側が許可に署名していない限り、デバイス上のすべてのアプリが、動的に登録されたブロードキャスト受信側に保護されていないブロードキャストを送信できました。

たとえば、アプリケーション A に AlarmReceiver を登録し、ブロードキャストを送信します。

// code 7
val filter = IntentFilter("alarmReceiver_custom_action")
val listenToBroadcastsFromOtherApps = true
val receiverFlags = if (listenToBroadcastsFromOtherApps) {
    
    
    ContextCompat.RECEIVER_EXPORTED    // 该接收器对其他应用开放
} else {
    
    
    ContextCompat.RECEIVER_NOT_EXPORTED    // 该接收器不对其他应用开放
}
// 这里的 registerReceiver 方法必须设置 receiverFlags 参数
registerReceiver(requireContext(), AlarmReceiver(), filter, receiverFlags)

// 发送广播
val intent = Intent("alarmReceiver_custom_action")    // 方式1
//val intent = Intent(requireActivity(), AlarmReceiver::class.java)    // 方式2
requireActivity().sendBroadcast(intent)

他のアプリケーションでは、コード 7 のメソッド 1 を通じてのみブロードキャストを送信できます。アプリケーション A のlistenToBroadcastsFromOtherApps が true に設定されている場合、アプリケーション A は他のアプリケーションを通じてブロードキャストを受信できます。1 は送信しました放送情報を受信できない場合があります。

実際に、アプリケーション A が方法 1 を通じて独自の内部ブロードキャストも送信し、ContextCompat.RECEIVER_NOT_EXPORTED を設定すると、このブロードキャストを受信できないこともわかりました。

アプリケーションが Context#registerReceiver メソッド (Context#registerReceiver() など) を通じてシステム ブロードキャストの受信機を登録するだけの場合、登録時にこのフラグを指定できない可能性があります。受信機。 。

概要: ダイナミックブロードキャストの登録方法が変更になり、android:exportedの設定と同様に他のアプリから見えるかどうかの設定が必要になります。実際、ローカル ブロードキャストとグローバル ブロードキャストの機能は同じですが、targetSdkVersion >= 34 に重点が置かれています。

2.3 より安全な動的コード読み込み

動的にロードされるすべてのファイルは読み取り専用としてマークされている必要があります。それ以外の場合、システムは例外をスローします。当局は、アプリケーションがコードを動的にロードすることをできる限り回避することを推奨しています。動的にロードすると、コードインジェクションやコード改ざんによってアプリケーションが損傷するリスクが大幅に増加するためです。

コードを動的にロードする必要がある場合は、動的にロードされるファイル (DEX、JAR、または APK ファイルなど) を読み取り専用に設定してから、ファイルを開いて何かを書き込む必要があります。

// code 8
val jar = File("DYNAMICALLY_LOADED_FILE.jar")
val os = FileOutputStream(jar)
os.use {
    
    
    // Set the file to read-only first to prevent race conditions
    jar.setReadOnly()
    // Then write the actual file content
}
val cl = PathClassLoader(jar.absolutePath, parentClassLoader)

さらに、動的に読み込まれた既存のファイルに対してシステムが例外をスローしないようにするために、当局は、アプリケーションでこれらのファイルを動的に再度読み込む前に、ファイルを削除して再作成することを推奨しています。ファイルを再作成するときは、上記のガイドラインに従って、書き込み中にファイルを読み取り専用としてマークします。あるいは、既存のファイルを読み取り専用としてマークすることもできますが、この場合は、悪意のあるアクションからアプリを保護するために、最初にファイルの整合性を検証する (たとえば、ファイルの署名を信頼できる値と照合するなど) ことをお勧めします。

2.4 ジップパスのトラバーサル

Android14 アプリケーションの場合、Android システムは次の方法で Zip パス トラバーサルの脆弱性を防止します。zip ファイルのエントリ名に「...」が含まれるか、「/」で始まる場合、ZipFile(String) および ZipInputStream.getNextEntry()ZipException 例外をスローします。

例外をスローしたくなく、ファイル名を変更できない場合は、dalvik.system.ZipPathValidator.clearCallback() を呼び出して検証を終了することを選択できます。もちろん、これはお勧めできません。

Zip パス トラバーサルの脆弱性: 「.../」を含む、または「/」で始まるファイル パスを構築することにより、悪意のある攻撃者は、Zip ファイルを解凍するときに、Zip ファイル以外のファイル システム上の任意のファイルまたはディレクトリにアクセスし、損害を与えることができます。 Zip ファイル セキュリティ上のリスクを引き起こすアプリケーションの脆弱性。

2.5 バックグラウンドでのアクティビティの開始に関する新しい制限事項

Android14 では、アプリがバックグラウンドからアクティビティを開始できる状況がシステムによってさらに制限されます。

  1. アプリが送信にPendingIntent#send()または同様のメソッドを使用するPendingIntent場合、送信する独自​​のバックグラウンド アクティビティを開始する許可を付与するかどうかを選択する必要があります。 a> PendingIntent 。承認を選択した場合は、 setPendingIntentBackgroundActivityStartMode(MODE_BACKGROUND_ACTIVITY_START_ALLOWED) メソッドを通じて ActivityOptions オブジェクトを返し、渡す必要があります。
  2. フォアグラウンドで表示されているアプリケーションがbindService() メソッドを使用して別のバックグラウンド アプリケーションのサービスをバインドする場合、表示されているアプリケーションは、独自のバックグラウンド アクティビティの起動権限をバックグラウンド アプリケーションに付与するかどうかを選択する必要があります。 1サーブをバウンドします。承認が選択されている場合、アプリケーションは bindService() メソッドを呼び出すときに BIND_ALLOW_ACTIVITY_STARTS フラグを設定する必要があります。

これらの変更により、既存の一連の制限が拡張され、悪意のあるアプリケーションが API を悪用してバックグラウンドで破壊的なアクティビティを開始するのを防ぎ、ユーザーを保護します。

概要: バックグラウンド起動の制御が厳しくなりました。プロジェクト内に該当するロジックがある場合は、バックグラウンドで起動できるか実行して確認することをお勧めします。問題がある場合は、上記内容に従って修正してください。 . 意味がよくわかりません。 。 。

3. 非 SDK インターフェイスの制限に関する更新

Android14 では、制限された非 SDK インターフェイスのリストが更新されます (Android 開発者との協力および内部テストで使用される最新の API リストに基づいています)。非 SDK インターフェイスの使用を制限する前に、パブリックな代替手段が利用可能であることを確認するために最善を尽くします。

Android 14 をターゲットにしていない場合、これらの変更の一部はアプリにすぐには影響しない可能性があります。ただし、アプリで非 SDK メソッドまたはフィールドを使用する場合は、アプリで問題が発生する重大なリスクが常に存在します。

一般に、パブリック SDK インターフェースは Android フレームワーク内にありますパッケージ インデックス (https://developer.android.google.cn/reference/packages)< a i=2> に記録されているインターフェース。非 SDK インターフェイスの処理は、API によって抽象化された実装の詳細であるため、これらのインターフェイスはいつでも予告なく変更される可能性があります。

アプリが非 SDK インターフェイスを使用しているかどうかが不明な場合は、テスト アプリをデバッグ モードで実行できます。アプリが非 SDK インターフェイスにアクセスすると、システムはログ メッセージを出力します。アプリのログ メッセージで次の詳細を調べることができます。
1) 宣言されたクラス、名前、および型 (Android ランタイムで使用される形式);
2) アクセス方法: リンク、リフレクション、または JNI;
3) アクセスされた非 SDK インターフェイスがどのリストに属しているか;
adb logcat を使用することもできます実行中のアプリケーションの PID の下に表示されるログ メッセージを表示します。たとえば、ログには次のようなエントリが含まれる場合があります。

Accessing hidden field Landroid/os/Message;->flags:I (light greylist, JNI)

アプリが非 SDK インターフェイスに依存している場合は、代替 SDK への移行計画を開始する必要があります。アプリの機能に非 SDK インターフェイスを使用する代替手段が見つからない場合は、新しいパブリック API をリクエストする必要があります。

Android 14 のすべての非 SDK インターフェースの完全なリストについては、次のファイルをダウンロードして表示できます。hiddenapi-flags.csv (https://dl.google. com/developers /android/udc/non-sdk/hiddenapi-flags.csv?hl=zh-cn)、このテーブル ファイルには多くのコンテンツが含まれており、クエリに使用できます。

概要: 通常のアプリケーション開発者は非 SDK インターフェイスを使用しないため、これは無視できます。

以上がこの記事の内容ですが、既存アプリを直接targetSdkVersionを34(Android14)にアップグレードした場合、注意すべき箇所や修正・テストが必要な箇所がまだあることが分かります。 Android 14 で追加された新機能をまだ知りたい場合は、私をフォローしてください。次の記事でお会いしましょう!

その他のコンテンツについては、公式アカウント Xiuzhizhu
をフォローするか、Xiuzhizhu の Android アルバムをご覧ください。

人を讃えるバラは手に香りを残します!いいね、再投稿大歓迎です〜再投稿の際は出典を明記してください〜

参考文献

  1. Android 14 公式ドキュメント https://developer.android.com/about/versions/14
  2. https://developer.android.google.cn/about/versions/14/behavior-changes-14?hl=zh-cn
  3. Android 14 の迅速な適応ポイント; Lianmao de Xiaoguo; https://juejin.cn/post/7231835495557890106?searchId=202307240025039D8229C74EA62159077B
  4. https://developer.android.google.cn/guide/components/foreground-services
  5. https://developer.android.com/about/versions/14/changes/user-initiated-data-transfers?hl=zh-cn
  6. https://developer.android.google.cn/about/versions/14/changes/fgs-types-required
  7. https://developer.android.google.cn/about/versions/13/features#runtime-receivers
  8. https://developer.android.google.cn/about/versions/14/changes/non-sdk-14?hl=zh-cn

おすすめ

転載: blog.csdn.net/lbs458499563/article/details/132928217