Attiva e personalizza l'handoff tra dispositivi

Continua su introduce nuovi metodi e classi per indicare il supporto della funzionalità e fornire i dati necessari che vengono trasmessi. In questo modo, puoi riprendere correttamente l'esperienza utente sul dispositivo di destinazione.

Attiva il supporto

Il supporto di Continua su (disattivato per impostazione predefinita) deve essere implementato per ogni attività. Per attivare la funzionalità, chiama setHandoffEnabled per indicare che l'attività corrente è pronta per l'handoff. Una volta chiamato setHandoffEnabled(true, null), l'handoff può avvenire in qualsiasi momento per l'attività, quindi chiamalo solo quando l'attività è pronta per l'handoff.

Puoi verificare se l'attività ha attivato Continua su con isHandoffEnabled. Se un'attività ha abilitato l'handoff, deve anche implementare onHandoffActivityDataRequested per assicurarsi che restituisca un HandoffActivityData non nullo, poiché non è implementato alcun comportamento predefinito.

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

Puoi configurare l'oggetto HandoffActivityData con eventuali extra pertinenti e un URI di riserva per informare Continua su come eseguire l'handoff al dispositivo di ricezione.

Questi dati sono necessari al sistema in due situazioni:

  • L'attività sta passando in background e i dati pertinenti devono essere salvati.
  • L'attività è in primo piano ed è stato richiesto l'handoff. Puoi controllare lo stato di una richiesta di trasferimento.

Verifica lo stato

La classe HandoffActivityDataRequestInfo fornisce informazioni sulla richiesta corrente di trasferimento di un'attività. Utilizza isActiveRequest per determinare se la richiesta è attualmente attiva. Se il metodo restituisce

  • true, l'attività corrente è in primo piano e l'utente ha richiesto di continuare su un altro dispositivo, ma se
  • false, l'attività è stata interrotta ed è in background, ma l'utente potrebbe richiedere un handoff in futuro.

Sul dispositivo di invio, se vuoi mostrare un'UI per indicare all'utente che è avvenuto o è in corso un trasferimento, puoi controllare isActiveRequest per verificare se è presente una richiesta attiva. Tuttavia, non eseguire questo codice in modo sincrono nell'ambito di onHandoffActivityDataRequested. Invece, metti in coda l'esecuzione di qualsiasi codice in modo asincrono per non bloccare o ritardare l'handoff.

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

Crea i dati di handoff

Per assicurarti che tutti i dati pertinenti e necessari vengano trasmessi durante l'handoff con la funzionalità Continua su, devi includerli nell'oggetto HandoffActivityData.

La classe HandoffActivityData rappresenta i dati di handoff associati a un'attività. HandoffActivityData informa Continua su come gestire e ricreare un'attività sul dispositivo di destinazione. I dati di handoff includono:

  • Nome del componente (obbligatorio): il ComponentName di un'attività corrispondente da avviare sul dispositivo di destinazione per riprendere il percorso dell'utente dopo l'handoff. Nella maggior parte dei casi e per la replica esatta dell'attività, questo sarà il nome del componente per la stessa attività che crea l'oggetto HandoffActivityData.
  • Extra (facoltativo): puoi specificare extra che verranno inclusi nell'avvio Intent dell'attività. Si tratta di un PersistableBundle che può essere utilizzato per fornire informazioni aggiuntive al componente. Gli extra devono avere una dimensione inferiore a 50 kB.

Per creare oggetti HandoffActivityData, utilizza la classe builder, HandoffActivityData.Builder. Crea un nuovo builder passando il ComponentName dell'attività che deve ricevere l'handoff (ad esempio, this.getComponentName per l'Activity corrente o un ComponentName(this, TargetActivity::class.java) esplicito). Poi utilizza il metodo setExtras per specificare facoltativamente gli extra. Infine, chiama build per creare l'oggetto 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()
}

Imposta l'opzione di riserva per il web

Nel caso in cui l'attività specificata non possa essere avviata sul dispositivo ricevente, puoi anche utilizzare setFallbackUri per impostare facoltativamente un URL di riserva che viene aperto sul dispositivo nel browser predefinito dell'utente.

Per consentire la visualizzazione del suggerimento Continua su sui dispositivi di destinazione in cui la tua app non è installata, passa un'istanza HandoffActivityParams con setAllowHandoffWithoutPackageInstalled impostato su true quando chiami setHandoffEnabled:

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

Poi includi l'URL di riserva nel tuo HandoffActivityData:

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

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

Implementa il reindirizzamento diretto al web

In alternativa, per implementare l'handoff diretto al web, passa HandoffActivityParams con setAllowHandoffWithoutPackageInstalled(true) a setHandoffEnabled e utilizza il metodo HandoffActivityData.createWebHandoff per generare HandoffActivityData:

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

val handoffData: HandoffActivityData = HandoffActivityData.createWebHandoff(webHandoffLink)

Ricevi e gestisci l'intent di trasferimento

Sul dispositivo di destinazione, l'app deve gestire l'handoff e ricreare l'esperienza dell'utente dal dispositivo di invio. Nello specifico, nell'attività che hai specificato in HandoffActivityData restituito da onHandoffActivityDataRequested, devi gestire l'intent e recuperare gli extra che contengono informazioni su come ricreare l'attività in modo appropriato.

Se specifichi l'handoff alla stessa attività, puoi ricevere l'intent nel metodo onCreate dell'attività in modo che i dati possano essere recuperati e precompilati in modo appropriato per l'utente.

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