0

I'm trying to work with ContentProvider and SyncAdapter, I got all my files setup and all, it's working fine. What I'm actually doing is that, I'm using the syncadapter to to send data to my Server, but I want it to delete it after sending, but Instead, it keeps on sending data repeatedly till it gets this error and crash:

09-02 21:34:57.207: E/dalvikvm-heap(8505): Generating hprof for process: com.deliveryscience.track:sync PID: 8505
09-02 21:35:12.113: E/dalvikvm(8505): can't open /data/misc/app_oom.hprof: Permission denied
09-02 21:35:12.183: E/dalvikvm-heap(8505):  hprofDumpHeap failed with result: -1 
09-02 21:35:12.183: E/dalvikvm-heap(8505): After hprofDumpHeap for process
09-02 21:35:12.183: E/dalvikvm(8505): Out of memory: Heap Size=196608KB, Allocated=189573KB, Limit=196608KB, Proc Limit=196608KB
09-02 21:35:12.193: E/dalvikvm(8505): Extra info: Footprint=195472KB, Allowed Footprint=196608KB, Trimmed=16KB

And below is my code too, all I just want it to do is Loop through and delete each line on the database as it loops through.

public void sendData(ContentProviderClient provider){

        Uri uri = Uri.parse("content://com.example.track.services/ds");
        Log.d("Uri Url:", uri.toString());
        try {
            Log.e("Oya:", "I'm here in the sync");
            final Cursor cursor = provider.query(uri, null, "", null, "");
            //cursor
            int j = cursor.getCount();

            if (cursor.getCount() == 0) {
                Account newAccount = new Account("dummyAcct", "com.example.track");
                AccountManager mgr = (AccountManager) getContext().getSystemService(Context.ACCOUNT_SERVICE);
                // If the account already exists no harm is done but
                // a warning will be logged.
                mgr.addAccountExplicitly(newAccount, null, null);
                int syncOnOff = 0;
                ContentResolver.setIsSyncable(newAccount, "com.example.track.services", syncOnOff);
            }else {

                Log.w("colum", String.valueOf(cursor.getCount()));
                if (cursor.moveToFirst()) {
                    do {
                        String link = cursor.getString(cursor.getColumnIndex("token_id"));
                        String URL_Update = "http://dev.tracking.co/locations/add.json?token=" + link;
                        Log.d("Sync Url:", URL_Update);
                        StringRequest req = new StringRequest(Request.Method.POST ,URL_Update, 
                                new Response.Listener<String>() {

                                    @Override
                                    public void onResponse(String response) {
                                        // TODO Auto-generated method stub
                                        Log.e("str Response:", response);
                                    }

                        }, new Response.ErrorListener() {

                            @Override
                            public void onErrorResponse(VolleyError error) {
                                // TODO Auto-generated method stub

                            }


                        }){
                            @Override
                            protected Map<String,String> getParams(){
                                Map<String,String> params = new HashMap<String, String>();
                                params.put("device_id",cursor.getString(cursor.getColumnIndex("device_id")));
                                params.put("latitude",cursor.getString(cursor.getColumnIndex("lat")));
                                params.put("longitude", cursor.getString(cursor.getColumnIndex("long")));
                                params.put("time", cursor.getString(cursor.getColumnIndex("time")));
                     Log.d("Parameter", params.toString());
                                return params;
                            }
                        };

                        AppController.getInstance().addToRequestQueue(req);
                        //Uri id = Uri.parse(cursor.getString(cursor.getColumnIndex(MyContract._ID)));
                        //provider.delete(id, null, null);
                        cursor.moveToNext();
                    } while (cursor.moveToLast());
                }
            }

        } catch (RemoteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

And also, how do I attach 3 Content Providers to one Sync Adapter. And also, looking at my App in the Sync Section of my phone, it only allows "REMOVE", the "SYNC NOW" option is disabled, but if I press the general Sync button, it syncs

2 Answers2

1

The reason your loop is going on forever is the use of while(cursor.moveToLast()) - this always succeeds as you keep moving to the last row over and over again. You should instead use isAfterLast() to check to see if you are done processing all the data.

Of course, your delete statement should probably be in onResponse so you don't delete records until they are successfully sent.

ianhanniballake
  • 191,609
  • 30
  • 470
  • 443
0

You should apply your cursor loop something like that...

final Cursor cursor = provider.query(uri, null, "", null, "");

 int j = cursor.getCount();

 if(j==0){
  //do your stuff
} else {

  cursor.moveToFirst();

 do {

  //do your stuff

  cursor.moveToNext(); //Note that this statement should be the last one for your particular iteration of the loop

} while(!cursor.isAfterLast());

}

EDITED: According to android developers documentation

Sync adapters run asynchronously, so you should use them with the expectation that they transfer data regularly and efficiently, but not instantaneously. If you need to do real-time data transfer, you should do it in an AsyncTask or an IntentService.

see this link

XtreemDeveloper
  • 1,132
  • 9
  • 14
  • Thanks, works fine. What of this. How do I attach 3 Content Providers to one Sync Adapter. And also, looking at my App in the Sync Section of my phone, it only allows "REMOVE", the "SYNC NOW" option is disabled, but if I press the general Sync button, it syncs –  Sep 03 '14 at 05:29
  • I know actually, and Async Is what I want actually. The data there would be sent when there's Internet. When there's no Internet, there's a request that tries to send and if error, it saves till there is for the Sync to do it. –  Sep 03 '14 at 06:00