API per Android 4.2

Livello API: 17

Android 4.2 (JELLY_BEAN_MR1) è un aggiornamento della release Jelly Bean che offre nuove funzionalità per utenti e app sviluppatori. Questo documento fornisce un'introduzione alle nuove e utili API per gli sviluppatori.

In qualità di sviluppatore di app, devi scaricare l'immagine di sistema Android 4.2 e la piattaforma SDK dalla pagina SDK Manager il prima possibile. Se Se non disponi di un dispositivo con Android 4.2 su cui testare la tua app, utilizza il sistema Android 4.2 per testare la tua app nell'emulatore Android. Quindi crea le tue app sulla base della piattaforma Android 4.2 per iniziare a utilizzare le API più recenti.

Per ottimizzare meglio la tua app per i dispositivi con Android 4.2, devi impostare targetSdkVersion su "17", installalo su un'immagine di sistema Android 4.2, testarlo, quindi pubblicare un aggiornamento con questa modifica.

Tu possono utilizzare le API in Android 4.2 supportando al contempo le versioni precedenti aggiungendo condizioni al codice che controllano il livello API di sistema prima di eseguirlo API non supportate dal tuo minSdkVersion. Per scoprire di più su mantenendo la compatibilità con le versioni precedenti, leggi l'articolo Creazione di una compatibilità con le versioni precedenti UI.

Ulteriori informazioni su come funzionano i livelli API sono disponibili nella pagina Che cos'è l'API Livello?

Importanti cambiamenti del comportamento

Se hai già pubblicato un'app per Android, tieni presente quanto segue modifiche che potrebbero influire sul comportamento della tua app:

  • I fornitori di contenuti non vengono più esportati per impostazione predefinita. Vale a dire, il valore predefinito dell'attributo android:exported ora è “false". Se è importante che altre app siano in grado di accedere al tuo fornitore di contenuti, devi impostare esplicitamente android:exported="true".

    Questa modifica ha effetto solo se imposti android:targetSdkVersion o android:minSdkVersion su 17 o superiore. In caso contrario, il valore predefinito è sempre “true" anche con Android 4.2 e versioni successive.

  • Rispetto alle versioni precedenti di Android, i risultati relativi alla posizione dell'utente potrebbero essere meno precisi se la tua app richiede l'autorizzazione ACCESS_COARSE_LOCATION, ma non richiede l'autorizzazione ACCESS_FINE_LOCATION.

    Per soddisfare le aspettative in materia di privacy degli utenti quando la tua app richiede l'autorizzazione per posizione approssimativa (e non precisa), il sistema non fornirà una stima della posizione dell'utente. è più precisa rispetto a un isolato.

  • Alcune impostazioni del dispositivo definite da Settings.System sono ora di sola lettura. Se la tua app tenta di scrivere modifiche alle impostazioni definite in Settings.System che sono state spostate in Settings.Global, l'operazione di scrittura non riuscirà in modo invisibile su Android 4.2 e versioni successive.

    Anche se il valore di android:targetSdkVersion e android:minSdkVersion è inferiore a 17, la tua app non può modificare le impostazioni con spostato in Settings.Global con Android 4.2 e versioni successive.

  • Se la tua app utilizza WebView, Android 4.2 aggiunge un ulteriore livello di in modo da poter associare più sicuro JavaScript al tuo Codice Android. Se imposti targetSdkVersion a 17 o superiore, devi aggiungere l'annotazione @JavascriptInterface a qualsiasi metodo disponibile per il codice JavaScript (anche il metodo deve essere pubblico). Se non fornisci il il metodo non è accessibile da una pagina web in WebView con Android 4.2 o versioni successive. Se imposti il parametro targetSdkVersion alla 16 o a una versione precedente, l'annotazione non è obbligatoria, ma ti consigliamo di aggiornare la versione di destinazione e aggiungi l'annotazione per maggiore sicurezza.

    Scopri di più sull'associazione da codice JavaScript a codice Android.

Daydream

