Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I'll assume that you're using an AsyncTask for loading the cursor just for the sake of the explanation, but it would work the same if you're using a Loader, an ThreadPool or whatever.</p> <p>From the service, as soon as new data was changed I would send a <code>LocalBroadcast</code>. The activity might be there or not, so a broadcast is a good way to let it know there's new data. So from the service you would do:</p> <pre><code> // that's an example, let's say your SyncAdapter updated the album with this ID // but you could create a simply "mybroadcast", up to you. Intent i = new Intent("albumId_" + albumId); LocalBroadcastManager.getInstance(this).sendBroadcast(i); </code></pre> <p>and then from the activity/fragment that have the Cursor, you'll be listening to this broadcast like this:</p> <pre><code> public void onResume(){ // the filter matches the broadcast IntentFilter filter = new IntentFilter("albumId_" + albumId); LocalBroadcastManager.getInstance(this).registerReceiver(myReceiver, filter); } public void onPause(){ LocalBroadcastManager.getInstance(this).unregisterReceiver(myReceiver); } // and of course you have to create a BroadcastReceiver private BroadcastReceiver myReceiver = new BroadcastReceiver(){ @Override public void onReceive(Context context, Intent intent){ // here you know that your data have changed, so it's time to reload it reloadData = new ReloadData().execute(); // you should cancel this task onPause() } }; </code></pre> <p>as I said, this next part varies depending on what threading method you're using to load the Cursor, for this example I'll show in a AsyncTask because it's very popular (but I really believe you and every developer in the world should use the Loaders pattern).</p> <pre><code>private class ReloadData extends AsyncTask&lt;Void, Void, Cursor&gt; { protected Cursor doInBackground(Void... void) { // here you query your data base and return the new cursor ... query ... return cursor; } protected void onPostExecute(Cursor result) { // you said you're using a subclass of CursorAdater // so you have the method changeCursor, that changes the cursor and closes the old one myAdapter.changeCursor(result); } </code></pre> <p>}</p> <p>The above approach I tested and used before and I know it works. There's a way of making it work with the flag <code>FLAG_REGISTER_CONTENT_OBSERVER</code> and override <code>onContentChanged()</code> to re-execute the query and swap the cursor, but I've never tested it. It will be something like that:</p> <p>init your adapter with the constructor <code>CursorAdapter(Context context, Cursor c, int flags)</code> passing the flag <code>FLAG_REGISTER_CONTENT_OBSERVER</code> and override <code>onContentChanged()</code>. Inside onContentChanged you will execute the AsyncTask just like above. This way you don't have to use the <code>LocalBroadcastManager</code> as the database will alert. The reason that method is not my main answer, it's because I've never tested it.</p> <p>Note that <code>autoRequery</code> have been deprecated and it's discouraged as it performs data loading in the UI thread.</p> <p><strong>edit:</strong></p> <p>I just noticed that the content observer is an API 11 thing. You have two options: 1 use the support library instead: <a href="https://developer.android.com/reference/android/support/v4/widget/CursorAdapter.html" rel="nofollow">https://developer.android.com/reference/android/support/v4/widget/CursorAdapter.html</a> or the broadcast option.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload