Search code examples
androidandroid-contentproviderandroid-syncadapter

Sync Adapter with Content Provider Data Looping and deleting


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


Solution

  • 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.