-1

I am trying to export my SQLite database to CSV, using ExportDatabaseCSVTask.

After several corrections, this is how this looks like:

Upon the button click in CatalogActivity:

@Override
    public boolean onOptionsItemSelected(MenuItem item) {
        //export data to CSV using method in InventoryProvider via separate java class ExportDatabaseCSVTask
            case  R.id.export_to_csv:
                tryExporting();
              return true;
        }
        return super.onOptionsItemSelected(item);
    }


    public void tryExporting() {
        if (ContextCompat.checkSelfPermission(this,
                Manifest.permission.READ_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 1);
            return;
        }
        new ExportDatabaseCSVTask(this).execute();
    }


    @Override
    public void onRequestPermissionsResult(int requestCode,
                                           @NonNull String permissions[], @NonNull int[] grantResults) {
        switch (requestCode) {
            case REQUEST_READ_EXTERNAL_STORAGE: {
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    new ExportDatabaseCSVTask(this).execute();
                }
            }
        }

and this is the class that is trigerred

            public class ExportDatabaseCSVTask extends AsyncTask<String, String, Boolean> {
        SQLiteDatabase database;
        private Context context;
        private ProgressDialog dialog;
        InventoryProvider iProvider;
        InventoryDbHelper mDbHelper;

        public ExportDatabaseCSVTask(Context context) {
            this.context = context;
        }

        @Override
        protected void onPreExecute() {

            if (dialog == null) {
                dialog = new ProgressDialog(context);
                dialog.setMessage("Downloading Files... Please Wait...");
                dialog.show();
            }

        }



        @TargetApi(Build.VERSION_CODES.O)
        protected Boolean doInBackground(final String... args) {
            File exportDir = new File(Environment.getExternalStorageDirectory(), "/codesss/");

        if (!exportDir.exists()) { exportDir.mkdirs();
            if(!exportDir.mkdirs()) {
                Log.e("mDebug", "Couldn't get the directory"); 
            }
        }
                File file = new File(exportDir, "inventory.csv");
                try {
                    file.createNewFile();
                    if(!file.createNewFile()) {
                        Log.e("mDebug", "Couldn't create the file"); --> ERROR HERE result is ignored error
                    }


CSVWriter csvWrite = new CSVWriter(new FileWriter(file));
                    database = this.mDbHelper.getWritableDatabase();
                    database = this.mDbHelper.getReadableDatabase();
                    Cursor curCSV = database.rawQuery("SELECT * FROM inventory", null);


                    csvWrite.writeNext(curCSV.getColumnNames());
                    while (curCSV.moveToNext()) {
                        String arrStr[] = null;
                        String[] mySecondStringArray = new String[curCSV.getColumnNames().length];
                        for (int i = 0; i < curCSV.getColumnNames().length; i++) {
                            mySecondStringArray[i] = curCSV.getString(i);
                        }
                        csvWrite.writeNext(mySecondStringArray);
                    }

                    csvWrite.close();
                    curCSV.close();
                    return true;
                } catch (IOException e) {
                    return false;
                }
            }



        protected void onPostExecute(final Boolean success) {
            if (dialog != null) {
                if (dialog.isShowing()) { dialog.dismiss();
                 dialog = null;
                }
            }
          // if ((dialog != null)) { this.dialog.dismiss(); }
           if (success) {
               Toast.makeText(context, "Export successful!", Toast.LENGTH_SHORT).show();
     ShareFile();
            } else {
                Toast.makeText(context, "Export failed", Toast.LENGTH_SHORT).show();
           }
        }

     private void ShareFile() {
            File exportDir = new File(Environment.getExternalStorageDirectory(), "/codesss/");
            String fileName = "inventory.csv";
            File sharingGifFile = new File(exportDir, fileName);
            Intent shareIntent = new Intent(android.content.Intent.ACTION_SEND);
            shareIntent.setType("application/csv");
            Uri uri = Uri.fromFile(sharingGifFile);
            shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
            context.startActivity(Intent.createChooser(shareIntent, "Share CSV"));
        }
    }

Permissions already added

   <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

Update

So, now the error is with creating the file. Result of file.createNewFile(); is ignored

Debug shows that folder is created - D/myAppName: folder exist:/storage/emulated/0/codesss But, its empty, no folder exists.

Created separate question for this new issue - Exporting SQLite Database to csv file in android

Guest123
  • 11
  • 7
  • Did you forget `execute()`?: `new ExportDatabaseCSVTask(this).execute();` – forpas Mar 03 '19 at 10:02
  • yes, you are right, didn't notice :( thank you very much! The problem still persists though, as the Logcat displays error as E/WindowManager: android.view.WindowLeaked: Activity com.example.android.stockpile.CatalogActivity has leaked window DecorView@72cebd7[] that was originally added here – Guest123 Mar 03 '19 at 10:27

1 Answers1

0

In onPreExecute() change to this:

if (dialog == null) {
    dialog = new ProgressDialog(context);
    dialog.setMessage("Downloading Files... Please Wait...");
}

so that you don't create a new Dialog each time.
In onPostExecute() again check for null:

if (dialog != null) {
    if (dialog.isShowing()) { 
        dialog.dismiss(); 
        dialog = null;
    }
}

Also since this dialog id created with the context of CatalogActivity make sure that this activity is not closed while the dialog is shown.
Also change all:

Toast.makeText(CatalogActivity.getApplicationContext...

with

Toast.makeText(context....
forpas
  • 160,666
  • 10
  • 38
  • 76
  • I also added '' this.dialog.show();'' to PreExecute, as otherwise dialog is not appearing. Unfortunately, app is crashing. The dialog appears for few seconds, and app crashes with same error ---- CatalogActivity has leaked window DecorView@2c9348a[] – Guest123 Mar 03 '19 at 11:40
  • Error on this line --> this.dialog.show(); Without this line, as per your suggestion, app crashes with a null pointer (Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference) on this toast message ----- Toast.makeText(CatalogActivity.getApplicationContext, "Export Failed", Toast.LENGTH_SHORT).show(); – Guest123 Mar 03 '19 at 11:44
  • Also for `CatalogActivity.getApplicationContext.startActivity` change to `context.startActivity` – forpas Mar 03 '19 at 11:53
  • after changing to context, the following error: **An error occurred while executing doInBackground() Caused by: java.lang.RuntimeException: Can't toast on a thread that has not called Looper.prepare().** .........................Pointing to Toast.makeText(context, "Export Failed", Toast.LENGTH_SHORT).show(); & public class ExportDatabaseCSVTask extends AsyncTask { – Guest123 Mar 03 '19 at 11:54
  • yes, changed everywhere from CatalogActivity.getApplicationContext to just context – Guest123 Mar 03 '19 at 11:55
  • Just make sure that the context which is the activity's context is valid, meaning that the activity is not closed while this process is active. – forpas Mar 03 '19 at 12:02
  • yes, that makes sense, thanks a lot for pointing this out! Now the app ''runs'' saying Export Failed from onPostExecute method. it's highlighting **exportDir.mkdirs()** and **file.createNewFile();** - as ''result is ignored'' – Guest123 Mar 03 '19 at 12:20
  • Hi, I am voting for your answer as you clearly explained what was wrong with the error as per my question. Now, I am dealing with an issue where no folder or file visible, created separate question. – Guest123 Mar 03 '19 at 19:53