Daydream è una nuova modalità salvaschermo interattiva per dispositivi Android. Si attiva automaticamente quando il dispositivo è inserito in un dock o quando rimane inattivo mentre è collegato a una base caricabatteria (invece di spegnere lo schermo). Daydream mostra un sogno alla volta e questo potrebbe essere un display passivo e puramente visivo che si spegne al tocco o che può essere interattivo e reattivo all'intera suite di eventi di input. I tuoi sogni vengono inseriti nel processo della tua app e hanno accesso completo il toolkit per la UI di Android, che comprende visualizzazioni, layout e animazioni, in modo da essere più flessibili potente degli sfondi animati o dei widget di app.

Puoi creare un sogno per Daydream implementando una sottoclasse DreamService. Le API di DreamService sono progettati per essere simili a quelli di Activity. Per specificare l'UI per Inoltre, passa un ID risorsa di layout o View a setContentView() in qualsiasi momento, dopo aver una finestra, ad esempio da onAttachedToWindow() di Google.

Il corso DreamService fornisce altri importanti callback del ciclo di vita basati sulle API Service di base, come onDreamingStarted(), onDreamingStopped() e onDetachedFromWindow(). Non puoi avviare una richiesta DreamService dal tuo viene avviata automaticamente dal sistema.

Se il tuo sogno è interattivo, puoi avviare un'attività da quel sogno per indirizzare l'utente all'UI completa dell'app per maggiori dettagli o controlli. Puoi usare finish() per terminare il tuo sogno in modo che l'utente possa vedere nuova attività.

Per rendere disponibile daydream al sistema, dichiara il tuo DreamService con un elemento <service> nel file manifest. Devi quindi includere un filtro per intent con l'azione "android.service.dreams.DreamService". Ad esempio:

<service android:name=".MyDream" android:exported="true"
    android:icon="@drawable/dream_icon" android:label="@string/dream_label" >
    <intent-filter>
        <action android:name="android.service.dreams.DreamService" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</service>

Esistono altri metodi utili in DreamService tieni presente:

  • setInteractive(boolean) stabilisce se il sogno riceve eventi di input o uscite immediatamente dopo l'input dell'utente. Se il tuo sogno interattivo, l'utente può utilizzare i pulsanti Indietro o Home per uscire dalla modalità sogno oppure puoi chiamare finish() per fermare il tuo sogno.
  • Se vuoi un display completamente immersivo, puoi chiamare setFullscreen() per nascondere la barra di stato.
  • Prima dell'avvio di Daydream, la luminosità del display si attenua per segnalare all'utente che il timeout per inattività si sta avvicinando. Se chiami setScreenBright(true) puoi invece impostare il display alla luminosità abituale.

Per saperne di più, consulta la documentazione di DreamService.

Display secondari

Android ora consente alla tua app di mostrare contenuti esclusivi su schermate aggiuntive collegate al dispositivo dell'utente tramite una connessione cablata o Wi-Fi. Per creare contenuti unici per un display secondario, estendi le Presentation e implementare il callback onCreate(). Entro onCreate(), specifica la tua UI per il display secondario chiamando il numero setContentView(). Essendo un'estensione della classe Dialog, la classe Presentation fornisce la regione in cui l'app può visualizzare una UI unica sul display secondario.

Per rilevare display secondari dove puoi mostrare il tuo Presentation: usa DisplayManager o MediaRouter su quelle di livello inferiore. Sebbene le API DisplayManager ti consentano di enumerare più display che possono essere collegati contemporaneamente, di solito dovresti usare MediaRouter per accedere rapidamente alla visualizzazione predefinita del sistema per presentazioni.

Per ottenere la visualizzazione predefinita per la tua presentazione, chiama MediaRouter.getSelectedRoute() e superala ROUTE_TYPE_LIVE_VIDEO. Restituisce un oggetto MediaRouter.RouteInfo che descrive la route attualmente selezionata dal sistema per le presentazioni video. Se MediaRouter.RouteInfo non è null, richiama getPresentationDisplay() per visualizzare il Display che rappresenta il display connesso.

Potrai quindi visualizzare la presentazione passando l'oggetto Display a un costruttore per il corso Presentation. La presentazione ora vengono visualizzati sul display secondario.

