Molti dispositivi Android sono dotati di fotocamere integrate. In questo tutorial, lavoreremo attraverso la tecnica di base per catturare un'immagine usando la fotocamera Android e poi ritagliarla usando le app che l'utente ha già installato sul proprio dispositivo. Lungo il percorso, mostrerò anche come rendere conto agli utenti i cui dispositivi non supportano né l'acquisizione di immagini né le azioni di ritaglio.
Crea un nuovo progetto Android in Eclipse o l'IDE scelto. Nella tua classe di attività principale, aggiungi le seguenti istruzioni di importazione dopo la dichiarazione del pacchetto:
importare android.app.Activity; import android.content.ActivityNotFoundException; import android.content.Intent; import android.graphics.Bitmap; import android.net.Uri; importare android.os.Bundle; import android.provider.MediaStore; importa android.view.View; import android.view.View.OnClickListener; importa android.widget.Button; import android.widget.ImageView; importare android.widget.Toast;
Questi ci permetteranno di realizzare l'acquisizione, il ritaglio e la visualizzazione delle immagini all'interno dell'app. Apri il file XML delle stringhe dell'applicazione, che dovresti trovare nella cartella "res / values". Aggiungi le seguenti stringhe:
Cattura una foto da ritagliare! Immagine Avvia fotocamera
Useremo queste stringhe nell'interfaccia utente.
Progettiamo il layout dell'app. Apri il tuo file XML principale, che dovrebbe essere nella cartella "res / layout". Utilizzare un layout lineare come segue, che Eclipse potrebbe aver già fornito:
All'interno del layout lineare, aggiungi la seguente visualizzazione di testo:
Qui mostriamo del testo informativo usando una stringa che abbiamo definito nel file XML delle stringhe. Dopo la visualizzazione del testo, aggiungi un pulsante come segue:
Il valore ID ci consentirà di identificare il pulsante in Java, in modo che possiamo rispondere ai clic. Di nuovo, usiamo una stringa che abbiamo già definito in XML. Infine, dopo il pulsante, aggiungi una vista immagine:
Inseriremo l'immagine acquisita dall'utente con la fotocamera del dispositivo all'interno di questa vista immagine, utilizzando il valore dell'ID per identificarlo in Java. Usiamo una delle stringhe come descrizione del contenuto e una risorsa selezionabile per lo sfondo che creeremo in seguito. Se vuoi che la Vista immagine si allunghi per riempire lo spazio disponibile, modifica gli attributi di larghezza e altezza su "fill_parent" invece di "wrap_content" - ricorda che questo potrebbe rendere l'immagine visualizzata di scarsa qualità.
Per lo sfondo selezionabile, crea un nuovo file XML in ciascuna delle tue cartelle disegnabili dell'app, assegnandogli il nome "pic_border.xml" in modo che corrisponda al valore che abbiamo utilizzato nella sezione di layout di visualizzazione immagine. Il modo più semplice per farlo è creare il file in una cartella estraibile, copiare il codice XML, salvarlo e copiarlo nelle altre cartelle disegnabili.
Usa il seguente codice XML nel tuo nuovo file disegnabile "pic_border":
L'utilizzo di una risorsa di sfondo disegnabile è del tutto facoltativa, quindi sentitevi liberi di omettere questa parte. Ecco come apparirà l'app quando verrà lanciata:
Nella classe Attività della tua app, estendi la riga di dichiarazione della classe di apertura come segue:
public class ShootAndCropActivity estende Activity implementa OnClickListener
Modificare il nome della classe in base alle proprie esigenze. All'interno del metodo "onCreate" dell'attività, aggiungere quanto segue dopo il codice esistente chiamando il metodo superclasse e impostando il layout del contenuto, che Eclipse avrebbe dovuto compilare:
// recupera un riferimento al pulsante dell'interfaccia utente Pulsante captureBtn = (Button) findViewById (R.id.capture_btn); // Gestisci i clic del pulsante captureBtn.setOnClickListener (this);
Qui semplicemente istruiamo la classe a gestire i clic sui pulsanti. L'utente preme il pulsante per avviare la fotocamera. Ora dobbiamo fornire un metodo "onClick". Aggiungilo come segue, dopo il metodo "onCreate":
public void onClick (View v) if (v.getId () == R.id.capture_btn)
All'interno dell'istruzione "if", implementeremo utilizzando la fotocamera.
Nella parte superiore della dichiarazione della classe, prima del metodo "onCreate", aggiungi le seguenti variabili di istanza:
// tiene traccia dell'obiettivo di cattura della videocamera final int CAMERA_CAPTURE = 1; // foto catturata uri private Uri picUri;
Utilizzeremo la prima variabile per tenere traccia dell'interazione dell'utente mentre naviga verso l'app per fotocamera e viceversa. La seconda variabile memorizzerà l'URI dell'immagine acquisita. All'interno dell'istruzione "if" nel metodo "onClick", aggiungi il seguente codice per avviare l'Intent della videocamera, includendolo in un blocco "try":
prova // usa l'intento standard per catturare un'immagine Intent captureIntent = new Intent (MediaStore.ACTION_IMAGE_CAPTURE); // gestiremo i dati restituiti in onActivityResult startActivityForResult (captureIntent, CAMERA_CAPTURE);
Quando viene eseguito questo codice, l'app fotocamera dell'utente verrà avviata e sarà in grado di scattare una foto. Gestiremo l'utente che ritorna dall'app della telecamera all'interno del metodo "onActivityResult". Da lì saremo in grado di verificare che l'utente stia tornando da questo Intento usando la variabile "CAMERA_CAPTURE" che passiamo all'avvio dell'attività. Tuttavia, prima di farlo, dobbiamo gestire la situazione in cui il dispositivo dell'utente non supporta l'intento di acquisizione dell'immagine che abbiamo tentato di avviare qui. Dopo il blocco "try", aggiungi un "catch" come segue:
catch (ActivityNotFoundException anfe) // visualizza un messaggio di errore String errorMessage = "Whoops - il tuo dispositivo non supporta l'acquisizione di immagini!"; Toast toast = Toast.makeText (this, errorMessage, Toast.LENGTH_SHORT); toast.show ();
Ogni volta che provi a lanciare un Intento al di fuori della tua app, questa è una precauzione che potresti voler prendere. Questo è in particolare il caso dell'azione di ritaglio che esploreremo in seguito, tuttavia questo modello di codice è una buona abitudine da adottare in generale, poiché i dispositivi dell'utente variano notevolmente. Quando l'utente accetta la foto che ha catturato, tornerà all'app.
Abbiamo lanciato l'app per fotocamera con "startActivityForResult", quindi ora dobbiamo gestire il risultato. Aggiungi il metodo "onActivityResult" dopo il metodo "onClick" come segue:
protected void onActivityResult (int requestCode, int resultCode, Intent data) if (resultCode == RESULT_OK)
All'interno dell'istruzione "if", aggiungi un altro per verificare che stiamo tornando dall'app della telecamera, utilizzando la variabile che abbiamo passato:
// l'utente sta tornando dall'acquisizione di un'immagine utilizzando la fotocamera se (requestCode == CAMERA_CAPTURE)
Torneremo anche al metodo "onActivityResult" dopo che l'utente ritaglia la propria immagine, quindi aggiungeremo un "else if" più tardi. All'interno di questa istruzione "se", aggiungi il seguente codice per recuperare l'URI della foto acquisita:
// ottiene l'Uri per l'immagine catturata picUri = data.getData ();
Ora dobbiamo passare questo URI a un'app che può ritagliarlo. Useremo un metodo di supporto per ottenere questo, quindi aggiungi la seguente chiamata al metodo:
// esegue l'operazione di ritaglio performCrop ();
Aggiungi il metodo helper che abbiamo chiamato dopo il metodo "onActivityResult":
private void performCrop ()
All'interno di questo metodo chiameremo un Intento per eseguire il ritaglio, quindi aggiungiamo i blocchi "try" e "catch" nel caso in cui il dispositivo dell'utente non supporti l'operazione di ritaglio:
try catch (ActivityNotFoundException anfe) // visualizza un messaggio di errore String errorMessage = "Whoops - il tuo dispositivo non supporta l'azione di ritaglio!"; Toast toast = Toast.makeText (this, errorMessage, Toast.LENGTH_SHORT); toast.show ();
Usiamo la stessa tecnica che abbiamo usato quando lanciamo l'Intent della fotocamera. Se il dispositivo dell'utente non supporta l'intento di ritaglio, vedrà un messaggio di errore. All'interno del blocco "try", lancia l'Intent come segue:
// richiama l'intento di azione crop standard (il dispositivo dell'utente potrebbe non supportarlo) Intent cropIntent = new Intent ("com.android.camera.action.CROP"); // indica il tipo di immagine e Uri cropIntent.setDataAndType (picUri, "image / *"); // imposta le proprietà di ritaglio cropIntent.putExtra ("crop", "true"); // indica l'aspetto del crop crop desideratoIntent.putExtra ("aspectX", 1); cropIntent.putExtra ("aspectY", 1); // indica l'output X e Y cropIntent.putExtra ("outputX", 256); cropIntent.putExtra ("outputY", 256); // recupera i dati sul ritorno cropIntent.putExtra ("return-data", true); // avvia l'attività - gestiamo il ritorno in onActivityResult startActivityForResult (cropIntent, PIC_CROP);
Qui impostiamo varie proprietà per l'immagine ritagliata, istruendo l'app per recuperare i dati dell'immagine risultanti al termine del ritaglio. Se vuoi che le dimensioni dell'immagine ritagliate differiscano da questa, modifica le linee "outputX" e "outputY" di conseguenza. Chiamiamo l'intent usando "startActivityForResult", quindi recupereremo nuovamente il risultato all'interno di "onActivityResult". Come con l'intento della telecamera, passiamo una variabile per tenere traccia di quale Intent da cui stiamo tornando, quindi aggiungi una dichiarazione di variabile all'inizio della classe, accanto alle altre variabili di istanza:
// tiene traccia dell'intento di ritaglio finale int PIC_CROP = 2;
Oltre al ritaglio, l'utente può selezionare un'area dell'immagine.
Finalmente possiamo recuperare l'immagine ritagliata e mostrarla nell'interfaccia utente dell'app. All'interno del tuo metodo "onActivityResult", dopo l'istruzione "if" in cui controlli il codice di richiesta "CAMERA_CAPTURE", aggiungi un controllo dell'istruzione "if else" per il codice "PIC_CROP", nel qual caso torniamo dall'operazione di ritaglio :
// l'utente sta tornando dal ritaglio dell'immagine else if (requestCode == PIC_CROP)
All'interno di questa dichiarazione, possiamo recuperare l'immagine ritagliata restituita come segue:
// recupera i dati restituiti Bundle extras = data.getExtras (); // ottiene la bitmap ritagliata Bitmap thePic = extras.getParcelable ("data");
Ora abbiamo l'immagine ritagliata dall'utente come Bitmap. Mostriamolo nella vista immagine come segue:
// recupera un riferimento a ImageView ImageView picView = (ImageView) findViewById (R.id.picture); // mostra l'immagine ritagliata restituita picView.setImageBitmap (thePic);
Ora l'immagine ritagliata apparirà nell'interfaccia utente dell'app non appena l'utente tornerà dal ritaglio. Salva ed esegui la tua app su un dispositivo reale per testarlo.
In questo tutorial abbiamo esplorato il processo di acquisizione e ritaglio di base all'interno dell'SDK di Android. Tuttavia, l'azione di ritaglio in particolare può essere un po 'imprevedibile sui vari dispositivi utente in funzione. Molte app diverse possono gestire l'operazione di ritaglio, quindi alcuni sviluppatori adottano un algoritmo più complesso per risolvere le scelte dell'utente, presentando all'utente queste app come elenco di opzioni tra cui scegliere. Qualunque siano le app fornite dall'ambiente utente, il processo di base di acquisizione e ritaglio rimane lo stesso.