AI グラス用の最初のアクティビティを作成する

対象の XR デバイス
このガイダンスは、次のようなタイプの XR デバイス向けのエクスペリエンスを構築する際に役立ちます。
AI グラス

AI グラスのエクスペリエンスは、既存の Android Activity フレームワーク API をベースに構築されており、AI グラスの独自性をサポートするための追加のコンセプトが含まれています。デバイス上で完全な APK を実行する XR ヘッドセットとは異なり、AI グラスはスマートフォンの既存のアプリ内で実行される専用のアクティビティを使用します。このアクティビティは、ホストデバイスから AI グラスに投影されます。

アプリの AI グラス エクスペリエンスを作成するには、AI グラス用の新しい投影 Activity を作成して、既存のスマートフォン アプリを拡張します。このアクティビティは、AI グラスでのアプリのメインの起動エントリ ポイントとして機能します。このアプローチでは、スマートフォンと AI グラスのエクスペリエンス間でビジネス ロジックを共有して再利用できるため、開発が簡素化されます。

バージョンの互換性

Jetpack XR SDK の Android SDK の互換性要件を確認してください。

依存関係

AI グラス用の次のライブラリ依存関係を追加します。

Groovy

dependencies {
    implementation "androidx.xr.runtime:runtime:1.0.0-alpha10"
    implementation "androidx.xr.glimmer:glimmer:1.0.0-alpha06"
    implementation "androidx.xr.projected:projected:1.0.0-alpha04"
    implementation "androidx.xr.arcore:arcore:1.0.0-alpha10"
}

Kotlin

dependencies {
    implementation("androidx.xr.runtime:runtime:1.0.0-alpha10")
    implementation("androidx.xr.glimmer:glimmer:1.0.0-alpha06")
    implementation("androidx.xr.projected:projected:1.0.0-alpha04")
    implementation("androidx.xr.arcore:arcore:1.0.0-alpha10")
}

アプリのマニフェストでアクティビティを宣言する

他のタイプのアクティビティと同様に、システムがアクティビティを認識して実行できるように、アプリのマニフェスト ファイルでアクティビティを宣言する必要があります。

<application>
  <activity
      android:name="com.example.xr.projected.GlassesMainActivity"
      android:exported="true"
      android:requiredDisplayCategory="xr_projected"
      android:label="Example AI Glasses activity">
      <intent-filter>
          <action android:name="android.intent.action.MAIN" />
      </intent-filter>
  </activity>
</application>

コードに関する主なポイント

  • android:requiredDisplayCategory 属性に xr_projected を指定して、このアクティビティが予測コンテキストを使用して接続されたデバイスからハードウェアにアクセスする必要があることをシステムに伝えます。

アクティビティを作成する

次に、ディスプレイがオンになるたびに AI グラスに何かを表示できる小さなアクティビティを作成します。

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

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

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

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

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

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

コードに関する主なポイント

コンポーザブルを実装する

作成したアクティビティは、実装する必要がある HomeScreen コンポーザブル関数を参照します。次のコードでは、Jetpack Compose Glimmer を使用して、AI グラスのディスプレイにテキストを表示できるコンポーザブルを定義しています。

@Composable
fun HomeScreen(
    areVisualsOn: Boolean,
    isVisualUiSupported: Boolean,
    onClose: () -> Unit,
    modifier: Modifier = Modifier
) {
    Box(
        modifier = modifier
            .surface(focusable = false)
            .fillMaxSize(),
        contentAlignment = Alignment.Center
    ) {
        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")
        }
    }
}

コードに関する主なポイント

  • アクティビティで定義したように、HomeScreen 関数には、AI グラスのディスプレイがオンのときにユーザーに表示されるコンポーザブル コンテンツが含まれています。
  • Jetpack Compose Glimmer Text コンポーネントは、メガネのディスプレイに「Hello, AI Glasses!」というテキストを表示します。
  • Jetpack Compose Glimmer Button は、AI メガネ アクティビティの onClose を介して finish() を呼び出すことでアクティビティを閉じます。

AI グラスが接続されているかどうかを確認する

アクティビティを起動する前に、ユーザーの AI グラスがスマートフォンに接続されているかどうかを判断するには、ProjectedContext.isProjectedDeviceConnected メソッドを使用します。このメソッドは、アプリが接続ステータスのリアルタイム更新を取得するために監視できる Flow<Boolean> を返します。

アクティビティを開始する

基本的なアクティビティを作成したので、グラスで起動できます。メガネのハードウェアにアクセスするには、次のコードに示すように、投影コンテキストを使用するようにシステムに指示する特定のオプションを指定して、アクティビティを開始する必要があります。

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

ProjectedContextcreateProjectedActivityOptions メソッドは、投影されたコンテキストでアクティビティを開始するために必要なオプションを生成します。context パラメータは、スマートフォンまたはメガネ型デバイスのコンテキストにできます。

次のステップ

AI グラス用の最初のアクティビティを作成したので、その機能を拡張する他の方法を見てみましょう。