Menggunakan konteks yang diproyeksikan untuk mengakses hardware kacamata AI

Perangkat XR yang kompatibel
Panduan ini membantu Anda membangun pengalaman untuk jenis perangkat XR ini.
Kacamata AI

Setelah Anda meminta dan diberi izin yang diperlukan, aplikasi Anda dapat mengakses hardware kacamata AI. Kunci untuk mengakses hardware kacamata (bukan hardware ponsel), adalah dengan menggunakan konteks yang diproyeksikan.

Ada dua cara utama untuk mendapatkan konteks yang diproyeksikan, bergantung pada tempat kode Anda dieksekusi:

Mendapatkan konteks yang diproyeksikan jika kode Anda berjalan dalam aktivitas kacamata AI

Jika kode aplikasi Anda berjalan dari dalam aktivitas kacamata AI, konteks aktivitasnya sendiri sudah merupakan konteks yang diproyeksikan. Dalam skenario ini, panggilan yang dilakukan dalam aktivitas tersebut sudah dapat mengakses hardware kacamata.

Mendapatkan konteks yang diproyeksikan jika kode Anda berjalan di komponen aplikasi ponsel

Jika bagian aplikasi Anda di luar aktivitas kacamata AI (seperti aktivitas ponsel atau layanan) perlu mengakses hardware kacamata, aplikasi tersebut harus mendapatkan konteks yang diproyeksikan secara eksplisit. Untuk melakukannya, gunakan metode createProjectedDeviceContext():

// From a phone Activity, get a context for the AI glasses
try {
    val glassesContext = ProjectedContext.createProjectedDeviceContext(this)
    // Now use glassesContext to access glasses' system services
} catch (e: IllegalStateException) {
    // Projected device was not found
}

Memeriksa validitas

Setelah membuat konteks yang diproyeksikan, pantau ProjectedContext.isProjectedDeviceConnected. Saat metode ini menampilkan true, konteks yang diproyeksikan tetap valid untuk perangkat yang terhubung, dan aktivitas atau layanan aplikasi ponsel Anda (seperti CameraManager) dapat mengakses hardware kacamata AI.

Membersihkan saat koneksi terputus

Konteks yang diproyeksikan terikat pada siklus proses perangkat yang terhubung, sehingga akan dihancurkan saat perangkat terputus. Saat perangkat terputus, ProjectedContext.isProjectedDeviceConnected menampilkan false. Aplikasi Anda harus memantau perubahan ini dan membersihkan layanan sistem (seperti CameraManager) atau resource yang dibuat aplikasi Anda menggunakan konteks yang diproyeksikan tersebut.

Menginisialisasi ulang saat terhubung kembali

Saat perangkat kacamata AI terhubung kembali, aplikasi Anda dapat memperoleh instance konteks yang diproyeksikan lain menggunakan createProjectedDeviceContext(), lalu menginisialisasi ulang layanan atau resource sistem menggunakan konteks yang diproyeksikan baru.

Mengakses audio menggunakan Bluetooth

Saat ini, kacamata AI terhubung ke ponsel Anda sebagai perangkat audio Bluetooth standar. Headset dan profil A2DP (Advanced Audio Distribution Profile) didukung. Dengan pendekatan ini, aplikasi Android apa pun yang mendukung input atau output audio dapat berfungsi di kacamata, meskipun aplikasi tersebut tidak dibuat secara khusus untuk mendukung kacamata. Dalam beberapa kasus, penggunaan Bluetooth mungkin berfungsi lebih baik untuk kasus penggunaan aplikasi Anda sebagai alternatif untuk mengakses hardware kacamata menggunakan konteks yang diproyeksikan.

Seperti perangkat audio Bluetooth standar lainnya, izin untuk memberikan izin RECORD_AUDIO dikontrol oleh ponsel, bukan kacamata.

Mengambil gambar dengan kamera kacamata AI

Untuk mengambil gambar dengan kamera kacamata AI, siapkan dan ikat ImageCapture kasus penggunaan CameraX ke kamera kacamata menggunakan konteks yang benar untuk aplikasi Anda:

private fun startCamera() {
    // Get the CameraProvider using the projected context.

    val cameraProviderFuture = ProcessCameraProvider.getInstance(
        ProjectedContext.createProjectedDeviceContext(this)
    )

    cameraProviderFuture.addListener({
        // Used to bind the lifecycle of cameras to the lifecycle owner
        val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()

        // Select the camera. When using the projected context, DEFAULT_BACK_CAMERA maps to the AI glasses' camera.
        val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
    
        // Check for the presence of a camera before initializing the ImageCapture use case.
       if (!cameraProvider.hasCamera(cameraSelector)) {
            Log.w(TAG, "The selected camera is not available.")
            return@addListener
        }

        // Get supported streaming resolutions.
        val cameraInfo = cameraProvider.getCameraInfo(cameraSelector)
        val camera2CameraInfo = Camera2CameraInfo.from(cameraInfo)
        val cameraCharacteristics = camera2CameraInfo.getCameraCharacteristic(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)

        // Define the resolution strategy.
        val targetResolution = Size(1920, 1080)
        val resolutionStrategy = ResolutionStrategy(
            targetResolution,
            ResolutionStrategy.FALLBACK_RULE_CLOSEST_LOWER)

        val resolutionSelector = ResolutionSelector.Builder()
            .setResolutionStrategy(resolutionStrategy)
            .build()

        // If you have other continuous use cases bound, such as Preview or ImageAnalysis, you can use  Camera2 Interop's CaptureRequestOptions to set the FPS
        val fpsRange = Range(30, 30)
        val captureRequestOptions = CaptureRequestOptions.Builder()
                .setCaptureRequestOption(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE,fpsRange)
                .build()

        // Initialize the ImageCapture use case.
        val imageCapture = ImageCapture.Builder()
            // Optional: Configure resolution, format, etc.
            .setResolutionSelector(resolutionSelector)
            .build()

        try {
            // Unbind use cases before rebinding
            cameraProvider.unbindAll()

            // 4. Bind use cases to camera
            cameraProvider.bindToLifecycle(this as LifecycleOwner, cameraSelector, imageCapture)

        } catch(exc: Exception) {
            // This catches exceptions like IllegalStateException if use case binding fails
            Log.e(TAG, "Use case binding failed", exc)
        }

    }, ContextCompat.getMainExecutor(this))
}

Poin penting tentang kode

  • Mendapatkan instance ProcessCameraProvider menggunakan konteks perangkat yang diproyeksikan.
  • Dalam cakupan konteks yang diproyeksikan, kamera utama kacamata AI yang menghadap ke luar dipetakan ke DEFAULT_BACK_CAMERA saat memilih kamera.
  • Pemeriksaan pra-binding menggunakan cameraProvider.hasCamera(cameraSelector) untuk memverifikasi apakah kamera yang dipilih tersedia di perangkat sebelum melanjutkan.
  • Menggunakan Interop Camera2 dengan Camera2CameraInfo untuk membaca CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP yang mendasarinya, yang dapat berguna untuk pemeriksaan lanjutan pada resolusi yang didukung.
  • ResolutionSelector kustom dibuat untuk mengontrol secara tepat resolusi gambar output untuk ImageCapture.
  • Membuat kasus penggunaan ImageCapture yang dikonfigurasi dengan ResolutionSelector kustom.
  • Mengikat kasus penggunaan ImageCapture ke siklus proses aktivitas. Hal ini secara otomatis mengelola pembukaan dan penutupan kamera berdasarkan status Aktivitas (misalnya, menghentikan kamera saat aktivitas dijeda).

Setelah kamera kacamata AI disiapkan, Anda dapat mengambil gambar dengan kelas ImageCapture CameraX. Lihat dokumentasi CameraX untuk mempelajari cara menggunakan takePicture() untuk mengambil gambar.

Merekam video dengan kamera kacamata AI

Untuk merekam video, bukan gambar, dengan kamera kacamata AI, ganti komponen ImageCapture dengan komponen VideoCapture yang sesuai dan ubah logika eksekusi pengambilan.

Perubahan utama melibatkan penggunaan kasus penggunaan yang berbeda, pembuatan file output yang berbeda, dan memulai pengambilan menggunakan metode perekaman video yang sesuai. Untuk mengetahui informasi selengkapnya tentang VideoCapture API dan cara menggunakannya, lihat dokumentasi perekaman video CameraX.

Tabel berikut menunjukkan resolusi dan kecepatan frame yang direkomendasikan, bergantung pada kasus penggunaan aplikasi Anda:

Kasus penggunaan Resolusi Kecepatan frame
Komunikasi Video 1280 x 720 15 FPS
Computer Vision 640 x 480 10 FPS
Streaming Video AI 640 x 480 1 FPS

Mengakses hardware ponsel dari aktivitas kacamata AI

Aktivitas kacamata AI juga dapat mengakses hardware ponsel (seperti kamera atau mikrofon) dengan menggunakan createHostDeviceContext(context) untuk mendapatkan konteks perangkat host (ponsel):

// From an AI glasses Activity, get a context for the phone
val phoneContext = ProjectedContext.createHostDeviceContext(this)
// Now use phoneContext to access the phone's hardware

Saat mengakses hardware atau resource yang khusus untuk perangkat host (ponsel) dalam aplikasi hybrid (aplikasi yang berisi pengalaman seluler dan kacamata AI), Anda harus memilih konteks yang benar secara eksplisit untuk memastikan aplikasi Anda dapat mengakses hardware yang benar: