1

I'm building a simple backup app for android and this code reads and stores all the messages in the phone memory to a csv file,initially i was displaying an indeterminate progress bar,but the user of the app might get impatient with that (if their messages are too many) so i wanted to add a determinate horizontal progress bar to show them the actual progress,i've been trying to do this for sometime now but i can't get it right,i know i'm supposed to use the onProgressUpdate method in the async task class, but i don't really know how to implement that so i'm getting a lot of exceptions,so i was tried doing it in a different without the method and this is the code below

package daniel.idea.backup;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.provider.ContactsContract;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity implements OnClickListener {


 public ArrayList<String> smsBuffer = new ArrayList<String>();
 String smsFile = "SMS"+".csv";
 Integer x = 0;
 static Integer Total = 0;


//Initialize the various ui elements
Button contact,msg;
ProgressDialog pb;
TextView total;
static Context mContext;

//Method to fetch and write the contacts to the .vcf file

 public static String getVCF() {
     final String vfile = "Contacts.vcf";
     Cursor phones = mContext.getContentResolver().query(
     ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
     phones.moveToFirst();
     Total = phones.getCount();
     for (int i = 0; i < phones.getCount(); i++) {
         String lookupKey = phones.getString(phones.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
         Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_VCARD_URI, lookupKey);
         AssetFileDescriptor fd;
         try {
             fd = mContext.getContentResolver().openAssetFileDescriptor(uri, "r");
             FileInputStream fis = fd.createInputStream();
             byte[] buf = new byte[(int) fd.getDeclaredLength()];
             fis.read(buf);
             String VCard = new String(buf);
             String path = Environment.getExternalStorageDirectory().toString() + File.separator + vfile;
             FileOutputStream mFileOutputStream = new FileOutputStream(path, true);
             mFileOutputStream.write(VCard.toString().getBytes());
             phones.moveToNext();
             Log.d("Vcard", VCard);
             mFileOutputStream.close();
         } catch (Exception e1) {
             // TODO Auto-generated catch block
             e1.printStackTrace();
         }
     }
    return phones.getCount()+ " Contacts";
 }


 //This is the method used to get the sms and save them to a file

        private String  backupSMS(){
        smsBuffer.clear();
        Uri mSmsinboxQueryUri = Uri.parse("content://sms");
        Cursor cursor1 = mContext.getContentResolver().query(
                mSmsinboxQueryUri,
                new String[] { "_id", "thread_id", "address", "person", "date",
                        "body", "type" }, null, null, null);
        //startManagingCursor(cursor1);
        String[] columns = new String[] { "_id", "thread_id", "address", "person", "date", "body",
                "type" };
        if (cursor1.getCount() > 0) {
            String count = Integer.toString(cursor1.getCount());
            Log.d("Count",count);
            while (cursor1.moveToNext()) {

                 String messageId = cursor1.getString(cursor1
                        .getColumnIndex(columns[0]));

                 String threadId = cursor1.getString(cursor1
                        .getColumnIndex(columns[1]));

                String address = cursor1.getString(cursor1
                        .getColumnIndex(columns[2]));
                String name = cursor1.getString(cursor1
                        .getColumnIndex(columns[3]));
                String date = cursor1.getString(cursor1
                        .getColumnIndex(columns[4]));
                String msg = cursor1.getString(cursor1
                        .getColumnIndex(columns[5]));
                String type = cursor1.getString(cursor1
                        .getColumnIndex(columns[6]));



                smsBuffer.add(messageId + ","+ threadId+ ","+ address + "," + name + "," + date + " ," + msg + " ,"
                        + type);


            }           
            generateCSVFileForSMS(smsBuffer);

        }
        return cursor1.getCount() + "Messages";         
    }


     private void generateCSVFileForSMS(ArrayList<String> list)
    {

        try 
        {
            String storage_path = Environment.getExternalStorageDirectory().toString() + File.separator + smsFile;
            FileWriter write = new FileWriter(storage_path);

            write.append("messageId, threadId, Address, Name, Date, msg, type");
            write.append('\n');

            for (String s : list)
            {
                write.append(s);
                write.append('\n');
            }
            write.flush();
            write.close();
        }

        catch (NullPointerException e) 
        {
            System.out.println("Nullpointer Exception "+e);
             //  e.printStackTrace();
         }
        catch (IOException e) 
        {
            e.printStackTrace();
        }
        catch (Exception e) 
        {
            e.printStackTrace();
       }

    }


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

    mContext = MainActivity.this;
    Cursor phones_total = mContext.getContentResolver().query(
    ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);

    //This gets the count of all the contacts in the phone memory
    Integer total_contacts = phones_total.getCount();

    contact = (Button) findViewById (R.id.bt_contacts);
    msg = (Button) findViewById (R.id.bt_messages);
    total = (TextView) findViewById (R.id.tv_total);


    contact.setOnClickListener(this);
    msg.setOnClickListener(this);
    total.setText(total_contacts +" Contacts");
}

@Override
public void onClick(View v) {
    // TODO Auto-generated method stub

    switch(v.getId()){

    case R.id.bt_contacts:

        MyTask task = new MyTask();
        task.execute("Param 1","Param2","Param3");


        break;

    case R.id.bt_messages:

         SmsTask task2 = new SmsTask();
         task2.execute();
    }

}


public class MyTask extends AsyncTask<String, Integer, String>{

    @Override
    protected void onPreExecute() {

        //make the progressDialog
        pb = new ProgressDialog(MainActivity.this);
        pb.setTitle("Please wait ...");
        pb.setIndeterminate(false);
        pb.setMessage("Backing up contacts...");
        pb.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        pb.setProgress(0);
        pb.setMax(100);
        pb.show();


    }

    @Override
    protected String doInBackground(String... arg0) {
        // TODO Auto-generated method stub
        mContext = MainActivity.this;

        String total_c = getVCF();

         //Increment the progress dialog

        for(int i = 0; i < Total; i++){

            publishProgress(i);

        }

        return total_c;

    }

    @Override
    protected void onPostExecute(String result) {
        // TODO Auto-generated method stub
        super.onPostExecute(result);

        //hide the progress bar and display a toast message

        pb.dismiss();
        Toast.makeText(MainActivity.this, result + " Succesfully backed up", Toast.LENGTH_LONG).show();


    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        // TODO Auto-generated method stub
        super.onProgressUpdate(values);

        pb.incrementProgressBy(values[0]);

        values[0]++;
    }


}


public class SmsTask extends AsyncTask <String,Integer,String>{


        protected void onPreExecute() {

            //show the progress bar
            pb = ProgressDialog.show(MainActivity.this, "Processing",
                    "please wait", true);

            }


        @Override
        protected String doInBackground(String... params) {
            // TODO Auto-generated method stub
            mContext = MainActivity.this;

            String total_sms = backupSMS();

            return total_sms;



        }


        @Override
        protected void onPostExecute(String result) {
            // TODO Auto-generated method stub
            super.onPostExecute(result);

            //hide the progress bar and display a toast

            pb.dismiss();
            Toast.makeText(MainActivity.this, result + " Succesfully backed up", Toast.LENGTH_LONG).show();



    }



}



}

