اولین فعالیت خود را برای عینک‌های صوتی و عینک‌های نمایشی ایجاد کنید

دستگاه‌های XR قابل اجرا
این راهنما به شما کمک می‌کند تا برای این نوع دستگاه‌های XR تجربه ایجاد کنید.
صوتی و
عینک نمایش

تجربیات افزوده برای عینک‌های صوتی و عینک‌های نمایشی بر اساس API موجود در چارچوب Activity اندروید ساخته شده‌اند و شامل مفاهیم اضافی برای پشتیبانی از جنبه‌های منحصر به فرد این عینک‌ها هستند. برخلاف هدست‌های XR که یک APK کامل را روی دستگاه اجرا می‌کنند، عینک‌های صوتی و عینک‌های نمایشی از یک فعالیت اختصاصی استفاده می‌کنند که در برنامه موجود تلفن شما اجرا می‌شود. این فعالیت از دستگاه میزبان به عینک‌ها منتقل می‌شود.

برای ایجاد تجربه برنامه خود برای عینک‌های صوتی و عینک‌های نمایشی، شما برنامه تلفن موجود خود را با ایجاد یک Activity جدید projected گسترش می‌دهید. این activity به عنوان نقطه ورود اصلی راه‌اندازی برای برنامه شما روی عینک عمل می‌کند. این رویکرد توسعه را ساده می‌کند زیرا می‌توانید منطق کسب‌وکار را بین تجربیات تلفن و عینک خود به اشتراک بگذارید و دوباره استفاده کنید.

سازگاری نسخه

الزامات سازگاری Android SDK را برای Jetpack XR SDK بررسی کنید.

وابستگی‌ها

وابستگی‌های کتابخانه‌ای زیر را برای عینک‌های صوتی و عینک‌های نمایشی اضافه کنید:

گرووی

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"
}

کاتلین

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")
}

فعالیت خود را در مانیفست برنامه خود اعلام کنید

درست مانند سایر انواع اکتیویتی‌ها، شما باید اکتیویتی خود را در فایل مانیفست برنامه خود تعریف کنید تا سیستم آن را ببیند و اجرا کند.

<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>

نکات کلیدی در مورد کد

  • xr_projected برای ویژگی android:requiredDisplayCategory مشخص می‌کند تا به سیستم بگوید که این فعالیت باید از یک زمینه‌ی پیش‌بینی‌شده برای دسترسی به سخت‌افزار از یک دستگاه متصل استفاده کند.

فعالیت خود را ایجاد کنید

در مرحله بعد، یک فعالیت کوچک ایجاد خواهید کرد که می‌تواند هر زمان که صفحه نمایش روشن می‌شود، چیزی را روی عینک هوش مصنوعی نمایش دهد.

@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))
    }
}

نکات کلیدی در مورد کد

پیاده‌سازی composable

اکتیویتی که شما ایجاد کرده‌اید به یک تابع قابل ترکیب HomeScreen اشاره می‌کند که باید آن را پیاده‌سازی کنید. کد زیر از Jetpack Compose Glimmer برای تعریف یک تابع قابل ترکیب استفاده می‌کند که می‌تواند متنی را روی صفحه نمایش عینک نمایش دهد:

@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")
        }
    }
}

نکات کلیدی در مورد کد

  • همانطور که قبلاً در activity خود تعریف کردید، تابع HomeScreen شامل محتوای قابل ترکیبی است که کاربر هنگام روشن بودن صفحه نمایش عینک می‌بیند.
  • کامپوننت Jetpack Compose Glimmer Text متن «سلام، عینک هوش مصنوعی!» را روی نمایشگر عینک نمایش می‌دهد.
  • Button Jetpack Compose Glimmer با فراخوانی finish() از طریق onClose در activity مورد نظر، activity را می‌بندد.

بررسی کنید که آیا عینک‌های صوتی یا تصویری متصل هستند یا خیر

برای اینکه قبل از اجرای اکتیویتی خود، مشخص کنید که آیا عینک صوتی یا تصویری کاربر به تلفن همراهش متصل است یا خیر، از متد ProjectedContext.isProjectedDeviceConnected استفاده کنید. این متد یک Flow<Boolean> برمی‌گرداند که برنامه شما می‌تواند آن را مشاهده کند تا به‌روزرسانی‌های بلادرنگ در مورد وضعیت اتصال را دریافت کند.

فعالیت خود را شروع کنید

اکنون که یک اکتیویتی پایه ایجاد کرده‌اید، می‌توانید آن را روی عینک خود اجرا کنید. برای دسترسی به سخت‌افزار عینک، برنامه شما باید اکتیویتی شما را با گزینه‌های خاصی که به سیستم می‌گوید از یک زمینه‌ی پیش‌بینی‌شده استفاده کند، همانطور که در کد زیر نشان داده شده است، آغاز کند:

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

متد createProjectedActivityOptions در ProjectedContext گزینه‌های لازم برای شروع فعالیت شما در یک زمینه‌ی پیش‌بینی‌شده را تولید می‌کند. پارامتر context می‌تواند زمینه‌ای از تلفن یا دستگاه عینک باشد.

مراحل بعدی

حالا که اولین فعالیت خود را برای عینک‌های صوتی و عینک‌های نمایشی ایجاد کرده‌اید، روش‌های دیگری را که می‌توانید عملکرد آن را گسترش دهید، بررسی کنید: