Android – HowTo Intent Service

Was ist ein IntentService?

Ein Intent Service ist eine abgekapselte Art des Services. Viel kleiner und schlankter als der ServiceLayer und somit einfacher zu bedienen.

Wozu benötige ich einen IntentService?

Der IntentService wird benötigt um z.B. einfache Downloads bzw. Uploads zu starten. Wenn nur eine Aktion ausgeführt werden soll ohne die Activity zu verlassen. z.B. Downloaden von Bibiliotheken, Bilder oder ähnlichen Aktionen ohne die Applikation dabei zu verlassen. Der Service wird beendet sobald onPause oder onStop ausgeführt wird.

Wie setzte ich einen IntentService ein / HowTo Setup an IntentService?

Prepare ActivityView

Um einen IntentService aufrufen zu können benötigt man relativ wenig Vorbereitung. Da der Service nur gebunden zu einer Activity aufgerufen werden kann wird er ähnlich einer Activity gestartet.

Es können dem Service per Extra werte übergeben werden die anschließend ausgelesen werden.

Intent intent = new Intent(this, IntentTestService.class);
intent.putExtra(IntentTestService.EXTRA_TEST,"test");
startService(intent);

 

Prepare IntentService

 

package de.good.study.app.android.service;

import android.app.Activity;
import android.app.IntentService;
import android.content.Intent;
import android.util.Log;

/**
 * Created by jkoeber on 06.03.14.
 */
public class IntentTestService extends IntentService {
    private static final String CLASS_NAME = IntentTestService .class.getName();
    public static final String CUSTOM_INTENT = IntentTestService .class.getName()+".Receiver";
    public static final String RESULT = "serviceResult";
    public static final String STATUS = "serviceStatus";
    public static final int STATE_FINAL = 20;

    public DatabaseService() {
        super("IntentTestService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        int i = 0;

        Log.i(CLASS_NAME,"==> Service Started!");
        long endTime = 2*1000;
        while (i < STATE_FINAL) {
            synchronized (this) {
                try {
                    i += 1;
                    publishStatus(i);
                    wait(endTime);
                } catch (Exception e) {
                    Log.e(this.getClass().getName(),"Error by executing the service");
                }
            }
        }
    }

    /**
     * publish status
     * @param status
     */
    private void publishStatus(int status) {
        Intent intent = new Intent(CUSTOM_INTENT);
        intent.putExtra(STATUS, status);

        if(status == STATE_FINAL) {
            intent.putExtra(RESULT, Activity.RESULT_OK);
        } else {
            intent.putExtra(RESULT, Activity.RESULT_CANCELED);
        }

        sendBroadcast(intent);
    }
}

 

Response konsumieren

 

Die Activity kann anschließend den Response vom Service verarbeiten und abfangen über einen BroadcastListener. Hier ein Beispiel

    /**
     * BroadcastReceiver will execute IntentService and handle Reponse
     */
    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Bundle bundle = intent.getExtras();
            Log.i(CLASS_NAME,"Receive from Broadcast!");
            if (bundle != null) {
                int resultCode = bundle.getInt(IntentTestService.RESULT);
                int resultStatus = bundle.getInt(IntentTestService.STATUS);

                mProgressbar.setProgress(resultStatus);
                if (resultCode == RESULT_OK) {
                    Log.i(CLASS_NAME, "RESULT IS 100%, redirect to next Activity!");
                    Intent overviewIntent = new Intent(MainActivity.this, NextActivity.class);
                    startActivity(overviewIntent);
                }
            }
        }
    };

Nischenprodukt Phablet, Trendprodukt Tablet

Phablets

Der Trend zum Mix aus Tablet und Smarphone ist angelaufen. Ich gehe davon aus das es ein Nischenprodukt wird wenn es nicht bald die passenden Gadget dazu gibt. Zum einen ist ein Phablet nicht nur störend im Transport so ist es auch wirklich umständlich damit zu telefonieren. Oder sollte ich sagen, noch zu telefonieren?

Bei Apple wird auf eine Smartwatch getippt die ein Kommunikationsgadget zwischen Smartphone und Uhr sein soll. Ein Informationstool um nicht alle 10Minuten in seiner Hosentasche zu wühlen oder die Handtasche nach dem Smartphone zu durchforsten.

Auch andere Startups die auf Kickstarter finanziert wurden sind mittlerweile in Serienproduktion gegangen. z.b. Projekt Pebble. Eine Smartwatch die als Allround Gadget angeboten wird. Sie ist wasser- und kratzfest und wird per Bluetooth ans Smartphone gekoppelt.

Mit einer Smartwatch am Handgelenk und der Kombination zum Phablet wäre es ganz interessant ein leistungsstarkes Smartphone mit großem und hochauflösendem Display in  der Tasche zu tragen. Somit hätte ich nur ein Gerät am Mann zum lesen und kommunizieren und ein, nicht störendes Gadget am Handgelenk das die meisten ohnehin in analoger Form tragen.