The progress bar shows up but it dosen't update...apart from this the code works flawlessly...please i need suggestions on how i can implement a determinate progess bar into this code.Thanks

EDIT: I've gone throught the two answers posted, and i've re-written my code, instead of the progress bar updating it just skips from 0 to 100 when it's done, please can someone point out my mistake in this code

danidee
  • 9,298
  • 2
  • 35
  • 55
  • Hey,I know post is old but I came up with a (not so good) resolution, in case you still need it or anyone else, I just use `sleep(1)` in the `AsyncTask`. This allows the main thread to execute (update progress bar) since its blocked by the `AsyncTask` thread. Though this affects performance, I haven't found a better way, here's more info on [my question](https://stackoverflow.com/questions/65913512/updating-progress-bar-atomically-immediately-after-update-in-asynctask) – Jore Jan 30 '21 at 20:36

3 Answers3

3

I don't see you updating a progress bar anywhere in your code. Maybe because there is so much irrelevant code around it...

But here is what you have to do:

AsyncTask has no access to the UI from it's method doInBackground(). You can only access the UI from the onProgressUpdate() function during the execution of your AsyncTask. You did not define this function, so there cannot be performed any update.

Documentation: onProgressUpdate()

PKlumpp
  • 4,913
  • 8
  • 36
  • 64
0

You want to show the progress with your progress dialog ..like an integer..Loading..45%

if so, this link will help you

android how to work with asynctasks progressdialog

Community
  • 1
  • 1
Meenal
  • 2,879
  • 5
  • 19
  • 43
0

This is an old post, but I thought I'd chime in and see if I could help resolve it. The reason you're not getting the progress to update is because you have to make a call to publishProgress() within your main while() loop inside doInBackground(). The resources linked in the other answers should detail how to use the publishProgress() command!

ConcernedHobbit
  • 764
  • 1
  • 8
  • 17