Browse Source

added widget

develop
Robin Thoni 7 years ago
parent
commit
b31205c861

+ 12
- 0
app/src/main/AndroidManifest.xml View File

14
         android:theme="@style/AppTheme"
14
         android:theme="@style/AppTheme"
15
         android:name="android.support.multidex.MultiDexApplication">
15
         android:name="android.support.multidex.MultiDexApplication">
16
 
16
 
17
+        <service android:name="com.rthoni.stssaguenay.ui.widget.AppWidgetService"
18
+
19
+                 android:permission="android.permission.BIND_REMOTEVIEWS" />
20
+
17
         <activity
21
         <activity
18
             android:name=".ui.activities.MainActivity"
22
             android:name=".ui.activities.MainActivity"
19
             android:label="@string/app_name"
23
             android:label="@string/app_name"
42
                   android:label="@string/app_name" />
46
                   android:label="@string/app_name" />
43
         <meta-data android:name="com.facebook.sdk.ApplicationId"
47
         <meta-data android:name="com.facebook.sdk.ApplicationId"
44
                    android:value="@string/facebook_app_id"/>
48
                    android:value="@string/facebook_app_id"/>
49
+
50
+        <receiver android:name="com.rthoni.stssaguenay.ui.widget.AppWidgetProvider" >
51
+            <intent-filter>
52
+                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
53
+            </intent-filter>
54
+            <meta-data android:name="android.appwidget.provider"
55
+                       android:resource="@xml/appwidget_info" />
56
+        </receiver>
45
     </application>
57
     </application>
46
 
58
 
47
 </manifest>
59
 </manifest>

+ 13
- 0
app/src/main/java/com/rthoni/stssaguenay/business/STSBusiness.java View File

9
 import com.rthoni.stssaguenay.dbo.UserDbo;
9
 import com.rthoni.stssaguenay.dbo.UserDbo;
10
 import com.rthoni.stssaguenay.dbo.UsersSettingsDbo;
10
 import com.rthoni.stssaguenay.dbo.UsersSettingsDbo;
11
 
11
 
12
+import org.joda.time.DateTimeZone;
13
+import org.joda.time.LocalDateTime;
14
+import org.joda.time.LocalTime;
12
 import org.json.JSONArray;
15
 import org.json.JSONArray;
13
 import org.json.JSONObject;
16
 import org.json.JSONObject;
14
 
17
 
18
+import java.util.Date;
15
 import java.util.List;
19
 import java.util.List;
20
+import java.util.TimeZone;
16
 import java.util.Vector;
21
 import java.util.Vector;
17
 
22
 
