Ses gözlükleri ve ekranlı gözlükler için ilk etkinliğinizi oluşturma

Uygun XR cihazlar
Bu kılavuz, bu tür XR cihazlar için deneyimler oluşturmanıza yardımcı olur.
Ses ve
Ekran Gözlükleri

Ses gözlükleri ve ekranlı gözlükler için artırılmış deneyimler, mevcut Android Activity framework API'si üzerine kurulur ve bu gözlüklerin benzersiz yönlerini desteklemek için ek kavramlar içerir. Cihazda tam APK çalıştıran XR kulaklıkların aksine, ses gözlükleri ve ekran gözlükleri, telefonunuzdaki mevcut uygulamada çalışan özel bir etkinlik kullanır. Bu etkinlik, ana cihazdan gözlüğe yansıtılır.

Uygulamanızın ses gözlükleri ve ekranlı gözlüklerdeki deneyimini oluşturmak için yeni bir yansıtılan Activity oluşturarak mevcut telefon uygulamanızı genişletirsiniz. Bu etkinlik, uygulamanızın gözlüklerdeki ana başlatma giriş noktası olarak kullanılır. Bu yaklaşım, telefonunuz ve gözlüğünüzdeki deneyimler arasında işletme mantığını paylaşmanıza ve yeniden kullanmanıza olanak tanıdığı için geliştirme sürecini basitleştirir.

Sürüm uyumluluğu

Jetpack XR SDK için Android SDK uyumluluk koşullarını kontrol edin.

Bağımlılıklar

Aşağıdaki ses gözlüğü ve ekran gözlüğü için kitaplık bağımlılıklarını ekleyin:

Modern

dependencies {
    implementation "androidx.xr.runtime:runtime:1.0.0-alpha14"
    implementation "androidx.xr.glimmer:glimmer:1.0.0-alpha12"
    implementation "androidx.xr.glimmer:glimmer-google-fonts:1.0.0-alpha12"
    implementation "androidx.xr.projected:projected:1.0.0-alpha07"
    implementation "androidx.xr.arcore:arcore:1.0.0-alpha13"
}

Kotlin

dependencies {
    implementation("androidx.xr.runtime:runtime:1.0.0-alpha14")
    implementation("androidx.xr.glimmer:glimmer:1.0.0-alpha12")
    implementation("androidx.xr.glimmer:glimmer-google-fonts:1.0.0-alpha12")
    implementation("androidx.xr.projected:projected:1.0.0-alpha07")
    implementation("androidx.xr.arcore:arcore:1.0.0-alpha13")
}

Uygulamanızın manifest dosyasında etkinliğinizi beyan edin

Diğer etkinlik türlerinde olduğu gibi, sistemin etkinliğinizi görmesi ve çalıştırması için uygulamanızın manifest dosyasında etkinliğinizi beyan etmeniz gerekir.

<application>
  <activity
      android:name="com.example.xr.projected.GlassesMainActivity"
      android:exported="true"
      android:requiredDisplayCategory="xr_projected"
      android:label="Example activity for audio glasses and display glasses">
      <intent-filter>
          <action android:name="android.intent.action.MAIN" />
      </intent-filter>
  </activity>
</application>

Kodla ilgili önemli noktalar

  • Sisteme, bu etkinliğin bağlı bir cihazdaki donanıma erişmek için yansıtılan bir bağlam kullanması gerektiğini bildirmek üzere android:requiredDisplayCategory özelliği için xr_projected değerini belirtir.

Etkinliğinizi oluşturma

Ardından, ekran her açıldığında yapay zeka gözlüğünde bir şeyler gösterebilen küçük bir etkinlik oluşturacaksınız.

@OptIn(ExperimentalProjectedApi::class)
class GlassesMainActivity : ComponentActivity() {

    private var displayController: ProjectedDisplayController? = null
    private var isVisualUiSupported by mutableStateOf(false)
    private var areVisualsOn by mutableStateOf(true)
    private var isPermissionDenied by mutableStateOf(false)

    // Register the permissions launcher using the ProjectedPermissionsResultContract.
    private val requestPermissionLauncher: ActivityResultLauncher<List<ProjectedPermissionsRequestParams>> =
        registerForActivityResult(ProjectedPermissionsResultContract()) { results ->
            if (results[Manifest.permission.CAMERA] == true) {
                isPermissionDenied = false
                initializeGlassesFeatures()
            } else {
                // Handle permission denial.
                isPermissionDenied = true
            }
        }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        lifecycle.addObserver(object : DefaultLifecycleObserver {
            override fun onDestroy(owner: LifecycleOwner) {
                displayController?.close()
                displayController = null
            }
        })

        if (hasCameraPermission()) {
            initializeGlassesFeatures()
        } else {
            requestHardwarePermissions()
        }

