Gli utenti spesso iniziano le attività sul proprio smartphone Android, ad esempio rivedere un documento, organizzare i messaggi o sfogliare un assortimento di articoli, e poi vogliono passare a un Googlebook con il suo display più grande, la tastiera fisica e lo spazio di lavoro multi-finestra.
La funzionalità Continua su in Android 17 (livello API 37) e versioni successive consente alla barra delle app Googlebook di visualizzare un'icona dell'app (chiamata suggerimento) per l'attività che un utente stava eseguendo sul proprio smartphone nelle vicinanze. Con un solo clic, gli utenti possono continuare la loro attività sul Googlebook.
L'implementazione del trasferimento cross-device consente alla tua app di trasferire il contesto dell'attività in modo che l'utente riprenda il flusso di lavoro, nella tua app Android adattiva o nel browser desktop, esattamente da dove aveva interrotto sullo smartphone.
Scegliere un flusso di trasferimento
Prima di attivare il trasferimento cross-device, decidi come deve aprirsi ogni attività nell'app per smartphone quando un utente seleziona il suggerimento Continua su Googlebook:
| Flusso di trasferimento | Targeting su Googlebook | Ideale per | API Key |
|---|---|---|---|
| Trasferimento da un'app all'altra | App per Android nativa in esecuzione in una finestra del desktop | App ottimizzate per schermi di grandi dimensioni e visualizzazione a finestre sul desktop su Google Play | HandoffActivityData.Builder |
| Trasferimento da app ad app con fallback web | App per Android nativa, se installata; in caso contrario, un URL nel browser desktop predefinito | App ottimizzate per un'esperienza nativa con finestre del desktop, ma che richiedono un fallback affidabile del browser quando l'app non è installata su Googlebook | setFallbackUri |
| Trasferimento diretto al web | URL nel browser desktop predefinito (o intercettato dall'app nativa se configurata per i link alle app per Android) | Flussi di lavoro in cui l'applicazione web è l'esperienza desktop principale | HandoffActivityData.createWebHandoff |
Attivare il trasferimento per un'attività
Continua su è disattivata per impostazione predefinita e viene configurata per attività. Segui questi passaggi in ogni attività di invio sullo smartphone:
- Chiama
setHandoffEnablede passatrueuna volta che l'attività ha caricato lo stato richiesto per il trasferimento. Una volta attivato, il sistema può richiedere dati di trasferimento mentre l'attività è in primo piano o si sposta in background. - Esegui l'override di
onHandoffActivityDataRequestedper restituire un oggettoHandoffActivityDatanon nullo. Puoi eseguire query suisHandoffEnabledin qualsiasi momento per verificare se il trasferimento è attivo per l'attività.
import android.app.Activity
import android.app.HandoffActivityData
import android.app.HandoffActivityDataRequestInfo
import android.os.Bundle
import android.os.PersistableBundle
class DocumentEditorActivity : Activity() {
private var documentId: String = "doc_42"
private var scrollOffsetPx: Int = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Enable handoff once the activity is ready to transfer state.
setHandoffEnabled(true, null)
}
override fun onHandoffActivityDataRequested(
handoffRequestInfo: HandoffActivityDataRequestInfo
): HandoffActivityData {
val extras = PersistableBundle().apply {
putString(EXTRA_DOCUMENT_ID, documentId)
putInt(EXTRA_SCROLL_OFFSET, scrollOffsetPx)
}
return HandoffActivityData.Builder(getComponentName())
.setExtras(extras)
.build()
}
companion object {
const val EXTRA_DOCUMENT_ID = "extra_document_id"
const val EXTRA_SCROLL_OFFSET = "extra_scroll_offset"
}
}
Stato dell'attività del pacchetto per il trasferimento
Il sistema chiama onHandoffActivityDataRequested in due scenari:
- Trasferimento in primo piano:l'attività è in primo piano sullo smartphone e l'utente avvia un trasferimento dalla barra delle app di Googlebook.
- Acquisizione dello stato in background: l'attività viene spostata in background sullo smartphone e il sistema memorizza nella cache il payload di trasferimento nel caso in cui l'utente selezioni il suggerimento su Googlebook in un secondo momento.
Controllare se la richiesta di trasferimento è attiva
Ispeziona HandoffActivityDataRequestInfo utilizzando isActiveRequest per
distinguere tra un trasferimento attivo avviato dall'utente e un salvataggio in background:
- Se
isActiveRequestrestituiscetrue, l'utente ha richiesto attivamente di continuare su un altro dispositivo mentre l'attività è visibile. - Se
isActiveRequestrestituiscefalse, il sistema memorizza nella cache lo stato quando l'attività si interrompe.
Se visualizzi un indicatore visivo sullo smartphone che conferma che l'attività
si sta spostando su Googlebook, pianifica l'aggiornamento della UI in modo asincrono in modo che
onHandoffActivityDataRequested venga restituito senza ritardi.
Allegare gli extra statali e un fallback web
Un payload HandoffActivityData contiene le seguenti informazioni:
- Componente target (obbligatorio per il trasferimento da app ad app): passa
this.getComponentName()(l'ComponentNamedell'attività) o unComponentName(this, TargetActivity::class.java)esplicito aHandoffActivityData.Builderper indicare quale attività viene avviata su Googlebook. - Extra (facoltativo): passa un
PersistableBundleasetExtras()contenente identificatori e coordinate dell'interfaccia utente (ad esempio, ID documento aperto, tasti delle schede attive o posizioni di scorrimento). Il bundle deve avere dimensioni inferiori a 50 KB. - URI di riserva (facoltativo): passa un
Uriweb asetFallbackUriin modo che Googlebook possa aprire l'attività nel browser predefinito se l'app per Android non è installata.
import android.app.Activity
import android.app.HandoffActivityData
import android.app.HandoffActivityDataRequestInfo
import android.app.HandoffActivityParams
import android.net.Uri
import android.os.Bundle
import android.os.PersistableBundle
class ArticleReaderActivity : Activity() {
private var articleId: String = "android-desktop-windowing"
private var readingProgressPercent: Int = 45
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHandoffEnabled(
true,
HandoffActivityParams.Builder()
.setAllowHandoffWithoutPackageInstalled(true)
.build()
)
}
override fun onHandoffActivityDataRequested(
handoffRequestInfo: HandoffActivityDataRequestInfo
): HandoffActivityData {
if (handoffRequestInfo.isActiveRequest()) {
window.decorView.post {
onHandoffStartedToSecondaryDevice()
}
}
val extras = PersistableBundle().apply {
putString(EXTRA_ARTICLE_ID, articleId)
putInt(EXTRA_READING_PROGRESS, readingProgressPercent)
}
val fallbackWebUri = Uri.Builder()
.scheme("https")
.authority("example.com")
.appendPath("articles")
.appendPath(articleId)
.appendQueryParameter("progress", readingProgressPercent.toString())
.build()
return HandoffActivityData.Builder(getComponentName())
.setExtras(extras)
.setFallbackUri(fallbackWebUri)
.build()
}
private fun onHandoffStartedToSecondaryDevice() {
// Save local drafts and update phone UI without blocking handoff.
}
companion object {
const val EXTRA_ARTICLE_ID = "extra_article_id"
const val EXTRA_READING_PROGRESS = "extra_reading_progress"
}
}
Configurare il trasferimento diretto al web
Se la tua esperienza desktop principale su Googlebook è un'applicazione web, passa
HandoffActivityParams con setAllowHandoffWithoutPackageInstalled(true) a
setHandoffEnabled e chiama HandoffActivityData.createWebHandoff anziché
utilizzare HandoffActivityData.Builder:
import android.app.Activity
import android.app.HandoffActivityData
import android.app.HandoffActivityDataRequestInfo
import android.app.HandoffActivityParams
import android.net.Uri
import android.os.Bundle
class WebDashboardActivity : Activity() {
private var projectId: String = "proj_901"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHandoffEnabled(
true,
HandoffActivityParams.Builder()
.setAllowHandoffWithoutPackageInstalled(true)
.build()
)
}
override fun onHandoffActivityDataRequested(
handoffRequestInfo: HandoffActivityDataRequestInfo
): HandoffActivityData {
val webUri = Uri.Builder()
.scheme("https")
.authority("app.example.com")
.appendPath("projects")
.appendPath(projectId)
.build()
return HandoffActivityData.createWebHandoff(webUri)
}
}
Ricevere e ripristinare lo stato su Googlebook
Quando l'utente seleziona il suggerimento Continua su nella barra delle app di Googlebook, il
sistema avvia l'intent ComponentName di destinazione in una finestra del desktop e allega gli
extra PersistableBundle all'intent di avvio Intent.
Su Googlebook, gestisci il trasferimento in entrata tenendo presente le finestre delle app e i layout multipanello:
- Estrai gli extra del trasferimento:sia nel metodo
onCreateche in quelloonNewIntentdell'attività ricevente, recupera gli extra dall'intentIntentin arrivo. La gestione dionNewIntentgarantisce che, se l'attività utilizza la modalità di avviosingleTopo indirizza a una finestra desktop esistente, la finestra venga aggiornata all'elemento trasferito. - Adatta lo stato ai layout a più riquadri: uno stato che occupava una visualizzazione dettagliata a schermo intero su uno smartphone spesso corrisponde a un elemento selezionato all'interno di un layout elenco-dettagli o riquadro di supporto su Googlebook. Compila sia la selezione dell'elenco principale sia il riquadro dei dettagli in modo che la finestra del computer abbia un contesto completo.
- Preserva lo stato ripristinato durante il ridimensionamento della finestra:memorizza lo stato trasferito in un
ViewModel(SavedStateHandle) orememberSaveablein Jetpack Compose in modo che il ridimensionamento della finestra in formato libero su Googlebook non reimposti la sessione ripristinata.
import android.app.Activity
import android.content.Intent
import android.os.Bundle
class DocumentEditorReceiverActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Restore from the handoff intent only on initial launch so subsequent
// desktop window configuration changes use saved instance state.
if (savedInstanceState == null) {
handleHandoffIntent(intent)
}
}
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
setIntent(intent)
handleHandoffIntent(intent)
}
private fun handleHandoffIntent(incomingIntent: Intent?) {
val documentId = incomingIntent?.getStringExtra(EXTRA_DOCUMENT_ID)
?: return
val scrollOffsetPx = incomingIntent.getIntExtra(EXTRA_SCROLL_OFFSET, 0)
openDocumentInDesktopWorkspace(
documentId = documentId,
initialScrollOffsetPx = scrollOffsetPx
)
}
private fun openDocumentInDesktopWorkspace(
documentId: String,
initialScrollOffsetPx: Int
) {
// Load the document into the list-detail layout and restore scroll position.
}
companion object {
const val EXTRA_DOCUMENT_ID = "extra_document_id"
const val EXTRA_SCROLL_OFFSET = "extra_scroll_offset"
}
}
Testare il trasferimento tra uno smartphone e Googlebook
Per verificare l'implementazione end-to-end:
- Prepara entrambi i dispositivi
- Accedi allo stesso Account Google sia sullo smartphone Android (con Android 17 o versioni successive) sia su Googlebook (o su un dispositivo di test in modalità finestra desktop).
- Attiva il Bluetooth e connetti entrambi i dispositivi alla stessa rete Wi-Fi.
- Su entrambi i dispositivi, apri Impostazioni > Dispositivi connessi > Preferenze di connessione > Servizi cross-device > Continua l'attività, segui le istruzioni di configurazione e attiva Attività. Per i prerequisiti completi dell'ambiente, vedi Configurazione e test.
- Installare l'app
- Per il trasferimento da app ad app, installa la build sia sullo smartphone che su Googlebook.
- Per il fallback web o il trasferimento diretto al web, installa la build sullo smartphone e lascia l'app disinstallata su Googlebook per verificare che il browser apra l'URL previsto.
- Attivare il trasferimento
- Sullo smartphone, apri l'app e vai all'attività che consente
il trasferimento (chiamata
setHandoffEnabled(true, null)per il trasferimento da app ad app, o passaggio diHandoffActivityParamsconsetAllowHandoffWithoutPackageInstalled(true)durante il test con l'app disinstallata su Googlebook). - Su Googlebook, controlla il lato destro della barra delle app per trovare l'icona dell'app con il badge Continua su e selezionala.
- Sullo smartphone, apri l'app e vai all'attività che consente
il trasferimento (chiamata
- Verifica il ripristino del computer
- Verifica che l'app si apra in una finestra del computer (o scheda del browser) esattamente sull'elemento e sulla posizione di scorrimento dello smartphone.
- Ridimensiona la finestra dell'app su Googlebook e verifica che i contenuti ripristinati e la selezione persistano durante le transizioni tra le classi di dimensioni delle finestre.
Risorse aggiuntive
- Crea app adattive per Googlebook
- Informazioni sulla funzionalità Continua su
- Attivare e personalizzare il trasferimento cross-device
- Salvare gli stati dell'interfaccia utente