18
 /**
23
 /**
101
     {
106
     {
102
         setFavouriteStops(ctx, settingsDbo.getFavouriteStops());
107
         setFavouriteStops(ctx, settingsDbo.getFavouriteStops());
103
     }
108
     }
109
+
110
+    public static LocalDateTime getTime()
111
+    {
112
+        TimeZone tz = TimeZone.getDefault();
113
+        DateTimeZone dtz = DateTimeZone.forOffsetMillis(tz.getRawOffset() + (tz.inDaylightTime(new Date()) ? tz.getDSTSavings() : 0));
114
+        LocalDateTime date = LocalDateTime.now(dtz).plusMinutes(-30);
115
+        return date;
116
+    }
104
 }
117
 }

+ 25
- 0
app/src/main/java/com/rthoni/stssaguenay/business/SchedulesBusiness.java View File

8
 
8
 
9
 import org.joda.time.LocalDateTime;
9
 import org.joda.time.LocalDateTime;
10
 
10
 
11
+import java.util.Collections;
11
 import java.util.List;
12
 import java.util.List;
13
+import java.util.Vector;
12
 
14
 
13
 /**
15
 /**
14
  * Created by robin on 10/1/16.
16
  * Created by robin on 10/1/16.
20
     {
22
     {
21
         return SchedulesDataAccess.getMultiple(config, favouriteStopDbos, date, count);
23
         return SchedulesDataAccess.getMultiple(config, favouriteStopDbos, date, count);
22
     }
24
     }
25
+
26
+    public static String getSchedulesString(List<SchedulesDbo> schedulesDbos, String id)
27
+    {
28
+        List<LocalDateTime> schedules = new Vector<>();
29
+        for (SchedulesDbo schedule : schedulesDbos) {
30
+            if (schedule.getStopId().equals(id)) {
31
+                schedules.addAll(schedule.getSchedules());
32
+            }
33
+        }
34
+
35
+        Collections.sort(schedules);
36
+        schedules.size();
37
+
38
+        StringBuilder text = new StringBuilder();
39
+
40
+        for (int i = 0; i < Math.min(5, schedules.size()); ++i) {
41
+            if (i > 0) {
42
+                text.append(", ");
43
+            }
44
+            text.append(schedules.get(i).toString("HH:mm"));
45
+        }
46
+        return text.toString();
47
+    }
23
 }
48
 }

+ 3
- 23
app/src/main/java/com/rthoni/stssaguenay/ui/fragments/HomeFragment.java View File

102
             });
102
             });
103
 
103
 
104
             if (_schedules != null) {
104
             if (_schedules != null) {
105
-                List<LocalDateTime> schedules = new Vector<>();
106
-                for (SchedulesDbo schedule : _schedules) {
107
-                    if (schedule.getStopId().equals(favouriteStopDbo.getStop().getId())) {
108
-                        schedules.addAll(schedule.getSchedules());
109
-                    }
110
-                }
111
-
112
-                Collections.sort(schedules);
113
-                schedules.size();
114
-
115
-                StringBuilder text = new StringBuilder();
116
-
117
-                for (int i = 0; i < Math.min(5, schedules.size()); ++i) {
118
-                    if (i > 0) {
119
-                        text.append(", ");
120
-                    }
121
-                    text.append(schedules.get(i).toString("HH:mm"));
122
-                }
105
+                String text = SchedulesBusiness.getSchedulesString(_schedules, favouriteStopDbo.getStop().getId());
123
 
106
 
124
-                holder._textView2.setText(text.toString());
107
+                holder._textView2.setText(text);
125
             }
108
             }
126
             else {
109
             else {
127
                 holder._textView2.setText(R.string.loading_schedules);
110
                 holder._textView2.setText(R.string.loading_schedules);
241
         }
224
         }
242
         setRefreshing(true);
225
         setRefreshing(true);
243
         _adapter.setSchedules(null);
226
         _adapter.setSchedules(null);
244
-        TimeZone tz = TimeZone.getDefault();
245
-        DateTimeZone dtz = DateTimeZone.forOffsetMillis(tz.getRawOffset() + (tz.inDaylightTime(new Date()) ? tz.getDSTSavings() : 0));
246
-        LocalDateTime date = LocalDateTime.now(dtz).plusMinutes(-30);
247
 
227
 
248
-        SchedulesBusiness.getMultiple(STSBusiness.getConfig(getContext()), _adapter.getFavourites(), date, 10)
228
+        SchedulesBusiness.getMultiple(STSBusiness.getConfig(getContext()), _adapter.getFavourites(), STSBusiness.getTime(), 10)
249
                 .then(new LuConsumer<List<SchedulesDbo>>() {
229
                 .then(new LuConsumer<List<SchedulesDbo>>() {
250
                     @Override
230
                     @Override
251
                     public void execute(List<SchedulesDbo> data) {
231
                     public void execute(List<SchedulesDbo> data) {

+ 97
- 0
app/src/main/java/com/rthoni/stssaguenay/ui/widget/AppWidgetFactory.java View File

1
+package com.rthoni.stssaguenay.ui.widget;
2
+
3
+import android.content.Context;
4
+import android.content.Intent;
5
+import android.util.Log;
6
+import android.widget.RemoteViews;
7
+import android.widget.RemoteViewsService;
8
+import android.widget.TextView;
9
+
10
+import com.rthoni.stssaguenay.R;
11
+import com.rthoni.stssaguenay.business.STSBusiness;
12
+import com.rthoni.stssaguenay.business.SchedulesBusiness;
13
+import com.rthoni.stssaguenay.dbo.SchedulesDbo;
14
+import com.rthoni.stssaguenay.dbo.UserFavouriteStopsDbo;
15
+
16
+import java.util.List;
17
+
18
+/**
19
+ * Created by robin on 12/13/16.
20
+ */
21
+
22
+public class AppWidgetFactory implements RemoteViewsService.RemoteViewsFactory {
23
+
24
+    private Context _context;
25
+
26
+    private List<UserFavouriteStopsDbo> _favouriteStopsDbos;
27
+
28
+    private List<SchedulesDbo> _schedules;
29
+
30
+    private Intent _intent;
31
+
32
+    public AppWidgetFactory(Context context, Intent intent)
33
+    {
34
+        _context = context;
35
+        _intent = intent;
36
+        Log.d("WIDGET", "ctor");
37
+    }
38
+
39
+    @Override
40
+    public void onCreate() {
41
+    }
42
+
43
+    @Override
44
+    public void onDataSetChanged() {
45
+        Log.d("WIDGET", "onDataSetChanged: " + _intent.getStringExtra("schedules"));
46
+        SchedulesDbo.SchedulesDboArray array = new SchedulesDbo.SchedulesDboArray();
47
+        try {
48
+            array.fromJson(_intent.getStringExtra("schedules"));
49
+            _schedules = array.getData();
50
+        } catch (Exception e) {
51
+            e.printStackTrace();
52
+        }
53
+        _favouriteStopsDbos = STSBusiness.getFavouriteStops(_context);
54
+    }
55
+
56
+    @Override
57
+    public void onDestroy() {
58
+        _favouriteStopsDbos = null;
59
+    }
60
+
61
+    @Override
62
+    public int getCount() {
63
+        return _favouriteStopsDbos.size();
64
+    }
65
+
66
+    @Override
67
+    public RemoteViews getViewAt(int position) {
68
+        Log.d("WIDGET", "getViewAt " + position);
69
+        RemoteViews remoteView = new RemoteViews(_context.getPackageName(), R.layout.favourite_stop_recycler_view_item);
70
+        remoteView.setTextViewText(R.id.textView, _favouriteStopsDbos.get(position).getStop().getFullName());
71
+        String text = SchedulesBusiness.getSchedulesString(_schedules, _favouriteStopsDbos.get(position).getStop().getId());
72
+        remoteView.setTextViewText(R.id.textView2, text);
73
+        return remoteView;
74
+    }
75
+
76
+    @Override
77
+    public RemoteViews getLoadingView() {
78
+        Log.d("WIDGET", "getLoadingView");
79
+        RemoteViews remoteView = new RemoteViews(_context.getPackageName(), R.layout.favourite_stop_recycler_view_item);
80
+        return remoteView;
81
+    }
82
+
83
+    @Override
84
+    public int getViewTypeCount() {
85
+        return 1;
86
+    }
87
+
88
+    @Override
89
+    public long getItemId(int position) {
90
+        return 0;
91
+    }
92
+
93
+    @Override
94
+    public boolean hasStableIds() {
95
+        return false;
96
+    }
97
+}

+ 51
- 0
app/src/main/java/com/rthoni/stssaguenay/ui/widget/AppWidgetProvider.java View File

1
+package com.rthoni.stssaguenay.ui.widget;
2
+
3
+import android.appwidget.AppWidgetManager;
4
+import android.content.Context;
5
+import android.content.Intent;
6
+import android.net.Uri;
7
+import android.util.Log;
8
+import android.widget.RemoteViews;
9
+
10
+import com.luticate.utils.business.LuConsumer;
11
+import com.rthoni.stssaguenay.R;
12
+import com.rthoni.stssaguenay.business.STSBusiness;
13
+import com.rthoni.stssaguenay.business.SchedulesBusiness;
14
+import com.rthoni.stssaguenay.dataaccess.STSDataAccess;
15
+import com.rthoni.stssaguenay.dbo.SchedulesDbo;
16
+
17
+import java.util.List;
18
+
19
+/**
20
+ * Created by robin on 12/13/16.
21
+ */
22
+
23
+public class AppWidgetProvider extends android.appwidget.AppWidgetProvider {
24
+    public void onUpdate(final Context context, final AppWidgetManager appWidgetManager, final int[] appWidgetIds) {
25
+        final int N = appWidgetIds.length;
26
+
27
+        Log.d("WIDGET", "onUpdate");
28
+        // Perform this loop procedure for each App Widget that belongs to this provider
29
+        for (int i=0; i<N; i++) {
30
+
31
+            final int finalI = i;
32
+            SchedulesBusiness.getMultiple(STSBusiness.getConfig(context), STSBusiness.getFavouriteStops(context), STSBusiness.getTime(), 10)
33
+                    .then(new LuConsumer<List<SchedulesDbo>>() {
34
+                        @Override
35
+                        public void execute(List<SchedulesDbo> schedulesDbos) {
36
+
37
+                            Intent intent = new Intent(context, AppWidgetService.class);
38
+                            intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[finalI]);
39
+                            SchedulesDbo.SchedulesDboArray array = new SchedulesDbo.SchedulesDboArray();
40
+                            array.setData(schedulesDbos);
41
+                            intent.putExtra("schedules", array.toString());
42
+                            intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
43
+
44
+                            RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.app_widget);
45
+                            views.setRemoteAdapter(R.id.listFavouritesStops, intent);
46
+                            appWidgetManager.updateAppWidget(appWidgetIds[finalI], views);
47
+                        }
48
+                    });
49
+        }
50
+    }
51
+}