Fazit meinerseits. Phablet, kann ein tolles Produkt werden und seine Nische finden wenn man die passenden Gadget dazu entwickelt und das Produkt nicht alleine sterben lässt. Ich würde dem ganzen noch 1-2 Generationen Zeit lassen bis passende Komponenten dafür entwickelt wurden und auch die Technik der 5-7 Zoll Geräte ausgereifter ist. Was bei mir zum größten Teil vor allem mit Akkulaufzeit und Gesamtgewicht zu tun hat.

 

Tablets

werden mehr und mehr zum Massenprodukt. Immer mehr löst das schlanke, meistens langlaufende Gerät den heimischen Desktop oder sogar schon das Notebook ab. Spielekonsolen werden immer nebensächlicher zugunsten der Gelegenheitsspiele die man auch auf dem Tablet tätigen kann und auch als Secondscreengerät wird das Tablet immer interessanter.

Social Communities scheren derzeit Unmengen Nutzer um sich. Egal ob es um Bewertungen von TV Shows geht oder um ChekIns zu Fernsehprogrammen. Kleine Apps wie waydoo oder getglue die ein Secondscreen Erlebnis Realtime publizieren. Egal zu welchem Ereignis oder welcher Sendung kann ich meine Meinung auf Waydoo kundtun und mit den Mitgliedern der Community kommunizieren. Das ganze zumeist Realtime auf der Couch während die Sendung läuft.

Der klassische Reader für Ebooks mit EInk Oberfläche wird sich zwar halten aber immer mehr Nutzer laden sich parallel auch auf ihr Tablet die Amazon App um ihre Bücher unterwegs zu genießen. Oder im Dunklen 😉

Nachrichten, Kochen, Suchen, Shoppen und vieles mehr ist doch einfach schöner auf dem Tablet zu erledigen als am heimischen Notebook. Ich bin schneller, benötige weniger Platz fürs Gerät und kann das Tablet in der Kochnische noch zwischen den Zutaten platzieren ohne das ich lästigen Papiermüll produziere. Ist das nicht toll? … Ich denke schon und ich denke auch das es immer mehr geben wird die über die neuen Generationen der Tablets mit ankoppelbarer Tastatur und Co. nutzen werden als Multimediaplattform und das alte Notebook im Schrank verstauen werden.

Fazit. Nicht mal mehr eine Generation und die Tablets erfüllen endlich einen Zweck. Mit vernünftigen Apps können sie sowohl Multimediaspielzeug als auch Arbeitsmittel sein. Nicht nur für den alltäglichen nebensächlichen Mist den man fabriziert sondern auch für den Studenten der Informationen in der Cloud teilt oder dem externen Mitarbeiter der auf Kundenbesuche ist und ein Gerät benötigt mit mehr als nur 2h Akkulaufzeit um sich Präsentationen oder Arbeitsmaterial zu durchschauen und sich somit auf diverse Termine vorbereiten kann.

Android: setOnClickListener

Aufbauend auf dem ersten Tutorial (Wie fange ich an?) werde ich euch jetzt zeigen wie man seine MainActivity Class richtig befüllt und die erste Aktion über den Button ausführt.

Vorher machen wir noch einen kleinen Ausflug in den Lifecycle einer Android Activity. In der MainActivity werdet ihr ein onCreate(); finden. Diese „Mastermethode“ wird dazu verwendet Buttons und andere Elemente zu initialisieren und evtl. auch mit Leben zu befüllen. Es gibt noch andere Statusse in denen sich die Activity befinden kann. z.B. onView(); Es wird nicht empfohlen in der onView intensive Aufgaben zu initialisieren da sich sonst die ganze Activity in einem stehenden Zustand verwendet. Erst wenn der komplette Prozess abgerufen wäre würde sich die Oberfläche wieder bedienen lassen. Hier noch eine kleine Übersicht des Android Activity Lifecycles.

 

Zurück zu unseren Aktionen die wir auf unseren Button setzen wollen. Per klick soll die nächste Aktivität gestartet werden. Somit wird ein neuer Intent aufgerufen.

Um eine neue Activity aufzurufen müssen wir erstmal eine neue Activity erstellen. Dazu machen wir einen Rechtsklick auf unser Package in dem die MainActivity liegt und erstellen eine neue Klasse, hierbei geben wir als SuperClass Activity an.

Nachdem wir die Events.class erstellt haben benötigen wir noch eine neue LayoutFile für die Events Klasse. Also werden wir das machen. Rechtsklick auf den Ordner layout unter res und schon könnt ihr bei Other auf Android Layout xml File.

