4

In my application, I am accessing call log and text messages using getContentResolver() It means I am working with android content-provider. That getContentResolver() is running in a background service. Everything is okay, but my main challenge is this: whenever I start the service to run the codes which extract call log and text messages, the content provider blocks my main thread of execution. I tried to put those codes in a different thread of execution, but nothing is changing.

I really need help; how can I avoid that? Because the application is continually giving a ANR (Application Not Responding) message on devices which have small RAM and PROCESSORS.

In case you need me to show codes, I am ready to paste if is really needed.

UPDATE: (codes in a background service)

public class Getting_Call_log_Service extends Service {

//variables of getting call logs
private String ph_number;
private String temp_name;
private String real_name;
private String call_type;
private String dir;
private String call_date;
private String call_duration;
private Date call_day_time;
private SQLite_database_helper_class myDb;

public  class callsThread implements Runnable{
    callsThread(){}

    @Override
    public void run() {

            myDb=new SQLite_database_helper_class(getApplicationContext());
            //codes of extracting call logs
            Cursor cursor = getContentResolver().query(CallLog.Calls.CONTENT_URI,
                    null,null,null,null);

            int number=cursor.getColumnIndex(CallLog.Calls.NUMBER);//to get the index of phoneNumber column
            int name = cursor.getColumnIndex(CallLog.Calls.CACHED_NAME);//to get the index of contact name column
            int type = cursor.getColumnIndex(CallLog.Calls.TYPE);//to get the call type index
            int callDate = cursor.getColumnIndex(CallLog.Calls.DATE);//to get the date of calling
            int callDuration = cursor.getColumnIndex(CallLog.Calls.DURATION);//to get the duration of calling


            cursor.moveToFirst();

                do {

                    //extracting values from phone history
                    ph_number=cursor.getString(number);
                    temp_name=cursor.getString(name);
                    if (temp_name==null){
                        real_name="Annonymous caller!";
                    }else {
                        real_name=temp_name;
                    }
                    call_type=cursor.getString(type);
                    int dir_code=Integer.parseInt(call_type);
                    switch (dir_code) {
                        case CallLog.Calls.INCOMING_TYPE:
                            dir = "INCOMING CALL";
                            break;
                        case CallLog.Calls.OUTGOING_TYPE:
                            dir = "OUTGOING CALL";
                            break;

                        case CallLog.Calls.MISSED_TYPE:
                            dir = "MISSED CALL";
                            break;
                        case CallLog.Calls.REJECTED_TYPE:
                            dir = "REJECTED CALL";
                            break;
                        case CallLog.Calls.ANSWERED_EXTERNALLY_TYPE:
                            dir = "ANSWERED EXTERNALLY";
                            break;
                        case CallLog.Calls.BLOCKED_TYPE:
                            dir = "BLOCKED NUMBER";
                            break;
                        case CallLog.Calls.VOICEMAIL_TYPE:
                            dir = "VOICEMAIL";
                            break;
                    }
                    call_date=cursor.getString(callDate);
                    call_day_time=new Date(Long.valueOf(call_date));

                    call_duration=cursor.getString(callDuration);
                    //end of extraction

                            myDb.saving_call_logs(ph_number,real_name,dir,
                                    call_day_time.toString(), call_duration);
                }while (cursor.moveToNext());
                cursor.close();

        }
    }

public void calls_fromPhone(){

    Thread callThread=new Thread(new callsThread());
    callThread.start();

}


private void call_retriever(){

        TelephonyManager telephonyManager=(TelephonyManager)getSystemService(
                Context.TELEPHONY_SERVICE);

        PhoneStateListener phoneStateListener=new PhoneStateListener(){

            @Override
            public void onCallStateChanged(int state,String inComingNumber){
                if (state==TelephonyManager.CALL_STATE_IDLE){
                    //do stuff here

                    calls_fromPhone();
}

};
  telephonyManager.listen(phoneStateListener,
PhoneStateListener.LISTEN_CALL_STATE);
    }
@Override
public int onStartCommand(Intent intent,int flags, int startId){

    call_retriever();
return START_STICKY;
}
Mugirase Emmanuel
  • 385
  • 1
  • 5
  • 14
  • can you update your question with code which runs tasks in background and way use `ContentProvider`? – Sagar Jun 14 '18 at 10:42
  • `That getContentResolver() is running in a background service. ` ??? What do you mean exactly? Please elaborate and show code. – greenapps Jun 14 '18 at 10:45
  • `the content provider blocks my main thread of execution.` Dont think so. It will be the code where you use getContentResolver() that blocks if you dont do that in a thread. – greenapps Jun 14 '18 at 10:47
  • @sagar read my question updated with codes – Mugirase Emmanuel Jun 14 '18 at 10:53
  • @greeapps I updated the question and removed all bads but i really need a help – Mugirase Emmanuel Jun 14 '18 at 10:55
  • use `Asynctask` and do all your cursor related work in its `doInBackground` as `Runnable` thread run on UI thread and cursor related work blocks it – Kapil Rajput Jun 14 '18 at 11:16
  • are you doing anything else in the Service? from where are you calling `calls_fromPhone()` ? – Sagar Jun 14 '18 at 11:17
  • `use Asynctask and do all your cursor related work in its doInBackground as Runnable thread run on UI thread and cursor related work blocks it –` That all is not true. A very bad advise. – greenapps Jun 14 '18 at 11:26
  • You use a thread to do all the stuf. That is the way to go. I cannot believe that your content provider would block the gui. An interesting problem indeed. – greenapps Jun 14 '18 at 11:27
  • It is more: what are you doing before and after `calls_fromPhone()` is called? Please answer to Sagan. – greenapps Jun 14 '18 at 11:30
  • Please also show how you instantiate/start this service. – greenapps Jun 14 '18 at 11:31
  • 1
    `public void calls_fromPhone()` Aha... public? Are you starting this server with the `new` operator ? Dont do that. Use an intent. You are not supposed to call that function from outside the service. Make it `private void calls_fromPhone()` and call it from `onStartCommand`. – greenapps Jun 14 '18 at 11:39
  • @sagar and @greenapps review my updated code. `calls_fromPhone()` I am calling it in another method which listens to phone state and perform all the actions of retrieving call log and save them in a database. That methode is called in `onStartCommand()` method of my service. – Mugirase Emmanuel Jun 14 '18 at 12:06
  • how do you start the service? – Sagar Jun 14 '18 at 12:11
  • @Sagar I start it by a button click in main activity, or whenever a device reboots, it start automatically – Mugirase Emmanuel Jun 14 '18 at 12:23
  • I mean, the code. Do use `startService` or `startForegroundService` – Sagar Jun 14 '18 at 12:32
  • I use `startService(...)` – Mugirase Emmanuel Jun 14 '18 at 12:35

0 Answers0