+ 15
- 0
app/src/main/java/com/rthoni/stssaguenay/ui/widget/AppWidgetService.java View File

1
+package com.rthoni.stssaguenay.ui.widget;
2
+
3
+import android.content.Intent;
4
+import android.widget.RemoteViewsService;
5
+
6
+/**
7
+ * Created by robin on 12/13/16.
8
+ */
9
+
10
+public class AppWidgetService extends RemoteViewsService {
11
+    @Override
12
+    public RemoteViewsFactory onGetViewFactory(Intent intent) {
13
+        return new AppWidgetFactory(this.getApplicationContext(), intent);
14
+    }
15
+}

BIN
app/src/main/res/drawable/widget.png View File


+ 15
- 0
app/src/main/res/layout/app_widget.xml View File

1
+<?xml version="1.0" encoding="utf-8"?>
2
+<RelativeLayout
3
+    xmlns:android="http://schemas.android.com/apk/res/android"
4
+    android:layout_width="match_parent"
5
+    android:layout_height="match_parent"
6
+    android:padding="@dimen/widget_margin"
7
+    android:background="@color/widget_background">
8
+
9
+    <ListView
10
+        android:id="@+id/listFavouritesStops"
11
+        android:scrollbars="vertical"
12
+        android:layout_width="match_parent"
13
+        android:layout_height="match_parent"/>
14
+
15
+</RelativeLayout>

+ 1
- 0
app/src/main/res/layout/favourite_stop_recycler_view_item.xml View File

16
         android:id="@+id/textView"
16
         android:id="@+id/textView"
17
         android:clickable="false"
17
         android:clickable="false"
18
         android:focusable="false"
18
         android:focusable="false"
19
+        android:text="@string/loading_schedules"
19
         tools:text="Stop name"
20
         tools:text="Stop name"
20
         android:gravity="center_vertical"
21
         android:gravity="center_vertical"
21
         android:layout_weight="1.0"/>
22
         android:layout_weight="1.0"/>

+ 4
- 0
app/src/main/res/values-v14/dimens.xml View File

1
+<?xml version="1.0" encoding="utf-8"?>
2
+<resources>
3
+    <dimen name="widget_margin">8dp</dimen>
4
+</resources>

+ 1
- 0
app/src/main/res/values/colors.xml View File

3
     <color name="colorPrimary">#3F51B5</color>
3
     <color name="colorPrimary">#3F51B5</color>
4
     <color name="colorPrimaryDark">#303F9F</color>
4
     <color name="colorPrimaryDark">#303F9F</color>
5
     <color name="colorAccent">#FF4081</color>
5
     <color name="colorAccent">#FF4081</color>
6
+    <color name="widget_background">#ec2b2b2b</color>
6
 </resources>
7
 </resources>

+ 4
- 0
app/src/main/res/values/dimens.xml View File

8
     <dimen name="fab_margin">16dp</dimen>
8
     <dimen name="fab_margin">16dp</dimen>
9
 
9
 
10
     <dimen name="ad_height">-2dp</dimen>
10
     <dimen name="ad_height">-2dp</dimen>
11
+
12
+    <dimen name="widget_margin">8dp</dimen>
13
+
14
+
11
 </resources>
15
 </resources>

+ 10
- 0
app/src/main/res/xml/appwidget_info.xml View File

1
+<?xml version="1.0" encoding="utf-8"?>
2
+<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
3
+                    android:minWidth="80dp"
4
+                    android:minHeight="40dp"
5
+                    android:updatePeriodMillis="600000"
6
+                    android:previewImage="@drawable/widget"
7
+                    android:initialLayout="@layout/app_widget"
8
+                    android:resizeMode="horizontal|vertical"
9
+                    android:widgetCategory="home_screen">
10
+</appwidget-provider>

Loading…
Cancel
Save