WeatherInformation: widget WIP
authorgu.martinm@gmail.com <gu.martinm@gmail.com>
Thu, 25 Sep 2014 19:46:57 +0000 (21:46 +0200)
committergu.martinm@gmail.com <gu.martinm@gmail.com>
Thu, 25 Sep 2014 19:46:57 +0000 (21:46 +0200)
Android/WeatherInformation/AndroidManifest.xml
Android/WeatherInformation/res/layout/appwidget.xml [new file with mode: 0644]
Android/WeatherInformation/res/layout/appwidget_configure.xml [new file with mode: 0644]
Android/WeatherInformation/res/layout/notification.xml
Android/WeatherInformation/res/values-v14/dimens.xml [new file with mode: 0644]
Android/WeatherInformation/res/values/dimens.xml
Android/WeatherInformation/res/xml/appwidget_provider.xml [new file with mode: 0644]
Android/WeatherInformation/src/de/example/exampletdd/widget/WeatherInformationWidgetConfigure.java [new file with mode: 0644]
Android/WeatherInformation/src/de/example/exampletdd/widget/WeatherInformationWidgetProvider.java [new file with mode: 0644]

index 93b2253..e5d1bbf 100644 (file)
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
+        <activity android:name=".widget.WeatherInformationWidgetConfigure">
+            <intent-filter>
+                <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE"/>
+            </intent-filter>
+        </activity>
         
         <receiver android:name=".WeatherInformationBootReceiver"
             android:enabled="true">
                 <action android:name="android.intent.action.BOOT_COMPLETED"></action>
             </intent-filter>
         </receiver>
+        <receiver android:name="de.example.exampletdd.widget.WeatherInformationWidgetProvider" >
+            <intent-filter>
+                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
+            </intent-filter>
+            <meta-data android:name="android.appwidget.provider"
+                       android:resource="@xml/appwidget_provider" />
+        </receiver>
 
         <service
             android:name=".WeatherInformationBatch"
diff --git a/Android/WeatherInformation/res/layout/appwidget.xml b/Android/WeatherInformation/res/layout/appwidget.xml
new file mode 100644 (file)
index 0000000..d00a9b6
--- /dev/null
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:layout_gravity="fill"
+    android:orientation="horizontal"
+    android:baselineAligned="false"
+    android:padding="@dimen/widget_margin" >
+
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:layout_gravity="center"
+        android:gravity="center"
+        android:orientation="vertical" >
+    
+       <ImageView
+               android:layout_width="wrap_content"
+               android:layout_height="wrap_content"
+               android:layout_gravity="start"
+               android:contentDescription="@string/icon_weather_description"
+               android:orientation="vertical"
+               android:src="@drawable/ic_launcher" />
+    </LinearLayout>
+    
+
+       
+    <LinearLayout
+        android:layout_width="0dp"
+        android:layout_height="match_parent"
+        android:layout_gravity="center"
+        android:layout_weight="2"
+        android:gravity="center"
+        android:orientation="vertical" >
+        
+        <TextView
+            android:id="@+id/weather_appwidget_city"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:text="Morata de Tajuña"
+            android:textAlignment="center"
+            android:textAppearance="?android:attr/textAppearanceSmall"
+            android:textStyle="bold" />
+    
+        <TextView
+            android:id="@+id/weather_appwidget_country"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:text="Spain"
+            android:textAlignment="center"
+            android:textAppearance="?android:attr/textAppearanceSmall"
+            android:textStyle="normal" />
+    </LinearLayout>
+            
+    <LinearLayout
+        android:layout_width="0dp"
+        android:layout_height="match_parent"
+        android:layout_gravity="center"
+        android:layout_weight="1"
+        android:gravity="center"
+        android:orientation="vertical" >
+        
+        <TextView
+            android:id="@+id/weather_appwidget_temperature_max"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:text="12ºC"
+            android:textAlignment="center"
+            android:textAllCaps="true"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:textStyle="bold" />
+    
+       <TextView
+               android:id="@+id/weather_appwidget_temperature_min"
+               android:layout_width="wrap_content"
+               android:layout_height="wrap_content"
+               android:layout_gravity="center"
+               android:text="5ºC"
+               android:textAlignment="center"
+               android:textAllCaps="true"
+               android:textAppearance="?android:attr/textAppearanceMedium"
+               android:textStyle="normal" />
+    </LinearLayout>
+    
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:layout_gravity="center"
+        android:gravity="center"
+        android:orientation="vertical" >
+    
+       <ImageView
+               android:id="@+id/weather_appwidget_image"
+               android:layout_width="wrap_content"
+               android:layout_height="wrap_content"
+               android:layout_gravity="end"
+               android:contentDescription="@string/icon_weather_description"
+               android:orientation="vertical"
+               android:src="@drawable/ic_launcher" />
+    
+    </LinearLayout>
+
+</LinearLayout>
diff --git a/Android/WeatherInformation/res/layout/appwidget_configure.xml b/Android/WeatherInformation/res/layout/appwidget_configure.xml
new file mode 100644 (file)
index 0000000..7a0764b
--- /dev/null
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical">
+
+    <TextView
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="Acitivity configure, WIP."/>
+
+    <Button
+        android:id="@+id/weather_appwidget_configure_save_button"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@android:string/ok"/>
+
+</LinearLayout>
+
index 7644bf8..fd6bf80 100644 (file)
@@ -3,6 +3,7 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:layout_gravity="fill"
+    android:baselineAligned="false"
     android:orientation="horizontal" >
 
     <LinearLayout
