Следуя онлайн-примерам, я создал виджет, который показывает данные из XML-файла.Все работает, по крайней мере, кажется :), но
1) Я помещаю соединение с БД, интернет-соединение и анализ XML в "onDataSetChanged".Нет смысла повторять соединения для каждого активного виджета, поскольку данные одинаковы.Как я могу выполнить соединение только один раз, даже если пользователь активирует несколько виджетов?
2) Поскольку я сделал / скопировал, но я все еще должен понять :), есть ли какая-либо ошибка, кроме проблемы повторных соединений?Есть ли что-нибудь, что можно было бы сделать лучше?
3) Если бы я хотел добавить кнопку для обновления того, что я должен назвать?
4) Поскольку это выполняется каждые 30 минут, это труднодля меня, чтобы контролировать его поведение.Могу ли я быть уверен, что виджет продолжит работать должным образом со временем?
Спасибо, если кто-нибудь может помочь мне разобраться.
Здесь основные файлы
манифест
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="pm48.news.testwidget">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".NewWidgetProvider">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/scroll_widget_info" />
</receiver>
<service
android:name=".NewsWidgetService"
android:permission="android.permission.BIND_REMOTEVIEWS"
/>
</application>
</manifest>
scroll_widget_info.xml
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:initialKeyguardLayout="@layout/scroll_widget"
android:initialLayout="@layout/scroll_widget"
android:minWidth="250dp"
android:minHeight="110dp"
android:previewImage="@drawable/example_appwidget_preview"
android:resizeMode="vertical"
android:updatePeriodMillis="1800000"
android:widgetCategory="home_screen"></appwidget-provider>
NewsWidgetService
public class NewsWidgetService extends RemoteViewsService {
@Override
public RemoteViewsFactory onGetViewFactory(Intent intent) {
return new NewsRemoteViewsFactory(this.getApplicationContext(), intent);
}
}
class NewsRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory {
private List<News> mNewsItems = new ArrayList<News>();
private Context mContext;
private int mAppWidgetId;
public NewsRemoteViewsFactory(Context context, Intent intent) {
mContext = context;
mAppWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
}
public void onCreate() {
}
public void onDestroy() {
mNewsItems.clear();
}
public int getCount() {
return mNewsItems.size();
}
public RemoteViews getViewAt(int position) {
RemoteViews rv = new RemoteViews(mContext.getPackageName(), R.layout.scroll_widget_item);
rv.setTextViewText(R.id.widget_item, mNewsItems.get(position).getTitle());
Bundle extras = new Bundle();
extras.putInt(NewsWidgetProvider.EXTRA_ITEM, position);
Intent fillInIntent = new Intent();
fillInIntent.putExtras(extras);
rv.setOnClickFillInIntent(R.id.widget_item, fillInIntent);
return rv;
}
public RemoteViews getLoadingView() {
return null;
}
public int getViewTypeCount() {
return 1;
}
public long getItemId(int position) {
return position;
}
public boolean hasStableIds() {
return true;
}
public void onDataSetChanged() {
NewsRoomDatabase db = NewsRoomDatabase.getDatabase(mContext.getApplicationContext());
NewsDao mNewsDao = db.newsDao();
try {
URL url = new URL("http://examples.com/xml");
URLConnection connection = url.openConnection();
connection.setConnectTimeout(10000);
connection.connect();
InputStream in = connection.getInputStream();
List<News> new_news = parseXML(in);
mNewsDao.deleteAll();
for (News n : new_news) {
mNewsDao.insert(n);
}
} catch (Exception e) {
e.printStackTrace();
}
mNewsItems = mNewsDao.getAllNews();
}
List<News> parseXML(InputStream in) throws IOException, XmlPullParserException {
// *** return List<News> ***
}
}
NewsWigetProvider
public class NewsWidgetProvider extends AppWidgetProvider {
public static final String TOAST_ACTION = "com.example.android.stackwidget.TOAST_ACTION";
public static final String EXTRA_ITEM = "com.example.android.stackwidget.EXTRA_ITEM";
@Override
public void onDeleted(Context context, int[] appWidgetIds) {
super.onDeleted(context, appWidgetIds);
}
@Override
public void onDisabled(Context context) {
super.onDisabled(context);
}
@Override
public void onEnabled(Context context) {
super.onEnabled(context);
}
@Override
public void onReceive(Context context, Intent intent) {
AppWidgetManager mgr = AppWidgetManager.getInstance(context);
if (intent.getAction().equals(TOAST_ACTION)) {
int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
int viewIndex = intent.getIntExtra(EXTRA_ITEM, 0);
Toast.makeText(context, "Touched view " + viewIndex, Toast.LENGTH_SHORT).show();
}
super.onReceive(context, intent);
}
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
for (int i = 0; i < appWidgetIds.length; ++i)
Intent intent = new Intent(context, NewsWidgetService.class);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]);
intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.scroll_widget);
rv.setRemoteAdapter( R.id.stack_view, intent);
rv.setEmptyView(R.id.stack_view, R.id.empty_view);
Intent toastIntent = new Intent(context, NewsWidgetProvider.class);
toastIntent.setAction(NewsWidgetProvider.TOAST_ACTION);
toastIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]);
intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
PendingIntent toastPendingIntent = PendingIntent.getBroadcast(context, 0, toastIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
rv.setPendingIntentTemplate(R.id.stack_view, toastPendingIntent);
// !!!!!! ?????
appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetIds[i], R.id.stack_view);
appWidgetManager.updateAppWidget(appWidgetIds[i], rv);
}
super.onUpdate(context, appWidgetManager, appWidgetIds);
}
}
ОТ.Разработка программного обеспечения в течение 20 лет (Python, Javascript, VB и т. Д.), И я все ближе к Android.Возможно, это первоначальное разочарование от необходимости каждый раз понимать, как что-то делать, но я не вижу адекватной абстракции.Больше, чем программирование, вам нужно знать, какой объект использовать, каковы его методы и параметры, какова логика, которая имела в виду, кто создал объект ... Какой смысл в этом?