        setContent {
            GlimmerTheme {
                HomeScreen(
                    areVisualsOn = areVisualsOn,
                    isVisualUiSupported = isVisualUiSupported,
                    isPermissionDenied = isPermissionDenied,
                    onRetryPermission = { requestHardwarePermissions() },
                    onClose = { finish() }
                )
            }
        }
    }

    private fun initializeGlassesFeatures() {
        lifecycleScope.launch {
            // Check device capabilities
            val projectedDeviceController = ProjectedDeviceController.create(this@GlassesMainActivity)
            isVisualUiSupported = projectedDeviceController.capabilities.contains(CAPABILITY_VISUAL_UI)

            val controller = ProjectedDisplayController.create(this@GlassesMainActivity)
            displayController = controller
            val observer = GlassesLifecycleObserver(
                context = this@GlassesMainActivity,
                controller = controller,
                onVisualsChanged = { visualsOn -> areVisualsOn = visualsOn }
            )
            lifecycle.addObserver(observer)
        }
    }

    private fun hasCameraPermission(): Boolean {
        return ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) ==
                PackageManager.PERMISSION_GRANTED
    }

    private fun requestHardwarePermissions() {
        val params = ProjectedPermissionsRequestParams(
            permissions = listOf(Manifest.permission.CAMERA),
            rationale = "Camera access is required to overlay digital content on your physical environment."
        )
        requestPermissionLauncher.launch(listOf(params))
    }
}

Kodla ilgili önemli noktalar

Composable'ı uygulama

Oluşturduğunuz etkinlik, uygulamanız gereken bir HomeScreen composable işlevine referans veriyor. Aşağıdaki kod, gözlüğün ekranında metin görüntüleyebilen bir composable tanımlamak için Jetpack Compose Glimmer'ı kullanır:

@Composable
fun HomeScreen(
    areVisualsOn: Boolean,
    isVisualUiSupported: Boolean,
    isPermissionDenied: Boolean,
    onRetryPermission: () -> Unit,
    onClose: () -> Unit,
    modifier: Modifier = Modifier
) {
    Box(
        modifier = modifier
            .surface()
            .focusable(false)
            .fillMaxSize(),
        contentAlignment = Alignment.Center
    ) {
        if (isPermissionDenied) {
            Card(
                title = { Text("Permission Required") },
                action = { Button(onClick = onClose) { Text("Exit") } }
            ) {
                Text("Camera access is needed to use AI glasses features.")
                Button(onClick = onRetryPermission) { Text("Retry") }
            }
        } else if (isVisualUiSupported) {
            Card(
                title = { Text("Android XR") },
                action = {
                    Button(onClick = onClose) {
                        Text("Close")
                    }
                }
            ) {
                if (areVisualsOn) {
                    Text("Hello, AI Glasses!")
                } else {
                    Text("Display is off. Audio guidance active.")
                }
            }
        } else {
            Text("Audio Guidance Mode Active")
        }
    }
}

Kodla ilgili önemli noktalar

  • Daha önce etkinliğinizde tanımladığınız gibi, HomeScreen işlevi, gözlüğün ekranı açıkken kullanıcının gördüğü birleştirilebilir içeriği içerir.
  • Jetpack Compose Glimmer Text bileşeni, gözlüğün ekranında "Merhaba, Yapay Zeka Gözlükleri!" metnini gösterir.
  • Jetpack Compose Glimmer Button, yansıtılan etkinlikteki onClose aracılığıyla finish() çağrısı yaparak etkinliği kapatır.

Ses veya ekran gözlüğünün bağlı olup olmadığını kontrol etme

Etkinliğinizi başlatmadan önce kullanıcının ses veya ekran gözlüğünün telefonuna bağlı olup olmadığını belirlemek için ProjectedContext.isProjectedDeviceConnected yöntemini kullanın. Bu yöntem, bağlantı durumuyla ilgili anlık güncellemeler almak için uygulamanızın gözlemleyebileceği bir Flow<Boolean> döndürür.

Etkinliğinizi başlatma

Temel bir etkinlik oluşturduğunuza göre artık bu etkinliği gözlüğünüzde başlatabilirsiniz. Uygulamanızın gözlüğün donanımına erişebilmesi için etkinliğinizi, aşağıdaki kodda gösterildiği gibi sisteme yansıtılmış bir bağlam kullanmasını söyleyen belirli seçeneklerle başlatması gerekir:

val options = ProjectedContext.createProjectedActivityOptions(context)
val intent = Intent(context, GlassesMainActivity::class.java)
context.startActivity(intent, options.toBundle())

createProjectedActivityOptions yöntemi, ProjectedContext içinde etkinliğinizi planlanan bir bağlamda başlatmak için gerekli seçenekleri oluşturur. context parametresi, telefondaki veya gözlük cihazındaki bir bağlam olabilir.

Sonraki adımlar

Ses gözlüğü ve ekran gözlüğü için ilk etkinliğinizi oluşturduğunuza göre, işlevselliğini genişletebileceğiniz diğer yöntemleri keşfedin: