At integrere en kameraapplikation i en Android-applikation kræver både grundlæggende kendskab til Androids medierammeværk og forståelse for, hvordan man interagerer med en enheds hardware på en sikker og effektiv måde. Denne opskrift vil demonstrere, hvordan man bruger den standard kameraapp til at tage billeder, gemme dem i en offentlig mappe og vise dem i applikationen.

For at komme i gang skal du oprette et nyt projekt i Android Studio og navngive det "UsingTheDefaultCameraApp". Vælg standardmulighederne for telefoner og tablets og vælg "Empty Activity", når du bliver bedt om at vælge en aktivitetstype.

Opsætning af projektet

Start med at oprette en layoutfil, der indeholder et ImageView og en knap. Denne knap vil udløse en Intent for at starte den standard kameraapp. Når kameraappen er færdig, vil applikationen få et callback.

  1. Manifestfilen: Åbn AndroidManifest.xml og tilføj følgende tilladelser:

    xml
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  2. Layoutet: Åbn activity_main.xml og erstat den eksisterende TextView med følgende views:

    xml
    <Button
    android:id="@+id/take_picture_button" android:text="Tag billede" android:onClick="takePicture" /> <ImageView android:id="@+id/image_view" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
  3. Java-koden: I MainActivity.java tilføj de følgende globale variabler:

    java
    final int PHOTO_RESULT = 1;
    private Uri mLastPhotoURI = null;
  4. Opret fil-URI: Tilføj en metode til at generere en URI for det billede, der skal gemmes:

    java
    private Uri createFileURI() { String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(System.currentTimeMillis());
    String fileName = "PHOTO_" + timeStamp + ".jpg";
    return Uri.fromFile(new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), fileName)); }
  5. Knapklik-metode: Tilføj en metode, der håndterer klik på knappen:

    java
    public void takePicture(View view) {
    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); if (takePictureIntent.resolveActivity(getPackageManager()) != null) { mLastPhotoURI = createFileURI(); takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, mLastPhotoURI); startActivityForResult(takePictureIntent, PHOTO_RESULT); } }
  6. Håndtering af resultater: Overskriv onActivityResult()-metoden for at hente og vise det billede, der er taget:

    java
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == PHOTO_RESULT && resultCode == RESULT_OK) { mImageView.setImageBitmap(BitmapFactory.decodeFile(mLastPhotoURI.getPath())); } }

Når du har implementeret disse trin, kan du køre applikationen på en enhed eller emulator.

Hvordan det fungerer

Der er to hoveddele ved at arbejde med den standard kameraapp: opsætning af Intent for at starte appen, og håndtering af det billede, der tages. Først opretter vi en Intent ved at bruge MediaStore.ACTION_IMAGE_CAPTURE, som specificerer, at vi vil tage et billede. Vi tjekker, om der findes en passende app til at håndtere denne Intent ved at bruge resolveActivity(). Hvis resultatet ikke er null, ved vi, at en app er tilgængelig. Herefter opretter vi et filnavn og tilføjer det til Intent'en med putExtra(MediaStore.EXTRA_OUTPUT, mLastPhotoURI).

Når vi får callback'et i onActivityResult(), tjekker vi først, om det er resultatet af vores fotohandling og om resultatet er OK (brugeren kunne have annulleret). Hvis det er et billede, indlæses det i ImageView'et.

Yderligere muligheder

Hvis du ikke er bekymret for, hvor billedet gemmes, kan du udelade MediaStore.EXTRA_OUTPUT og lade systemet håndtere lagringen af billedet. I så fald vil callback'et i onActivityResult() indeholde et billede-thumbnail, som du kan vise i applikationen:

java
if (data != null) { imageView.setImageBitmap((Bitmap) data.getExtras().get("data")); }

For at vise hele billedets opløsning kan du bruge URI'en, der returneres i data Intent, som vist her:

java
if (data != null) {
try { imageView.setImageBitmap( MediaStore.Images.Media.getBitmap(getContentResolver(), Uri.parse(data.toUri(Intent.URI_ALLOW_UNSAFE)))); } catch (IOException e) { e.printStackTrace(); } }

Videooptagelse

Hvis du ønsker at optage video i stedet for at tage billeder, skal du blot ændre Intent'en som følger:

java
Intent takeVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);

Derefter kan du hente URI'en til videoen i onActivityResult():

java
Uri videoUri = intent.getData();

Det gamle Kamera-API

Den beskrevne opskrift viser, hvordan man bruger en Intent til at starte den standard kameraapp. Hvis du har brug for mere kontrol over kameraet, kan du bruge Android's Camera API. Denne metode giver dig mulighed for at interagere direkte med kameraets hardware.

Der findes to versioner af Camera API'en: den originale Camera API, der blev introduceret i Android 1.0 (API 1), og den nyere Camera2 API, som blev introduceret i Android 5.0 (API 21). Selvom det er ideelt at bruge den nyeste API for at udnytte de nyeste funktioner, skal man være opmærksom på, at Camera2 API'en kun udgør ca. 23 procent af markedet. Derfor kan det være nødvendigt at understøtte begge API'er for at sikre, at applikationen fungerer på de fleste enheder.

En vigtig funktion ved at bruge Camera2 API'en er muligheden for at bruge TextureView i stedet for den traditionelle SurfaceView. TextureView blev introduceret i Android 4.0 (API 14), og det gør det muligt at vise kameraets live preview på en mere fleksibel måde.

Konklusion

At bruge den standard kameraapp på Android giver en effektiv og simpel måde at integrere kamerafunktionalitet i din applikation. Det giver hurtigt adgang til en funktion, som de fleste brugere allerede er bekendt med, samtidig med at det gør det muligt at gemme og vise billeder i applikationen. For mere avanceret kontrol over kameraet kan du overveje at bruge Camera2 API, men vær opmærksom på at tilpasse din app til at understøtte både den gamle og den nye API afhængigt af brugerens enhed.

