1

I have an app, that has a service (using alarm manager to fire every minute). So while the user browses through the activities of the app, the service fires and updates a local SQLite table ("tbl_messages"). One of the activities holds a ListView with data from that table ("tbl_messages"). When the user is viewing that activity, I need the listview to be refreshed after the service fires and adds records to the table. How can I achieve this?

I use AsyncTask to get records (messages) from an external MySQL table and to insert them into the local SQLite. Where should I put a code and what code should that be?

I use a SimpleCursorAdapter for displaying the data in listView like this:

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_notif);

        ArrayList<String> listItems = new ArrayList<String>();
        SQLiteDatabase db = new myDbHelper(getApplicationContext()).getWritableDatabase();
        Cursor c = db.rawQuery("SELECT * FROM tbl_messages", null);

        String[] fromFieldNames = new String[]
{myDbHelper.DATA_NOT, myDbHelper.TITLU_NOT, myDbHelper.TITLUCONT_NOT, myDbHelper.CONT_NOT};
        int[] toViewIDs = new int[]
{R.id.tv_data,     R.id.tv_titlu,           R.id.tv_subtitlu,     R.id.tv_mesaj};

        // Create adapter 
        SimpleCursorAdapter myCursorAdapter =
                new SimpleCursorAdapter(
                        this,       // Context
                        R.layout.notif_item,    // Row layout template
                        c,              // cursor (set of DB records to map)
                        fromFieldNames,     // DB Column names
                        toViewIDs           // View IDs to put information in
                );

        // Set the adapter for the list view
        ListView myList = (ListView) findViewById(R.id.lv_notificari);
        myList.setAdapter(myCursorAdapter);
        myCursorAdapter.notifyDataSetChanged();
}

So this is done onCreate of the messagesActivity

How can I notifyDataSetChanged() from my AsyncTask class? Because my Adapter is declare locally in the activity onCreate, and it's not accessible from the service/AsyncTask class

Thank you

user1137313
  • 2,390
  • 9
  • 44
  • 91
  • Any reason for not declaring it globally? – Lazy Ninja Apr 11 '14 at 00:46
  • Why would you use an `AsyncTask` in a `Service`? The whole point of an `AsyncTask` is it allows a separate thread to do work but its other methods can interact with the UI elements of an `Activity`. – Squonk Apr 11 '14 at 00:49
  • Squonk - I do not want my communication with the remote server to freeze my activities, that is why I use AsyncTask. – user1137313 Apr 11 '14 at 01:23
  • Lazy Ninja - I do not know how to do that :( I know how to do it with simple variables but not with a Adapter. Can you share the code for it? – user1137313 Apr 11 '14 at 01:30
  • Squonk - A NetworkOnMainThreadException is thrown when an application attempts to perform a networking operation on its main thread. This is only thrown for applications targeting the Honeycomb SDK or higher. Applications targeting earlier SDK versions are allowed to do networking on their main event loop threads, but it's heavily discouraged. The easiest way to do this is to use of an AsyncTask, which allows you to perform asynchronous work on your user interface – user1137313 Apr 11 '14 at 09:37

3 Answers3

0

You need to bridge the gap somehow between the event in your service and the adapter in your activity.

You can poke holes through your APIs, and pass the reference to your adapter down into your service.

Or you can issue intents from your service to notify your activity of the event.

Bertrand
  • 3
  • 3
0

you don't need an AsyncTask in a Service because it does not run in UI thread, you may notify your Activity by using LocalBroadcastManager here a sample (just found using Google, search for LocalBroadcastManager for other examples) http://www.intertech.com/Blog/using-localbroadcastmanager-in-service-to-activity-communications/

sherpya
  • 4,890
  • 2
  • 34
  • 50
  • I don't agree with you, please take a look at http://stackoverflow.com/questions/7875926/does-android-service-run-from-a-seperated-thread-instead-of-ui. Activity and service should both run main thread, which should be your UI thread. – user1484819 Apr 11 '14 at 01:25
  • If I run the HTTPPost directly in the service I get NetworkOnMainThreadException. Seems like IT IS running in the UI Thread. So I should be using AsyncTask after all. – user1137313 Apr 11 '14 at 09:40
  • I see in the link provided by you information on how to send Extras to an intent/Activity... But I want to access the listview's adapter not send Extras – user1137313 Apr 11 '14 at 09:50
  • sherpya - Check this out: http://stackoverflow.com/questions/7875926/does-android-service-run-from-a-seperated-thread-instead-of-ui?lq=1 It really looks like I HAVE to use AsyncTask – user1137313 Apr 11 '14 at 09:51
  • yes I'm talking about `IntentService`, you can still use a simple `thread`, my suggestion about `LocalBroadcastManager` for the communication is still valid – sherpya Apr 11 '14 at 16:41
0

you can use the content provider whenever any data is modified, the ContentProvider notifies ContentResolver about the changes then the ContentResolver notifies all registered observers.

use android:export= "false" because you are not exposing this content provider uri to other application.

One useful thing it provides data change notifications (based on data URIs). In practice, it means that ListViews with content provider-supplied data refresh automatically, and it's really easy to make other UI elements also update automatically by registering data change observers (see ContentResolver in android).

see http://developer.android.com/guide/topics/providers/content-provider-basics.html.

MANISH PATHAK
  • 2,602
  • 4
  • 27
  • 31