我有一个在后台运行的Intent service
,它改变了存储在设备的SQLite
数据库中的一些值。在前台打开了一个活动,该活动对用户可见。活动向用户显示一些值,这些值由Intent Service
更改。如何在不要求用户刷新活动的情况下更改这些值并与SQLite
同步?
Android操作系统:奥利奥
有几种方法可以实现这一点,其中一种方法是使用界面。
在服务中:
public class MyService extends Service {
private Callbacks callback;
//Other codes
//.....
callback.updateClient(data) //trigger interface callback in appropriate place
//Other codes
//.....
public interface Callbacks{ //define interface according to your need
public void updateClient(long data);
}
}
在活动中:
public class MainActivity extends Activity implements MyService.Callbacks{
@Override
public void updateClient(long data) {
// change UI
}
}
在我的应用程序中,我运行服务来更新小部件,在MainActivity中启动服务:
private void startService() {
startService(new Intent(MainActivity.this, LoadQuotesService.class));
}
类LoadQuotesService
@SuppressLint("Registered")
public class LoadQuotesService extends Service {
@Override
public void onCreate() {
super.onCreate();
AlarmManagerBroadcastReceiver alarm = new AlarmManagerBroadcastReceiver();
alarm.SetAlarm(getBaseContext());
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
类AlarmManager BroadcastReceiver
public class AlarmManagerBroadcastReceiver extends BroadcastReceiver {
final public static String ONE_TIME = "onetime";
private DatabaseQuoteHelper databaseQuoteHelper;
private QuoteBusiness quoteBusiness;
private final String TAG = "AlarmManagerBroadcastReceiver";
@Override
public void onReceive(Context context, Intent intent) {
databaseQuoteHelper = DatabaseQuoteHelper.newInstance(context);
quoteBusiness = QuoteBusiness.newInstance(context);
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
assert pm != null;
PowerManager.WakeLock wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "YOUR TAG");
wakeLock.acquire(10 * 60 * 1000L /*10 minutes*/);
Bundle extras = intent.getExtras();
StringBuilder stringBuilder = new StringBuilder();
if (extras != null && extras.getBoolean(ONE_TIME, Boolean.FALSE)) {
stringBuilder.append("One time Timer : ");
}
@SuppressLint("SimpleDateFormat") Format formatter = new SimpleDateFormat("hh:mm:ss a");
stringBuilder.append(formatter.format(new Date()));
new GetRandomQuote().execute();
wakeLock.release();
}
@SuppressLint("StaticFieldLeak")
class GetRandomQuote extends AsyncTask<Void, Void, Void> {
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Void doInBackground(Void... voids) {
quoteBusiness.getListQuote(Api.GET_LIST_QUOTES_BY_TREND + "NEW/50", new IQuoteListener() {
@Override
public void start() {
}
@Override
public void result(List<Quote> quoteList) {
if (databaseQuoteHelper.getAllQuotes().size() > 0) {
databaseQuoteHelper.deleteAllData();
}
for (int i = 0; i < quoteList.size(); i++) {
Quote quote = quoteList.get(i);
databaseQuoteHelper.insertQuote(quote);
}
}
@Override
public void nil(String message) {
}
@Override
public void error(String err) {
}
});
return null;
}
}
@SuppressLint("ShortAlarm")
public void SetAlarm(Context context) {
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmManagerBroadcastReceiver.class);
intent.putExtra(ONE_TIME, Boolean.FALSE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
assert am != null;
int ONE_DAY = 1000 * 60 * 60 * 24;
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), ONE_DAY, pendingIntent);
}
public void CancelAlarm(Context context) {
Intent intent = new Intent(context, AlarmManagerBroadcastReceiver.class);
PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
assert alarmManager != null;
alarmManager.cancel(sender);
}
public void setOnetimeTimer(Context context) {
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmManagerBroadcastReceiver.class);
intent.putExtra(ONE_TIME, Boolean.TRUE);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0);
assert am != null;
am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), pi);
}
}
当我在我的小部件中显示加载数据时:
public class NewAppWidget extends AppWidgetProvider {
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
for (int appWidgetId : appWidgetIds) {
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.new_app_widget);
DatabaseQuoteHelper databaseQuoteHelper = DatabaseQuoteHelper.newInstance(context);
List<Quote> quoteList = databaseQuoteHelper.getAllQuotes();
if (!quoteList.isEmpty()) {
Random random = new Random();
int rdIndex = random.nextInt(quoteList.size() - 1);
CharSequence quoteContent = quoteList.get(rdIndex).getQuoteContentVN();
CharSequence authorName = quoteList.get(rdIndex).getQuoteAuthorName();
remoteViews.setTextViewText(R.id.appwidget_TvQuoteContent, quoteContent);
remoteViews.setTextViewText(R.id.appwidget_textAuthorName, authorName);
} else {
remoteViews.setTextViewText(R.id.appwidget_TvQuoteContent, context.getString(R.string.not_quote_save));
remoteViews.setTextViewText(R.id.appwidget_textAuthorName, context.getString(R.string.app_name));
}
Intent refresh = new Intent(context, NewAppWidget.class);
refresh.setAction("android.appwidget.action.APPWIDGET_UPDATE");
refresh.putExtra("appWidgetIds", appWidgetIds);
PendingIntent pendingIntentRefresh = PendingIntent.getBroadcast(context, 0, refresh, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.widgetBtnReload, pendingIntentRefresh);
appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
}
}
@Override
public void onEnabled(Context context) {
// Enter relevant functionality for when the first widget is created
}
@Override
public void onDisabled(Context context) {
// Enter relevant functionality for when the last widget is disabled
}
}
它工作正常,希望这有帮助!