複数デバイス間の引き継ぎを有効にしてカスタマイズする

Continue On では、この機能のサポートを示し、渡される必要なデータを提供するための新しいメソッドとクラスが導入されています。これにより、受信側デバイスでユーザー エクスペリエンスを適切に再開できます。

サポートを有効にする

「続行」のサポート(デフォルトではオフ)は、アクティビティごとに実装する必要があります。この機能を有効にするには、setHandoffEnabled を呼び出して、現在のアクティビティがハンドオフの準備ができていることを示します。setHandoffEnabled(true, null) が呼び出されると、アクティビティの引き継ぎがいつでも行われる可能性があるため、アクティビティの引き継ぎの準備が整ったときにのみ呼び出します。

アクティビティで Continue On が有効になっているかどうかは、isHandoffEnabled で確認できます。アクティビティでハンドオフが有効になっている場合は、onHandoffActivityDataRequested も実装して、null 以外の HandoffActivityData が返されるようにする必要があります。デフォルトの動作は実装されていません。

class MyHandoffActivity : Activity() {

    ...

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    // Do stuff
    ...
    // Enable handoff
    setHandoffEnabled(true, null)
  }

  // Override and implement onHandoffActivityDataRequested
  override fun onHandoffActivityDataRequested(handoffRequestInfo: HandoffActivityDataRequestInfo) : HandoffActivityData {
    // Create and return handoff data
  }
}

HandoffActivityData オブジェクトを、関連するエクストラとフォールバック URI で構成して、受信デバイスへのハンドオフの実行方法を Continue On に通知します。

このデータがシステムで必要になる状況は 2 つあります。

  • アクティビティがバックグラウンドに移行し、関連するデータを保存する必要がある。
  • アクティビティがフォアグラウンドにあり、ハンドオフがリクエストされている。ハンドオフ リクエストのステータスを確認できます。

ステータスを確認

HandoffActivityDataRequestInfo クラスは、アクティビティをハンドオフする現在のリクエストに関する情報を提供します。isActiveRequest を使用して、リクエストが現在アクティブかどうかを判断します。メソッドが

  • true の場合、現在のアクティビティはフォアグラウンドにあり、ユーザーは別のデバイスで続行することをリクエストしています。ただし、
  • false: アクティビティは停止してバックグラウンドにありますが、ユーザーが今後ハンドオフをリクエストする可能性があります。

送信側デバイスで、ハンドオフが発生したこと、または進行中であることをユーザーに示す UI を表示する場合は、isActiveRequest でアクティブなリクエストを確認できます。ただし、このコードを onHandoffActivityDataRequested の一部として同期的に実行しないでください。代わりに、ハンドオフをブロックまたは遅延させないように、非同期で実行するコードをキューに入れます。

// Override and implement onHandoffActivityDataRequested
override fun onHandoffActivityDataRequested(handoffRequestInfo: HandoffActivityDataRequestInfo) : HandoffActivityData {

  // Check whether the handoff request is active
  if (handoffRequestInfo.isActiveRequest()) {
    // Asynchronously show UI to let users know a handoff is in progress
  }

  // Create and return handoff data
}

引き継ぎデータを作成する

「続きから」機能を使用したハンドオフ中に関連する必要なデータがすべて渡されるようにするには、HandoffActivityData オブジェクトにデータを含める必要があります。

HandoffActivityData クラスは、アクティビティに関連付けられたハンドオフ データを表します。HandoffActivityData は、受信側デバイスでアクティビティを処理して再作成する方法を Continue On に通知します。引き継ぎデータには次のものが含まれます。

  • コンポーネント名(必須): 引き継ぎ後にユーザーのジャーニーを再開するために、受信側デバイスで起動する対応するアクティビティの ComponentName。ほとんどの場合、アクティビティを正確に複製するには、HandoffActivityData を作成する同じアクティビティのコンポーネント名になります。
  • Extras(省略可): アクティビティの開始 Intent に含まれるエクストラを指定できます。これは、コンポーネントに追加情報を提供するために使用できる PersistableBundle です。エクストラは 50 KB 未満にする必要があります。

