das Anzeigen von Views mit Inhalt war nur der Anfang.
Jetzt kommen wir zum Aktualisieren von Daten.
Für dieses Tutorial werden Kenntnisse für das Erstellen eines Widget und Starten eines Service vorausgesetzt und basiert auf das Tutorial erstellen von Widgets.
Als ersten erstellen wir ein Projekt. Dann eine Klasse, die von AppWidgetProvider erbt. In der Methode onUpdate starten wir einen Service, der für das Aktualisieren der Daten zuständig ist.
package de.alexroid.widgetsample;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
public class BasisAppWidgetProvider extends AppWidgetProvider {
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
// Build the intent to call the service
Intent intent = new Intent(context.getApplicationContext(),
UpdateWidgetService.class);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);
// Update the widgets via the service
context.startService(intent);
}
}
Als Extra übergeben wir gleich alle Widget IDs. Diese werden wir später brauchen. Und nicht vergessen den Service in der Manifest hinzuzufügen.
<application ..>
<service android:name="de.alexroid.widgetsample.UpdateWidgetService" />
</application>
Kommen wir zum Layout.
widget_layout.xml
<?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="match_parent"
android:background="@drawable/widget_background"
android:orientation="horizontal"
android:padding="@dimen/widget_margin"
android:weightSum="3" >
<ImageButton
android:id="@+id/button"
style="@android:style/Widget.Button"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_margin="8dp
"
android:layout_weight="1"
android:padding="8dp
"
android:src="@drawable/navigation_refresh" />
<TextView
android:id="@+id/textViewU"
style="@android:style/Widget.TextView"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_margin="8dp
"
android:layout_weight="1"
android:background="@drawable/widget_item_background"
android:gravity="center_horizontal|center_vertical"
android:padding="8dp
"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="@+id/textViewC"
style="@android:style/Widget.TextView"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_margin="8dp"
android:layout_weight="1"
android:background="@drawable/widget_item_background"
android:gravity="center_horizontal|center_vertical"
android:padding="8dp
"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
widget_background
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<stroke
android:width="5dp"
android:color="#FF000000" />
<gradient
android:angle="135"
android:endColor="#EE666666"
android:startColor="#EE333333" />
<corners android:radius="5dp" />
</shape>
widget_item_background
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<gradient
android:angle="45"
android:endColor="#EE33B5E5"
android:startColor="#EE0099CC" />
</shape>
Damit haben wir einen Button zum Inteagieren und zwei Textfelder für die Anzeige. Das Icon navigation_refresh ist aus dem Design-Pack. Der Service, der im Hintergrund für uns alles aktualisiert, sieht wie folgt aus.
package de.alexroid.widgetsample;
import android.app.PendingIntent;
import android.app.Service;
import android.appwidget.AppWidgetManager;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.IBinder;
import android.util.Log;
import android.widget.RemoteViews;
public class UpdateWidgetService extends Service {
@Override
public IBinder onBind(Intent arg0) {
return null;
}
@Override
public void onStart(Intent intent, int startId) {
int[] allWidgetIds = intent
.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS);
//für das Klicken, s.u.
boolean clicked = intent.getBooleanExtra(
AppWidgetManager.EXTRA_CUSTOM_EXTRAS, false);
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(this
.getApplicationContext());
SharedPreferences preferences = getSharedPreferences(getClass()
.getSimpleName(), 0);
for (int widgetId : allWidgetIds) {
RemoteViews remoteViews = new RemoteViews(this
.getApplicationContext().getPackageName(),
R.layout.widget_frame);
//Hier beziehen wir beide Zahlen, die wir darstellen
//numberC für das Klickevent und number für das zeitliche Update
int numberC = preferences.getInt("numberC", -1);
if (clicked) {
Editor edit = preferences.edit();
numberC += 1;
edit.putInt("number2", numberC );
edit.commit();
} else {
int number = preferences.getInt("number", -1) + 1;
Editor edit = preferences.edit();
edit.putInt("number", number);
edit.commit();
// Text setzen
remoteViews.setTextViewText(R.id.textViewU,
String.valueOf(number));
}
// Text setzen
remoteViews
.setTextViewText(R.id.textViewC, String.valueOf(numberC));
//Service wegen dem Klick starten
Intent clickService = new Intent(this.getApplicationContext(),
UpdateWidgetService.class);
clickService.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
clickService.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS,
allWidgetIds);
clickService.putExtra(AppWidgetManager.EXTRA_CUSTOM_EXTRAS, true);
PendingIntent pendingIntent = PendingIntent.getService(
getApplicationContext(), 0, clickService,
PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.button, pendingIntent);
//Widget tatsächlich updaten
appWidgetManager.updateAppWidget(widgetId, remoteViews);
stopSelf();
super.onStart(intent, startId);
}
}
}
Die Variable allWidgetIds hilft uns das Update auf mehreren Widgets durchzuführen.
Beim jedem Druchlauf des Updatemechanismus wird pro Widget die Zahl um eins hochgezählt und als Text gesetzt. Die Zahl in der Mitte wird im Invervall Aktualisiert und die Rechte durch das Klicken auf den Button.
Es wird derzeit nicht garantiert, dass der Service in dem Interval anspringt, wie ihr angegeben habt. Aber einmal die Stunde sollte den Akku nicht zu strapazieren. HIER ist der originale Text - unter updatePeriodMillis.
So der nächste Schritt ist vollbracht. Das Aktualisieren klappt nun auch.
Ich verabschiede mich für diese Nacht.
Alexander Fink
Keine Kommentare:
Kommentar veröffentlichen