Das neue XML File habe ich activity_events.xml getauft. Jetzt könnt ihr gerne meinen Code kopieren. Hierbei wird lediglich eine TextView und eine ListView verwendet.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
    

    <TextView
        android:id="@+id/textViewURL"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="TextView" />
    
    <ListView 
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
</LinearLayout>

So, anschließend bearbeiten wir jetzt noch unsere Events.class folgendermaßen:

private static String _URL = "url";

@Override
protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.activity_events);

	Intent intent = super.getIntent();
	Bundle extras = intent.getExtras();
	String url = (String) extras.get(_URL);

	TextView textViewURL = (TextView) findViewById(R.id.textViewURL);
	textViewURL.setText(url);
}

Hier wird lediglich die neue Activity dargestellt und der übergeben Parameter im TextView wieder ausgegeben.
Um auch die MainActivity dementsprechend anzupassen und eine Aktion auszuführen gibt es jetzt den CodeSnippet für die MainActivity.class

public class MainActivity extends Activity {

	private static String _URL = "url";
	private String url = "http://www.infranken.de/storage/rss/rss/2.0/lokales.xml";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button btnShowNext = (Button) findViewById(R.id.btnGo);
        btnShowNext.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				Intent itn = new Intent(v.getContext(), Events.class);
				itn.putExtra(_URL, url);
				v.getContext().startActivity(itn);
			}
		});

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

}

Bevor ihr die App nun starten könnt für einen ersten Testlauf müsstest ihr noch die Manifest File anpassen. Dank dem Sicherheitskonzept von Android, können Activities nicht willkürlich aufgerufen werden.

 

Android: Wie fange ich an?

Ein kleines Tutorial für alle die sich mit Android noch nicht zu sehr auseinander gesetzt haben und einen einfachen Einstig suchen. Wie gehe ich mit einem Button um und wie kann ich die Seite wechseln um neuen Content aufzurufen.

Bevor ich alles in einer Seite reinpack und immer nur gegen neuen Content austausche baue ich lieber neue komplette Seiten auf, inkludiere fertige Elemente und binnen ein paar Minuten läuft die Anwendung super stabil.

Meine alten Tutorials und HowTos haben sich alle auf Android 1.6 – 2.3 bezogen. Jetzt werde ich versuchen euch kleine Starthilfe Tipps für die Versionen 3.0 – 4.1 zu geben. Im Grunde genommen hat sich nicht viel verändert. Es sind nur jede Menge neue Funktionen und Gadget dazu gekommen. Siling Tabviews z.B. ist doch mal richtig cool! Aber back to Basics.

Wir erstellen eine kleine Andorid Applikation, nachdem Bilder mehr sagen als 1000 Worte werde ich versuchen viele Bilder zu verwenden.

Gebt eurer Android App einen guten Namen, den ihr auch weiter verwenden wollt 😉 Ich bin mittlerweile richtig begeistert von dem Werkzeug Version 2.3 zu 4.1 ist ein Meilenstein der sich sehen lässt. Es wird so viel Unterstützung geboten was wir früher umständlich implementieren mussten.

Die Screenshot’s 4 und 5 Zeigen euch den gleichen Step, lediglich die Auswahl ist unterschiedlich. Wollt ihr  vorgefertigtes Layout nutzen um direkt die Kompatibilität mit Tablets zu gewährleisten oder wollt ihr euch frei entfalten und ein blankes Layout verwenden. Ich werde für unser kleines Beispiel das blanke Layout wählen.

Anschließend muss lediglich noch die MainActivity erstellt werden. das geht fix wenn ihr none wählt. Wenn ihr jedoch für Android Versionen jenseits der 11 entwickelt könnt ihr euch sehr schöne Vorlagen, mal wieder zusammen bauen lassen. Da kann man immer etwas experimentieren.

Anschließend läd Android alle notwendigen Daten und fügt sich euch schon zusammen. Es werden alle Ordner erstellt die fürs vernünftige und flotte Entwickeln benötigt werden. Seid froh, das war in den Vorgängerversionen auch nicht so. Da dürfte man stundenlang Dokumentationen wälzen bevor man den richtigen Ordner gefunden hat.

Auf der Linken Seite seht ihr jetzt eure Ordnerstruktur. Hierbei werden im Ordner: r

es/values alle Standardwerte gepflegt. z.b. in der strings.xml alle Werte die später per ID auf Buttons, Texte und alle anderen möglichen Elemente übergeben werden.

Der mittlere Contentbereich in eurer IDE zeigt den ganz normalen Designbereich. Hierbei hat sich auch einiges geändert. Erstellen von Dialogen ist um ein vielfaches erleichtert worden und auch übersichtlicher gestaltet. In meinem kleinen Beispiel habe ich bereits das HelloWorld gegen einen kleinen Standardbutton getauscht. Diesen werde ich in meinem nächsten Kurztutorial mit leben füllen und eine andere Aktivität – setOnClickListener – damit aufrufen.