Per rilevare in fase di esecuzione la connessione di un nuovo display, crea un'istanza di MediaRouter.SimpleCallback in cui implementi il metodo di callback onRoutePresentationDisplayChanged(), che il sistema chiamerà quando un nuovo è collegato il display della presentazione. Poi registra il valore MediaRouter.SimpleCallback passandolo a MediaRouter.addCallback() insieme al tipo di percorso ROUTE_TYPE_LIVE_VIDEO. Quando ricevi una chiamata a onRoutePresentationDisplayChanged(), chiama MediaRouter.getSelectedRoute() come indicato sopra.

Per ottimizzare ulteriormente l'UI in Presentation per schermate secondarie, puoi applicare un tema diverso specificando l'attributo android:presentationTheme in <style> che hai applicati alla tua applicazione o alla tua attività.

Tieni presente che gli schermi collegati al dispositivo dell'utente spesso hanno schermi di dimensioni maggiori e potrebbe avere una densità dello schermo diversa. Poiché le caratteristiche dello schermo possono essere diverse, offrono risorse ottimizzate specificatamente per questi schermi più grandi. Se hai bisogno per richiedere risorse aggiuntive da Presentation, chiama getContext().getResources() per ottenere l'oggetto Resources corrispondente al display. Ciò fornisce le risorse della tua app più adatte dimensioni e densità dello schermo secondario.

Per ulteriori informazioni e alcuni esempi di codice, consulta la Presentation documentazione del corso.

Widget schermata di blocco

Android ora consente agli utenti di aggiungere widget delle app alla schermata di blocco. Per rendere disponibile l'App Widget per l'utilizzo nella schermata di blocco, aggiungi l'attributo android:widgetCategory al tuo file XML che specifica AppWidgetProviderInfo. Questo attributo supporta due valori: home_screen e keyguard. Per impostazione predefinita, l'attributo è impostato su home_screen, quindi gli utenti possono aggiungere il tuo widget dell'app alla schermata Home. Se vuoi che il widget dell'app sia disponibile anche sulla serratura schermata, aggiungi il valore keyguard:

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    ...
    android:widgetCategory="keyguard|home_screen">
</appwidget-provider>

Devi anche specificare un layout iniziale per il widget dell'app quando ti trovi nella schermata di blocco con l'attributo android:initialKeyguardLayout. Funziona allo stesso modo di android:initialLayout, in quanto fornisce un layout che possa essere visualizzato immediatamente fino a quando il widget dell'app non viene inizializzato e può aggiornare il layout.

Per ulteriori informazioni sulla creazione di widget di app per la schermata di blocco, incluse le istruzioni per Dimensioni del widget dell'app quando ti trovi nella schermata di blocco, consulta la guida Widget app.

Più utenti

Android ora consente più spazi utente su dispositivi condivisibili come i tablet. Ogni utente su dispositivo dispone di un proprio insieme di account, app, impostazioni di sistema, file e dati associati all'utente.

In qualità di sviluppatore di app, non devi fare nulla per far funzionare la tua app in modo adeguato con più utenti su un unico dispositivo. Indipendentemente dal numero di utenti che possono esistere dispositivo, i dati salvati dall'app per un determinato utente vengono mantenuti separati da quelli salvati dall'app per altri utenti. Il sistema tiene traccia di quali dati utente appartengono al processo utente in cui che l'app sia in esecuzione, che fornisce l'accesso all'app solo ai dati di quell'utente e non consente l'accesso ai dati di altri utenti.

Salvataggio dei dati in un ambiente multiutente

Ogni volta che l'app salva le preferenze dell'utente, crea un database o scrive un file di archiviazione interna o esterna, i dati sono accessibili solo mentre l'utente è in esecuzione.

Per assicurarti che l'app funzioni correttamente in un ambiente multiutente, non fare riferimento alle la directory interna dell'app o la posizione di archiviazione esterna usando percorsi hardcoded e usa sempre le API appropriate:

Indipendentemente dall'API che utilizzi per salvare i dati di un determinato utente, i dati non verranno accessibili durante l'esecuzione come altro utente. Dal punto di vista della tua app, ogni utente è in esecuzione su un dispositivo completamente separato.

Identificare gli utenti in un ambiente multiutente