diff --git a/Android/WeatherInformation/res/values-v14/dimens.xml b/Android/WeatherInformation/res/values-v14/dimens.xml
new file mode 100644 (file)
index 0000000..94bb2e6
--- /dev/null
@@ -0,0 +1,7 @@
+<resources>
+
+    <!-- Default screen margins, per the Android Design guidelines. -->
+    <dimen name="activity_horizontal_margin">16dp</dimen>
+    <dimen name="activity_vertical_margin">16dp</dimen>
+    <dimen name="widget_margin">0dp</dimen>
+</resources>
index 55c1e59..063ada2 100644 (file)
@@ -3,5 +3,5 @@
     <!-- Default screen margins, per the Android Design guidelines. -->
     <dimen name="activity_horizontal_margin">16dp</dimen>
     <dimen name="activity_vertical_margin">16dp</dimen>
-
+    <dimen name="widget_margin">8dp</dimen>
 </resources>
diff --git a/Android/WeatherInformation/res/xml/appwidget_provider.xml b/Android/WeatherInformation/res/xml/appwidget_provider.xml
new file mode 100644 (file)
index 0000000..90ffc87
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
+    android:minWidth="40dp"
+    android:minHeight="40dp"
+    android:minResizeWidth="40dp"
+    android:minResizeHeight="40dp"
+    android:resizeMode="none"
+    android:previewImage="@drawable/ic_launcher"
+    android:initialLayout="@layout/appwidget"
+    android:configure="de.example.exampletdd.widget.WeatherInformationWidgetConfigure" 
+    android:widgetCategory="home_screen|keyguard"
+    android:updatePeriodMillis="86400000">
+</appwidget-provider>
diff --git a/Android/WeatherInformation/src/de/example/exampletdd/widget/WeatherInformationWidgetConfigure.java b/Android/WeatherInformation/src/de/example/exampletdd/widget/WeatherInformationWidgetConfigure.java
new file mode 100644 (file)
index 0000000..a38c2bf
--- /dev/null
@@ -0,0 +1,61 @@
+package de.example.exampletdd.widget;
+
+import android.app.Activity;
+import android.appwidget.AppWidgetManager;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import de.example.exampletdd.R;
+
+public class WeatherInformationWidgetConfigure extends Activity {
+       private int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
+       
+    final View.OnClickListener mOnClickListener = new View.OnClickListener() {
+        public void onClick(View v) {
+
+               
+            // When the button is clicked, save the string in our prefs and return that they
+            // clicked OK.
+            // Push widget update to surface with newly set prefix
+            final AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(
+                       WeatherInformationWidgetConfigure.this.getApplicationContext());
+            WeatherInformationWidgetProvider.updateAppWidget(
+                       WeatherInformationWidgetConfigure.this.getApplicationContext(),
+                       appWidgetManager,
+                    mAppWidgetId);
+
+            // Make sure we pass back the original appWidgetId
+            final Intent resultValue = new Intent();
+            resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
+            WeatherInformationWidgetConfigure.this.setResult(RESULT_OK, resultValue);
+            finish();
+        }
+    };
+    @Override
+    public void onCreate(final Bundle icicle) {
+        super.onCreate(icicle);
+     
+        // Set the result to CANCELED.  This will cause the widget host to cancel
+        // out of the widget placement if they press the back button.
+        this.setResult(RESULT_CANCELED);
+
+        // Set the view layout resource to use.
+        this.setContentView(R.layout.appwidget_configure);
+        
+        // Bind the action for the save button.
+        this.findViewById(R.id.weather_appwidget_configure_save_button).setOnClickListener(mOnClickListener);
+        
+        // Find the widget id from the intent. 
+        final Intent intent = getIntent();
+        final Bundle extras = intent.getExtras();
+        if (extras != null) {
+            mAppWidgetId = extras.getInt(
+                    AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
+        }
+        
+        // If they gave us an intent without the widget id, just bail.
+        if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
+               this.finish();
+        }
+    }
+}
diff --git a/Android/WeatherInformation/src/de/example/exampletdd/widget/WeatherInformationWidgetProvider.java b/Android/WeatherInformation/src/de/example/exampletdd/widget/WeatherInformationWidgetProvider.java
new file mode 100644 (file)
index 0000000..2495ebc
--- /dev/null
@@ -0,0 +1,64 @@
+package de.example.exampletdd.widget;
+
+
+import android.appwidget.AppWidgetManager;
+import android.appwidget.AppWidgetProvider;
+import android.appwidget.AppWidgetProviderInfo;
+import android.content.Context;
+import android.os.Bundle;
+import android.util.Log;
+import android.widget.RemoteViews;
+import de.example.exampletdd.R;
+
+public class WeatherInformationWidgetProvider extends AppWidgetProvider {
+    private static final String TAG = "WeatherInformationWidgetProvider";
+
+    @Override
+    public void onUpdate(final Context context, final AppWidgetManager appWidgetManager, final int[] appWidgetIds) {
+        Log.d(TAG, "onUpdate");
+        // For each widget that needs an update, get the text that we should display:
+        //   - Create a RemoteViews object for it
+        //   - Set the text in the RemoteViews object
+        //   - Tell the AppWidgetManager to show that views object for the widget.
+        final int N = appWidgetIds.length;
+        for (int i=0; i<N; i++) {
+            int appWidgetId = appWidgetIds[i];
+            updateAppWidget(context, appWidgetManager, appWidgetId);
+        }
+    }
+    
+    @Override
+    public void onDeleted(Context context, int[] appWidgetIds) {
+        Log.d(TAG, "onDeleted");
+        // When the user deletes the widget, delete the preference associated with it.
+        final int N = appWidgetIds.length;
+        for (int i=0; i<N; i++) {
+            //ExampleAppWidgetConfigure.deleteTitlePref(context, appWidgetIds[i]);
+        }
+    }
+    
+    static void updateAppWidget(final Context context, final AppWidgetManager appWidgetManager, final int appWidgetId) {
+        Log.i(TAG, "updateAppWidget appWidgetId=" + appWidgetId);
+
+        int widgetId;
+        Bundle myOptions = appWidgetManager.getAppWidgetOptions(appWidgetId);
+
+        // Get the value of OPTION_APPWIDGET_HOST_CATEGORY
+        int category = myOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY, -1);
+
+        // If the value is WIDGET_CATEGORY_KEYGUARD, it's a lockscreen widget
+        boolean isKeyguard = category == AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD;
+        
+        // Once you know the widget's category, you can optionally load a different base layout, set different 
+        // properties, and so on. For example:
+        //int baseLayout = isKeyguard ? R.layout.keyguard_widget_layout : R.layout.widget_layout;
+        
+        // Construct the RemoteViews object.  It takes the package name (in our case, it's our
+        // package, but it needs this because on the other side it's the widget host inflating
+        // the layout from our package).
+        final RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.appwidget);
+
+        // Tell the widget manager
+        appWidgetManager.updateAppWidget(appWidgetId, views);
+    }
+}