auto updating list widget
This commit is contained in:
@@ -43,6 +43,18 @@
|
|||||||
android:name="net.headlezz.notificationlogger.logger.NotificationProvider"
|
android:name="net.headlezz.notificationlogger.logger.NotificationProvider"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<!-- widget stuff -->
|
||||||
|
<receiver android:name=".widget.ListWidgetProvider">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
||||||
|
</intent-filter>
|
||||||
|
<meta-data android:name="android.appwidget.provider"
|
||||||
|
android:resource="@xml/widget_info" />
|
||||||
|
</receiver>
|
||||||
|
<service android:name=".widget.ListWidgetService"
|
||||||
|
android:permission="android.permission.BIND_REMOTEVIEWS"
|
||||||
|
/>
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import net.headlezz.notificationlogger.logger.BlacklistItem;
|
|||||||
import net.headlezz.notificationlogger.logger.BlacklistTable;
|
import net.headlezz.notificationlogger.logger.BlacklistTable;
|
||||||
import net.headlezz.notificationlogger.logger.LoggedNotification;
|
import net.headlezz.notificationlogger.logger.LoggedNotification;
|
||||||
import net.headlezz.notificationlogger.logger.Logged_notificationTable;
|
import net.headlezz.notificationlogger.logger.Logged_notificationTable;
|
||||||
|
import net.headlezz.notificationlogger.widget.WidgetUtils;
|
||||||
|
|
||||||
public class DatabaseUtils {
|
public class DatabaseUtils {
|
||||||
|
|
||||||
@@ -16,6 +17,7 @@ public class DatabaseUtils {
|
|||||||
Logged_notificationTable.CONTENT_URI,
|
Logged_notificationTable.CONTENT_URI,
|
||||||
Logged_notificationTable.getContentValues(ln, false)
|
Logged_notificationTable.getContentValues(ln, false)
|
||||||
);
|
);
|
||||||
|
WidgetUtils.notifyWidgetsUpdate(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LoggedNotification getNotificationById(Context context, long id) {
|
public static LoggedNotification getNotificationById(Context context, long id) {
|
||||||
@@ -31,6 +33,7 @@ public class DatabaseUtils {
|
|||||||
// there are no notifications with negative ids, so we use this to select all rows
|
// there are no notifications with negative ids, so we use this to select all rows
|
||||||
String whereClause = Logged_notificationTable.FIELD_NOTIFICATION_ID + " != -1";
|
String whereClause = Logged_notificationTable.FIELD_NOTIFICATION_ID + " != -1";
|
||||||
resolver.delete(Logged_notificationTable.CONTENT_URI, whereClause, new String[0]);
|
resolver.delete(Logged_notificationTable.CONTENT_URI, whereClause, new String[0]);
|
||||||
|
WidgetUtils.notifyWidgetsUpdate(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isPackageBlacklisted(Context context, String packageName) {
|
public static boolean isPackageBlacklisted(Context context, String packageName) {
|
||||||
@@ -81,5 +84,6 @@ public class DatabaseUtils {
|
|||||||
Logged_notificationTable.FIELD__ID + " = ?",
|
Logged_notificationTable.FIELD__ID + " = ?",
|
||||||
new String[]{String.valueOf(id)}
|
new String[]{String.valueOf(id)}
|
||||||
);
|
);
|
||||||
|
WidgetUtils.notifyWidgetsUpdate(context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package net.headlezz.notificationlogger.widget;
|
||||||
|
|
||||||
|
import android.appwidget.AppWidgetManager;
|
||||||
|
import android.appwidget.AppWidgetProvider;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.widget.RemoteViews;
|
||||||
|
|
||||||
|
import net.headlezz.notificationlogger.R;
|
||||||
|
|
||||||
|
public class ListWidgetProvider extends AppWidgetProvider {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
|
||||||
|
for(int widgetId : appWidgetIds) {
|
||||||
|
RemoteViews rvs = updateWidgetListView(context, widgetId);
|
||||||
|
appWidgetManager.updateAppWidget(appWidgetIds, rvs);
|
||||||
|
}
|
||||||
|
super.onUpdate(context, appWidgetManager, appWidgetIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
private RemoteViews updateWidgetListView(Context context, int appWidgetId) {
|
||||||
|
RemoteViews rvs = new RemoteViews(context.getPackageName(), R.layout.widget_list);
|
||||||
|
|
||||||
|
Intent serviceIntent = new Intent(context, ListWidgetService.class);
|
||||||
|
serviceIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
|
||||||
|
serviceIntent.setData(Uri.parse(serviceIntent.toUri(Intent.URI_INTENT_SCHEME)));
|
||||||
|
|
||||||
|
rvs.setRemoteAdapter(R.id.list_widget_listView, serviceIntent);
|
||||||
|
rvs.setEmptyView(R.id.list_widget_listView, R.id.list_widget_empty_view);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return rvs;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package net.headlezz.notificationlogger.widget;
|
||||||
|
|
||||||
|
import android.appwidget.AppWidgetManager;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.widget.RemoteViewsService;
|
||||||
|
|
||||||
|
public class ListWidgetService extends RemoteViewsService {
|
||||||
|
@Override
|
||||||
|
public RemoteViewsFactory onGetViewFactory(Intent intent) {
|
||||||
|
int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
|
||||||
|
return new ListWidgetViewFactory(getApplicationContext(), appWidgetId);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
package net.headlezz.notificationlogger.widget;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.database.Cursor;
|
||||||
|
import android.text.format.DateUtils;
|
||||||
|
import android.widget.RemoteViews;
|
||||||
|
import android.widget.RemoteViewsService;
|
||||||
|
|
||||||
|
import net.headlezz.notificationlogger.R;
|
||||||
|
import net.headlezz.notificationlogger.logger.LoggedNotification;
|
||||||
|
import net.headlezz.notificationlogger.logger.Logged_notificationTable;
|
||||||
|
|
||||||
|
import timber.log.Timber;
|
||||||
|
|
||||||
|
public class ListWidgetViewFactory implements RemoteViewsService.RemoteViewsFactory {
|
||||||
|
|
||||||
|
int mAppWidgetId;
|
||||||
|
Context mContext;
|
||||||
|
|
||||||
|
Cursor mCursor;
|
||||||
|
|
||||||
|
public ListWidgetViewFactory(Context context, int appWidgetId) {
|
||||||
|
mContext = context;
|
||||||
|
this.mAppWidgetId = appWidgetId;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate() { /** ignored **/ }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDataSetChanged() {
|
||||||
|
Timber.d("ON DATA SET CHANGED");
|
||||||
|
if(mCursor != null) {
|
||||||
|
mCursor.close();
|
||||||
|
}
|
||||||
|
mCursor = mContext.getContentResolver().query(Logged_notificationTable.CONTENT_URI, null, null, null, Logged_notificationTable.FIELD_DATE + " DESC");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
if(mCursor != null)
|
||||||
|
mCursor.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCount() {
|
||||||
|
if(mCursor == null) {
|
||||||
|
Timber.d("cursor is null");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return mCursor.getCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RemoteViews getViewAt(int position) {
|
||||||
|
RemoteViews rv = new RemoteViews(mContext.getPackageName(), R.layout.widget_list_item);
|
||||||
|
mCursor.moveToPosition(position);
|
||||||
|
|
||||||
|
LoggedNotification notification = Logged_notificationTable.getRow(mCursor, false);
|
||||||
|
|
||||||
|
rv.setTextViewText(R.id.widget_list_item_title, notification.appName);
|
||||||
|
rv.setTextViewText(R.id.widget_list_item_notification, notification.title + ": " + notification.message);
|
||||||
|
rv.setTextViewText(R.id.widget_list_item_date, DateUtils.formatDateTime(mContext, notification.date, DateUtils.FORMAT_ABBREV_ALL | DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_DATE));
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RemoteViews getLoadingView() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getViewTypeCount() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getItemId(int position) {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasStableIds() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package net.headlezz.notificationlogger.widget;
|
||||||
|
|
||||||
|
import android.appwidget.AppWidgetManager;
|
||||||
|
import android.content.ComponentName;
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import net.headlezz.notificationlogger.R;
|
||||||
|
|
||||||
|
public class WidgetUtils {
|
||||||
|
|
||||||
|
public static void notifyWidgetsUpdate(Context context) {
|
||||||
|
AppWidgetManager manager = AppWidgetManager.getInstance(context);
|
||||||
|
int[] appWidgetIds = manager.getAppWidgetIds(new ComponentName(context, ListWidgetProvider.class));
|
||||||
|
manager.notifyAppWidgetViewDataChanged(appWidgetIds, R.id.list_widget_listView);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
BIN
app/src/main/res/drawable/widget_list_preview.png
Normal file
BIN
app/src/main/res/drawable/widget_list_preview.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 67 KiB |
26
app/src/main/res/layout/widget_list.xml
Normal file
26
app/src/main/res/layout/widget_list.xml
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<?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:orientation="vertical"
|
||||||
|
android:padding="4dp">
|
||||||
|
|
||||||
|
<!-- ListView to be shown on widget -->
|
||||||
|
<ListView
|
||||||
|
android:dividerHeight="4dp"
|
||||||
|
android:id="@+id/list_widget_listView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
|
||||||
|
<!-- Empty view is show if list items are empty -->
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/list_widget_empty_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="Empty list"
|
||||||
|
android:textColor="#ffffff"
|
||||||
|
android:textSize="20sp"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
40
app/src/main/res/layout/widget_list_item.xml
Normal file
40
app/src/main/res/layout/widget_list_item.xml
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:background="@android:color/white"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:padding="8dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
||||||
|
android:id="@+id/widget_list_item_title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:clickable="false"
|
||||||
|
android:textColor="@android:color/black"
|
||||||
|
android:textStyle="bold"
|
||||||
|
tools:text="appname" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:textAppearance="@style/TextAppearance.AppCompat.Caption"
|
||||||
|
android:layout_below="@+id/widget_list_item_title"
|
||||||
|
android:id="@+id/widget_list_item_notification"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:clickable="false"
|
||||||
|
android:textColor="@android:color/black"
|
||||||
|
tools:text="message" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:textAppearance="@style/TextAppearance.AppCompat.Caption"
|
||||||
|
android:id="@+id/widget_list_item_date"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:clickable="false"
|
||||||
|
android:textColor="@android:color/black"
|
||||||
|
tools:text="date"
|
||||||
|
android:layout_alignTop="@+id/widget_list_item_title"
|
||||||
|
android:layout_alignParentEnd="true" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
10
app/src/main/res/xml/widget_info.xml
Normal file
10
app/src/main/res/xml/widget_info.xml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:minWidth="250dp"
|
||||||
|
android:minHeight="110dp"
|
||||||
|
android:updatePeriodMillis="300000"
|
||||||
|
android:previewImage="@drawable/widget_list_preview"
|
||||||
|
android:initialLayout="@layout/widget_list"
|
||||||
|
android:resizeMode="horizontal|vertical"
|
||||||
|
android:widgetCategory="home_screen">
|
||||||
|
</appwidget-provider>
|
||||||
Reference in New Issue
Block a user