Se la tua app vuole identificare utenti unici, ad esempio per raccogliere dati e analisi o creare un altro account associazioni, devi seguire le pratiche consigliate per identificare per le installazioni uniche. Creando una nuova UUID all'avvio dell'app per la prima volta, avrai la certezza di ottenere un ID univoco per il monitoraggio di ogni utente, indipendentemente dal numero Gli utenti installano la tua app su un singolo dispositivo. In alternativa, puoi salvare un token locale recuperato da il tuo server o utilizza l'ID di registrazione fornito da Google Cloud Messaging.

Tieni presente che se la tua app richiede uno degli identificatori del dispositivo hardware (ad esempio l'indirizzo MAC Wi-Fi) indirizzo IP o il numero di SERIAL), forniscono lo stesso valore per ogni perché questi identificatori sono legati all'hardware e non all'utente. Per non parlare dell'altro i problemi presentati da questi identificatori, come discusso nel documento Post del blog sulle installazioni di app.

Nuove impostazioni globali

Le impostazioni di sistema sono state aggiornate per supportare più utenti con l'aggiunta di Settings.Global. Questa raccolta di impostazioni è simile alle impostazioni di Settings.Secure perché sono di sola lettura, ma viene applicata a livello globale in tutti gli spazi utente sul dispositivo.

Diverse impostazioni esistenti sono state spostate qui da Settings.System o Settings.Secure. Se la tua app è al momento apporta modifiche alle impostazioni definite in precedenza in Settings.System (ad es. AIRPLANE_MODE_ON), dovresti aspettarti che questa operazione non funzionerà più su un dispositivo con Android 4.2 o versioni successive se tali impostazioni sono spostato in Settings.Global. Puoi continuare a leggere le impostazioni in Settings.Global, ma poiché le impostazioni non sono più considerate sicure di modificare le app, se provi a farlo non riuscirai in automatico e il sistema scriverà un avviso Il log di sistema quando esegui l'app su Android 4.2 o versioni successive.

Supporto layout RTL

Android ora offre diverse API che ti consentono di creare interfacce utente con trasformare l'orientamento del layout per supportare le lingue che utilizzano interfacce utente da destra a sinistra (RTL) e per la lettura come l'arabo e l'ebraico.

Per iniziare a supportare i layout RTL nella tua app, imposta l'attributo android:supportsRtl sull'elemento <application> nel file manifest e imposta il valore “true". Una volta abilitata, il sistema abiliterà varie API RTL per visualizzare la tua app con i layout RTL. Ad esempio, la barra delle azioni mostrerà l'icona e il titolo sul lato destro e i pulsanti di azione a sinistra ed eventuali layout creati con il verranno invertiti anche i corsi View forniti dal framework.

Se hai bisogno di ottimizzare ulteriormente l'aspetto della tua app quando viene visualizzata con un layout RTL, esistono due livelli base di ottimizzazione:

  1. Conversione delle proprietà di layout orientate a sinistra e a destra in layout orientati all'inizio e alla fine proprietà.

    Ad esempio, usa android:layout_marginStart invece di android:layout_marginLeft e android:layout_marginEnd al posto di android:layout_marginRight.

    La classe RelativeLayout fornisce anche il layout corrispondente per sostituire le posizioni sinistra/destra, ad esempio android:layout_alignParentStart a sostituisci android:layout_alignParentLeft e android:layout_toStartOf anziché android:layout_toLeftOf.

  2. In alternativa, per ottimizzare completamente i layout RTL, puoi fornire dati file di layout utilizzando il qualificatore di risorse ldrtl (ldrtl è l'acronimo di direzione-layout-da-destra a sinistra}). Ad esempio, puoi salvare i file di layout predefiniti res/layout/ e i tuoi layout ottimizzati per RTL in res/layout-ldrtl/.

    Il qualificatore ldrtl è ottimo per le risorse disabili, in modo che tu possa fornire grafici che sono orientati nella direzione corrispondente alla direzione di lettura.

Nel framework sono disponibili varie altre API per supportare i layout RTL, ad esempio in la classe View in modo che tu possa implementare i comportamenti corretti per viste e in Configuration per eseguire query sulla direzione del layout corrente.

Nota:se utilizzi SQlite e i nomi di tabelle o colonne sono "solo numero" essere attenzione: l'utilizzo di String.format(String, Object...) può causare errori in cui i numeri sono state convertite nella lingua araba se il dispositivo è stato impostato sulla lingua araba. Devi utilizzare String.format(Locale,String,Object...) per assicurarti che i numeri vengano e mantenuto come ASCII. Usa anche String.format("%d", int) anziché usare String.valueOf(int) per formattare i numeri.

Frammenti nidificati

Ora puoi incorporare frammenti all'interno di altri. Ciò è utile per diverse situazioni inserire componenti dell'interfaccia utente dinamici e riutilizzabili in un componente dell'interfaccia utente stesso dinamiche e riutilizzabili. Ad esempio, se utilizzi ViewPager per creare frammenti che scorrono verso sinistra e destra e occupano gran parte dello spazio sullo schermo, ora inserisci i frammenti in ogni pagina dei frammenti.

Per nidificare un frammento, richiama semplicemente getChildFragmentManager() su Fragment in cui vuoi aggiungere un frammento. Viene restituito un FragmentManager che puoi utilizzare come fai normalmente dall'attività di primo livello per creare transazioni di frammento. Ad esempio, ecco del codice che aggiunge un frammento dall'interno un corso Fragment esistente:

Kotlin

val videoFragment = VideoPlayerFragment()
childFragmentManager.beginTransaction().apply {
    add(R.id.video_fragment, videoFragment)
    commit()
}

Java

Fragment videoFragment = new VideoPlayerFragment();
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction.add(R.id.video_fragment, videoFragment).commit();

Dall'interno di un frammento nidificato, puoi ottenere un riferimento al frammento padre richiamando getParentFragment().

Android Support Library ora supporta anche i frammenti nidificati, in modo da poter implementare progetti di frammenti su Android 1.6 e versioni successive.

Nota: non puoi gonfiare un layout in un frammento quando tale layout include un <fragment>. I frammenti nidificati sono supportati solo se aggiunti a in modo dinamico.

Script di rendering

La funzionalità di calcolo di Renderscript è stata migliorata con le seguenti funzionalità:

Funzionalità intrinseche dello script

Puoi usare le funzionalità intrinseche degli script integrati di Renderscript che implementano operazioni comuni per te, ad esempio:

Per utilizzare uno script intrinseco, chiama il metodo create() statico di ogni per creare un'istanza dello script. Quindi chiamerai il set() disponibile metodi di ogni script intrinseco per impostare gli input e le opzioni necessari. Infine, chiama forEach() per eseguire lo script.

Gruppi di script

Gli ScriptGroup ti consentono di collegare il Renderscript correlato script ed eseguirli con una sola chiamata.

Utilizza un ScriptGroup.Builder per aggiungere tutti gli script al gruppo chiamando il numero addKernel(). Una volta aggiungere tutti gli script, creare le connessioni tra script chiamando addConnection(). Quando hai finito di aggiungere i collegamenti, chiama create() per creare il gruppo di script. Prima di eseguire il gruppo di script, specifica l'input Allocation e script iniziale da eseguire con setInput(Script.KernelID, Allocation) e fornirà l'output Allocation in cui verrà scritto il risultato e lo script finale in eseguito con setOutput(). Infine, richiama execute() per eseguire il gruppo di script.

Script filtro

Filtro Script definisce i vincoli sulle API Renderscript esistenti che consentono l'esecuzione del codice risultante su una gamma più ampia di processori (CPU, GPU e DSP). Per creare fileFilterscript, crea .fs anziché .rs e specifica #pragma rs_fp_relaxed per indicare al runtime di Renderscript che i tuoi script non richiedono una precisione rigorosa in virgola mobile IEEE 754-2008. Questa precisione consente il flush-to-zero dei denormi e l'arrotondamento verso lo zero. Inoltre, il Filtro Script gli script non devono utilizzare tipi integrati a 32 bit e devono specificare una funzione root personalizzata mediante il metodo Attributo __attribute__((kernel)) perché non supporta i cursori, che non sono supportati definita dalla firma predefinita della funzione root().

Nota. Sebbene il supporto di Filtroscript sia disponibile solo sulla piattaforma, gli sviluppatori sarà disponibile nella versione 21.0.1 di SDK Tools.

Per una visualizzazione dettagliata di tutte le modifiche API in Android 4.2, vedi Report Differenze API.