HandoffActivityData オブジェクトを作成するには、ビルダー クラス HandoffActivityData.Builder を使用します。ハンドオフを受け取るアクティビティの ComponentName(現在の Activity の this.getComponentName、または明示的な ComponentName(this, TargetActivity::class.java) など)を渡して、新しいビルダーを作成します。次に、setExtras メソッドを使用して、必要に応じてエクストラを指定します。最後に、build を呼び出して HandoffActivityData オブジェクトを作成します。

// Override and implement onHandoffActivityDataRequested
override fun onHandoffActivityDataRequested(handoffRequestInfo: HandoffActivityDataRequestInfo) : HandoffActivityData {

  // Check whether the handoff request is active
  if (handoffRequestInfo.isActiveRequest()) {
    // Asynchronously show UI to let users know a handoff is in progress
  }

  val extras: PersistableBundle = PersistableBundle()
  // Put relevant and necessary values into extras (e.g. scroll position)
  extras.putString("data_id", getDataId())
  extras.putInt("scroll_position", getScrollPosition())

  // Create and return handoff data
  return HandoffActivityData.Builder(getComponentName()) // Designate handoff to the same activity
    .setExtras(extras)
    .build()
}

ウェブのフォールバック オプションを設定する

指定したアクティビティを受信側のデバイスで開始できない場合は、setFallbackUri を使用して、デバイスのデフォルトのブラウザで開く代替 URL を設定することもできます。

アプリがインストールされていない受信デバイスに [Continue On] の候補を表示できるようにするには、setHandoffEnabled を呼び出すときに、setAllowHandoffWithoutPackageInstalled を true に設定した HandoffActivityParams インスタンスを渡します。

setHandoffEnabled(
  true,
  HandoffActivityParams.Builder()
    .setAllowHandoffWithoutPackageInstalled(true)
    .build()
)

次に、HandoffActivityData に代替 URL を含めます。

val fallbackWebLink: Uri = Uri.parse("https://myapp.com/fallback?query=" + paramVal)

val handoffData: HandoffActivityData = HandoffActivityData.Builder(getComponentName())
  .setExtras(extras)
  .setFallbackUri(fallbackWebLink)
  .build()

ウェブへの直接リンクを実装する

または、ウェブへの直接ハンドオフを実装するには、setAllowHandoffWithoutPackageInstalled(true) を指定した HandoffActivityParams を setHandoffEnabled に渡し、HandoffActivityData.createWebHandoff メソッドを使用して HandoffActivityData を生成します。

val webHandoffLink: Uri = Uri.parse("https://myapp.com/handoff?query=" + paramVal)

val handoffData: HandoffActivityData = HandoffActivityData.createWebHandoff(webHandoffLink)

引き継ぎインテントを受信して処理する

受信側のデバイスでは、アプリがハンドオフを処理し、送信側のデバイスからユーザー エクスペリエンスを再作成する必要があります。具体的には、onHandoffActivityDataRequested から返された HandoffActivityData で指定したアクティビティで、インテントを処理し、アクティビティを適切に再作成する方法に関する情報を含むエクストラを取得する必要があります。

同じアクティビティへのハンドオフを指定する場合は、アクティビティの onCreate メソッドでインテントを受け取り、データを取得してユーザー向けに適切に事前入力できます。

class MyHandoffActivity : Activity() {

    ...

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

    // Get the launch intent and retrieve extras
    val intent: Intent = getIntent()
    if (intent != null && intent.hasExtra("data_id")) {
      val dataID: String = intent.getStringExtra("data_id")
      // Retrieve the data that corresponds to the data ID
      ...
      // Populate activity UI with relevant data
      ...

      if (intent.hasExtra("scroll_position")) {
        val scrollPosition: Int = intent.getIntExtra("scroll_position", 0)
        // Move the page to the scroll position
        ...
      }
    }
  }
}