Hvordan implementere Google Cloud Messaging (GCM) og Google Sign-In i din Android-app

For at kunne bruge Google Cloud Messaging (GCM) i din Android-applikation, er der flere vigtige trin, som du skal følge for at sikre, at applikationen fungerer korrekt og er i stand til at modtage beskeder fra serveren. GCM er en effektiv løsning til at sende push-beskeder til brugernes enheder, men kræver en række services, som alle arbejder sammen. GCM kræver, at du opretter flere klasser og opretter forbindelser til Googles API'er.

Først og fremmest skal du registrere din app med GCM-serveren. Det gøres ved at bruge InstanceID-klassen for at hente en enhedstoken. Denne token bruges til at identificere enheden og muliggøre kommunikation med serveren. Den nødvendige kode til at registrere applikationen ser sådan ud:

java
InstanceID instanceID = InstanceID.getInstance(this); String token = instanceID.getToken( getString(R.string.gcm_defaultSenderId), GoogleCloudMessaging.INSTANCE_ID_SCOPE, null); Log.i("GCMRegistrationService", "GCM Registration Token: " + token);

Dette gøres dog ikke direkte i aktiviteten, fordi kaldet til getToken() kan blokere UI-tråden. I stedet oprettes en separat service, GCMRegistrationService, som håndterer denne opgave i en baggrundstråd. Her er koden for at oprette denne service:

java
public class GCMRegistrationService extends IntentService {
private final String SENT_TOKEN = "SENT_TOKEN"; public GCMRegistrationService() { super("GCMRegistrationService"); } @Override
protected void onHandleIntent(Intent intent) {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); try { InstanceID instanceID = InstanceID.getInstance(this); String token = instanceID.getToken( getString(R.string.gcm_defaultSenderId), GoogleCloudMessaging.INSTANCE_ID_SCOPE, null); Log.i("GCMRegistrationService", "GCM Registration Token: " + token); sharedPreferences.edit().putBoolean(SENT_TOKEN, true).apply(); } catch (Exception e) { sharedPreferences.edit().putBoolean(SENT_TOKEN, false).apply(); } } }

Denne service registrerer appen med GCM-serveren og gemmer status for token-sendingen i SharedPreferences.

Når registreringen er fuldført, er den næste vigtige komponent GCMService, som håndterer modtagelsen af push-beskeder. Denne service skal udvide GcmListenerService og overskrive metoden onMessageReceived() for at reagere på modtagne beskeder:

java
public class GCMService extends GcmListenerService { @Override
public void onMessageReceived(String from, Bundle data) {
super.onMessageReceived(from, data); Log.i("GCMService", "onMessageReceived(): " + data.toString()); } }

En anden vigtig service, der skal oprettes, er GCMInstanceService, som udvider InstanceIDListenerService. Denne service lytter efter opdateringer til enhedens GCM-token og genstarter registreringen, hvis det er nødvendigt:

java
public class GCMInstanceService extends InstanceIDListenerService { @Override public void onTokenRefresh() { Intent intent = new Intent(this, GCMRegistrationService.class); startService(intent); } }

Når GCM-registreringen er sat op, er det nødvendigt at tilføje en metode til at kontrollere, om Google Play Services er tilgængelige på enheden. Denne kontrol er vigtig for at sikre, at din app kan bruge GCM-funktionaliteten korrekt. Hvis Play Services ikke er tilgængelige, skal du vise en fejlmeddelelse til brugeren:

java
private boolean isGooglePlayServicesAvailable() { GoogleApiAvailability googleApiAvailability = GoogleApiAvailability.getInstance();
int resultCode = googleApiAvailability.isGooglePlayServicesAvailable(this);
if (resultCode != ConnectionResult.SUCCESS) { if (googleApiAvailability.isUserResolvableError(resultCode)) { googleApiAvailability.getErrorDialog(this, resultCode, PLAY_SERVICES_RESOLUTION_REQUEST).show(); } else { Toast.makeText(MainActivity.this, "Unsupported Device", Toast.LENGTH_SHORT).show(); finish(); } return false; } return true; }

Når du har implementeret denne metode, kan du ændre onCreate()-metoden til først at kontrollere, om Play Services er tilgængelige, før du starter GCM-registrering:

java
if (isGooglePlayServicesAvailable()) { Intent intent = new Intent(this, GCMRegistrationService.class); startService(intent); }

For at teste din GCM-implementering kan du bruge en app kaldet "GCM (Push Notification) Tester", som kan downloades fra Google Play Store. Denne app giver dig mulighed for at teste, om din app korrekt modtager push-beskeder.

Udover GCM, kan du også implementere Google Sign-In i din app, så brugerne nemt kan logge ind med deres Google-konto. Denne funktion kræver, at du opretter et Google Services-konfigurationsfil fra Google Developer Console og tilføjer den til dit projekt. Sørg også for at tilføje de nødvendige afhængigheder i din build.gradle-fil og opdatere din app med de korrekte oplysninger.

Det er vigtigt at forstå, at GCM, som beskrevet her, kræver flere tjenester og klasser, der arbejder sammen. Selvom meget af arbejdet håndteres af Googles API'er, er det nødvendigt at oprette og konfigurere disse tjenester korrekt. Fejl i registreringsprocessen eller i håndteringen af beskeder kan føre til, at din app ikke modtager push-beskeder korrekt. Derfor bør du teste og verificere din implementation grundigt på både fysiske enheder og emulatorer for at sikre, at alt fungerer som forventet.