[Android] Support Android 12 (#23522)

* [Android] Support Android 12

* fix NetworkCredentials NPE

Co-authored-by: panliming-tuya <panlm@tuya.com>
diff --git a/examples/android/CHIPTool/app/build.gradle b/examples/android/CHIPTool/app/build.gradle
index 118b288..1ad83dc 100644
--- a/examples/android/CHIPTool/app/build.gradle
+++ b/examples/android/CHIPTool/app/build.gradle
@@ -92,7 +92,7 @@
     androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
     implementation "androidx.core:core-ktx:1.3.0"
     implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
-    implementation "androidx.work:work-runtime:2.3.3"
+    implementation "androidx.work:work-runtime:2.7.1"
     implementation 'com.google.code.gson:gson:2.8.5'
     implementation 'com.jjoe64:graphview:4.2.2'
 
diff --git a/examples/android/CHIPTool/app/src/main/AndroidManifest.xml b/examples/android/CHIPTool/app/src/main/AndroidManifest.xml
index 7a2febc..0d7401f 100644
--- a/examples/android/CHIPTool/app/src/main/AndroidManifest.xml
+++ b/examples/android/CHIPTool/app/src/main/AndroidManifest.xml
@@ -5,6 +5,9 @@
 
     <uses-permission android:name="android.permission.BLUETOOTH" />
     <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
+    <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
+    <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
+    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
     <uses-permission android:name="android.permission.CAMERA" />
     <uses-permission android:name="android.permission.INTERNET" />
     <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/SelectActionFragment.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/SelectActionFragment.kt
index a0fd93b..4f5b910 100644
--- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/SelectActionFragment.kt
+++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/SelectActionFragment.kt
@@ -19,6 +19,7 @@
 
 import android.Manifest
 import android.content.pm.PackageManager
+import android.os.Build
 import android.os.Bundle
 import android.view.LayoutInflater
 import android.view.View
@@ -68,39 +69,58 @@
     if (savedInstanceState != null) return
     if (hasLocationPermission()) return
 
-    val permissionRequest = registerForActivityResult(
-        ActivityResultContracts.RequestPermission()
-    ) { granted ->
-      if (granted) {
-        provisionWiFiCredentialsBtn.isEnabled = true
-        provisionThreadCredentialsBtn.isEnabled = true
-      } else {
-        provisionWiFiCredentialsBtn.isEnabled = false
-        provisionThreadCredentialsBtn.isEnabled = false
+    val permissionRequest =
+      registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { grantResults
+        ->
+        var granted = true
+        for (value in grantResults.values) {
+          if (!value) {
+            granted = false
+          }
+        }
+        if (granted) {
+          provisionWiFiCredentialsBtn.isEnabled = true
+          provisionThreadCredentialsBtn.isEnabled = true
+        } else {
+          provisionWiFiCredentialsBtn.isEnabled = false
+          provisionThreadCredentialsBtn.isEnabled = false
 
-        AlertDialog.Builder(requireContext())
+          AlertDialog.Builder(requireContext())
             .setTitle(R.string.location_permission_denied_title)
             .setMessage(R.string.location_permission_denied_message)
             .setPositiveButton(R.string.text_ok) { dialog, _ -> dialog.dismiss() }
             .setCancelable(false)
             .create()
             .show()
+        }
       }
-    }
 
-    permissionRequest.launch(Manifest.permission.ACCESS_FINE_LOCATION)
+    val permissions: Array<String> =
+      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
+        arrayOf(
+          Manifest.permission.BLUETOOTH_SCAN,
+          Manifest.permission.BLUETOOTH_CONNECT,
+          Manifest.permission.ACCESS_FINE_LOCATION,
+        )
+      } else {
+        arrayOf(Manifest.permission.ACCESS_FINE_LOCATION)
+      }
+    permissionRequest.launch(permissions)
   }
 
   private fun hasLocationPermission(): Boolean {
     val locationPermissionState =
-        ContextCompat.checkSelfPermission(
-            requireContext(),
-            Manifest.permission.ACCESS_FINE_LOCATION
-        )
+      ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.ACCESS_FINE_LOCATION)
+    var blePermissionState = 1
+    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
+      blePermissionState =
+        ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.BLUETOOTH_SCAN)
+    }
 
-    return PackageManager.PERMISSION_GRANTED == locationPermissionState
+    return PackageManager.PERMISSION_GRANTED == (locationPermissionState + blePermissionState)
   }
 
+
   private fun getCallback() = FragmentUtil.getHost(this, Callback::class.java)
 
   /** Interface for notifying the host. */
diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/provisioning/DeviceProvisioningFragment.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/provisioning/DeviceProvisioningFragment.kt
index f816fab..8dd548c5 100644
--- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/provisioning/DeviceProvisioningFragment.kt
+++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/provisioning/DeviceProvisioningFragment.kt
@@ -121,19 +121,16 @@
 
       val deviceId = DeviceIdUtil.getNextAvailableId(requireContext())
       val connId = bluetoothManager.connectionId
-      val network = NetworkCredentials()
+      var network: NetworkCredentials? = null
       var networkParcelable = checkNotNull(networkCredentialsParcelable)
 
-      val wifi = networkParcelable.getWiFiCredentials()
-      if (wifi != null)
-      {
-        network.setWiFiCredentials(wifi.getSsid(), wifi.getPassword())
+      val wifi = networkParcelable.wiFiCredentials
+      if (wifi != null) {
+        network = NetworkCredentials.forWiFi(NetworkCredentials.WiFiCredentials(wifi.ssid, wifi.password))
       }
-
-      val thread = networkParcelable.getThreadCredentials()
-      if (thread != null)
-      {
-        network.setThreadCredentials(thread.getOperationalDataset())
+      val thread = networkParcelable.threadCredentials
+      if (thread != null) {
+        network = NetworkCredentials.forThread(NetworkCredentials.ThreadCredentials(thread.operationalDataset))
       }
 
       deviceController.pairDevice(gatt, connId, deviceId, deviceInfo.setupPinCode, network)