-2

I created an app with database in assets folder . I wrote a code to copy database to sdcard and of course for android 6 + it needs run time permission. My problem : App copies database before asking for permission so for the first time app crashes but permission window is on screen and if you allow it on second run app works like charm . Please help me to solve this issue .

Here's my code :

package farmani.com.essentialwordsforielts.mainPage;

import android.Manifest;
import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Build;
import android.os.Environment;
import android.support.annotation.NonNull;
import android.support.design.widget.NavigationView;
import android.support.design.widget.TabLayout;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.ViewPager;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Gravity;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import farmani.com.essentialwordsforielts.R;

public class MainActivity extends AppCompatActivity  {

public static Context context;
DrawerLayout drawerLayout;
NavigationView navigationView;
ImageView hamburger;
SQLiteDatabase database;
String destPath;

public static ArrayList<Structure> list = new ArrayList<Structure>();
public static ArrayList<Structure> favorite = new ArrayList<Structure>();

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

    if(Build.VERSION.SDK_INT >= 23){


        if(ContextCompat.checkSelfPermission(MainActivity.this, 
Manifest.permission.READ_EXTERNAL_STORAGE) != 
PackageManager.PERMISSION_GRANTED){

            ActivityCompat.requestPermissions(MainActivity.this
                    , new String[]{Manifest.permission.READ_EXTERNAL_STORAGE
                            ,Manifest.permission.WRITE_EXTERNAL_STORAGE}
                    , 1);

        }else if(ContextCompat.checkSelfPermission(MainActivity.this, 
Manifest.permission.WRITE_EXTERNAL_STORAGE) != 
PackageManager.PERMISSION_GRANTED){

            ActivityCompat.requestPermissions(MainActivity.this
                    , new String[]{Manifest.permission.READ_EXTERNAL_STORAGE
                            ,Manifest.permission.WRITE_EXTERNAL_STORAGE}
                    , 1);

        }else {

            Toast.makeText(MainActivity.this,"You grandet 
earlier",Toast.LENGTH_LONG).show();

        }


    }





    try {
        destPath = 
Environment.getExternalStorageDirectory().getAbsolutePath() + "/ielts/";
        File file = new File(destPath);
        if (!file.exists()) {
            file.mkdirs();
            file.createNewFile();
            CopyDB(getBaseContext().getAssets().open("md_book.db"),
                    new FileOutputStream(destPath + "/md_book.db"));
        }
    } catch (IOException e1) {
        e1.printStackTrace();
    }

    context = getApplicationContext();
    setTabOption();

    drawerLayout = findViewById(R.id.navigation_drawer);
    navigationView = findViewById(R.id.navigation_view);
    hamburger = findViewById(R.id.hamburger);
    hamburger.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            drawerLayout.openDrawer(Gravity.START);
        }
    });




    navigationView.setNavigationItemSelectedListener(new 
NavigationView.OnNavigationItemSelectedListener() {
        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem item) {
            int id = item.getItemId();
            if (id == R.id.exit) {
                AlertDialog.Builder alertDialog = new AlertDialog.Builder(
                        MainActivity.this);

                alertDialog.setTitle(R.string.exit);

                alertDialog.setMessage(R.string.exit_ask);
                alertDialog.setCancelable(false);

                alertDialog.setPositiveButton(R.string.yes,
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int 
which) {
                                finish();
                            }
                        });

                alertDialog.setNegativeButton(R.string.no,
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int 
which) {

                                dialog.cancel();
                            }
                        });

                alertDialog.show();
            }

            return true;
        }
    });

    selectList();
    selectFavorite();


}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] 
permissions, @NonNull int[] grantResults) {

    switch (requestCode) {
        case 1: {

            if (grantResults.length >= 2 && grantResults[0] == 
PackageManager.PERMISSION_GRANTED && grantResults[1] == 
PackageManager.PERMISSION_GRANTED) {

                Toast.makeText(MainActivity.this, "Access granted", 
Toast.LENGTH_LONG).show();

            }

        }
    }
}


@Override
public void onBackPressed() {
    if (drawerLayout.isDrawerOpen(Gravity.START)) {
        drawerLayout.closeDrawer(Gravity.START);
    } else {
        AlertDialog.Builder alertDialog = new AlertDialog.Builder(
                MainActivity.this);

        alertDialog.setTitle(R.string.exit);

        alertDialog.setMessage(R.string.exit_ask);
        alertDialog.setCancelable(false);

        alertDialog.setPositiveButton(R.string.yes,
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        finish();
                    }
                });

        alertDialog.setNegativeButton(R.string.no,
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {

                        dialog.cancel();
                    }
                });

        alertDialog.show();
    }
}


private void setTabOption() {
    ViewPager viewPager = findViewById(R.id.viewpager);
    viewPager.setAdapter(new AdapterFragment(getSupportFragmentManager(), 
context));
    TabLayout tabStrip = findViewById(R.id.tabs);
    tabStrip.setupWithViewPager(viewPager);
}

private void CopyDB(InputStream inputStream, OutputStream outputStream) 
throws IOException {
    byte[] buffer = new byte[1024];
    int length;
    while ((length = inputStream.read(buffer)) > 0) {
        outputStream.write(buffer, 0, length);
    }
    inputStream.close();
    outputStream.close();
}

private void selectFavorite(){

    database = SQLiteDatabase.openOrCreateDatabase(destPath + "/md_book.db", 
null);
    Cursor cursor = database.rawQuery("SELECT * FROM main WHERE fav = 1", 
null);
    while (cursor.moveToNext()){
        String word = cursor.getString(cursor.getColumnIndex("word"));
        String definition = 
cursor.getString(cursor.getColumnIndex("definition"));
        String trans = cursor.getString(cursor.getColumnIndex("trans"));
        String img = cursor.getString(cursor.getColumnIndex("img"));
        int id = cursor.getInt(cursor.getColumnIndex("id"));

        Structure struct = new Structure(word, definition, trans, img, id);
        struct.setWord(word);
        struct.setDefinition(definition);
        struct.setTrans(trans);
        struct.setImg(img);
        struct.setId(id);
        favorite.add(struct);
    }

}

private void selectList(){

    database = SQLiteDatabase.openOrCreateDatabase(destPath + "/md_book.db", 
null);
    Cursor cursor = database.rawQuery("SELECT * FROM main", null);
    while (cursor.moveToNext()){
        String word = cursor.getString(cursor.getColumnIndex("word"));
        String definition = 
cursor.getString(cursor.getColumnIndex("definition"));
        String trans = cursor.getString(cursor.getColumnIndex("trans"));
        String img = cursor.getString(cursor.getColumnIndex("img"));
        int id = cursor.getInt(cursor.getColumnIndex("id"));

        Structure struct = new Structure(word, definition, trans, img, id);
        struct.setWord(word);
        struct.setDefinition(definition);
        struct.setTrans(trans);
        struct.setImg(img);
        struct.setId(id);
        list.add(struct);
    }

    }

}
  • Start by reading https://stackoverflow.com/questions/23353173/unfortunately-myapp-has-stopped-how-can-i-solve-this for some tips about how to track down the cause of the crash. – Code-Apprentice Feb 12 '18 at 21:36
  • I know why it crashes . it tries to copy database before granting permission . I tried to get permission first and then copy database in if clause but it's not helpful – Love Programming Feb 12 '18 at 21:39
  • Requesting permissions is asynchronous. This means that the call does not block and your code will copy the database, as you have seen. Read https://developer.android.com/training/permissions/requesting.html#java for an explanation of how to correctly respond to permission granted or denied. – Code-Apprentice Feb 12 '18 at 21:39
  • did u read my code? I used same method. but still I got problem . – Love Programming Feb 12 '18 at 21:41
  • Which line of code causes the crash? – Code-Apprentice Feb 12 '18 at 21:42
  • this is the log:android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database – Love Programming Feb 12 '18 at 21:52
  • any reason why you're copying to the SDCard? if not, then copy it to the ApplicationStorageDirectory && you don't need to worry about the permissions. – wooldridgetm Feb 12 '18 at 22:07
  • I think I have to change this part destPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/ielts/"; but to what? – Love Programming Feb 12 '18 at 22:15

1 Answers1

0

It is quite simple. Move your Copy DB code into permission granted handling. If you do it in your onCreate prior to having permission you will crash. Bets of luck.

package farmani.com.essentialwordsforielts.mainPage;

        import android.Manifest;
        import android.content.Context;
        import android.content.DialogInterface;
        import android.content.pm.PackageManager;
        import android.database.Cursor;
        import android.database.sqlite.SQLiteDatabase;
        import android.os.Build;
        import android.os.Environment;
        import android.support.annotation.NonNull;
        import android.support.design.widget.NavigationView;
        import android.support.design.widget.TabLayout;
        import android.support.v4.app.ActivityCompat;
        import android.support.v4.content.ContextCompat;
        import android.support.v4.view.ViewPager;
        import android.support.v4.widget.DrawerLayout;
        import android.support.v7.app.AlertDialog;
        import android.support.v7.app.AppCompatActivity;
        import android.os.Bundle;
        import android.view.Gravity;
        import android.view.MenuItem;
        import android.view.View;
        import android.widget.ImageView;
        import android.widget.Toast;
        import java.io.File;
        import java.io.FileOutputStream;
        import java.io.IOException;
        import java.io.InputStream;
        import java.io.OutputStream;
        import java.util.ArrayList;
        import farmani.com.essentialwordsforielts.R;

public class MainActivity extends AppCompatActivity {

    public static Context context;
    DrawerLayout drawerLayout;
    NavigationView navigationView;
    ImageView hamburger;
    SQLiteDatabase database;
    String destPath;

    public static ArrayList<Structure> list = new ArrayList<Structure>();
    public static ArrayList<Structure> favorite = new ArrayList<Structure>();

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

        if(Build.VERSION.SDK_INT >= 23){


            if(ContextCompat.checkSelfPermission(MainActivity.this,
                    Manifest.permission.READ_EXTERNAL_STORAGE) !=
                    PackageManager.PERMISSION_GRANTED){

                ActivityCompat.requestPermissions(MainActivity.this
                        , new String[]{Manifest.permission.READ_EXTERNAL_STORAGE
                                ,Manifest.permission.WRITE_EXTERNAL_STORAGE}
                        , 1);

            }else if(ContextCompat.checkSelfPermission(MainActivity.this,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE) !=
                    PackageManager.PERMISSION_GRANTED){

                ActivityCompat.requestPermissions(MainActivity.this
                        , new String[]{Manifest.permission.READ_EXTERNAL_STORAGE
                                ,Manifest.permission.WRITE_EXTERNAL_STORAGE}
                        , 1);

            }else {

                Toast.makeText(MainActivity.this,"You grandet 
                        earlier",Toast.LENGTH_LONG).show();

            }


        }

        context = getApplicationContext();
        setTabOption();

        drawerLayout = findViewById(R.id.navigation_drawer);
        navigationView = findViewById(R.id.navigation_view);
        hamburger = findViewById(R.id.hamburger);
        hamburger.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                drawerLayout.openDrawer(Gravity.START);
            }
        });







    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode) {
            case 1: {

                if (grantResults.length >= 2 && grantResults[0] ==
                        PackageManager.PERMISSION_GRANTED && grantResults[1] ==
                        PackageManager.PERMISSION_GRANTED) {

                   setupDB();
                   setupNavDrawer();

                    Toast.makeText(MainActivity.this, "Access granted",
                            Toast.LENGTH_LONG).show();

                }

            }
        }
    }


    @Override
    public void onBackPressed() {
        if (drawerLayout.isDrawerOpen(Gravity.START)) {
            drawerLayout.closeDrawer(Gravity.START);
        } else {
            AlertDialog.Builder alertDialog = new AlertDialog.Builder(
                    MainActivity.this);

            alertDialog.setTitle(R.string.exit);

            alertDialog.setMessage(R.string.exit_ask);
            alertDialog.setCancelable(false);

            alertDialog.setPositiveButton(R.string.yes,
                    new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int which) {
                            finish();
                        }
                    });

            alertDialog.setNegativeButton(R.string.no,
                    new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int which) {

                            dialog.cancel();
                        }
                    });

            alertDialog.show();
        }
    }


    private void setTabOption() {
        ViewPager viewPager = findViewById(R.id.viewpager);
        viewPager.setAdapter(new AdapterFragment(getSupportFragmentManager(),
                context));
        TabLayout tabStrip = findViewById(R.id.tabs);
        tabStrip.setupWithViewPager(viewPager);
    }

    private void setupDB(){
        try {
            destPath =
                    Environment.getExternalStorageDirectory().getAbsolutePath() + "/ielts/";
            File file = new File(destPath);
            if (!file.exists()) {
                file.mkdirs();
                file.createNewFile();
                CopyDB(getBaseContext().getAssets().open("md_book.db"),
                        new FileOutputStream(destPath + "/md_book.db"));
            }
        } catch (IOException e1) {
            e1.printStackTrace();
        }
    }
    private void setupNavDrawer(){
        navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                int id = item.getItemId();
                if (id == R.id.exit) {
                    AlertDialog.Builder alertDialog = new AlertDialog.Builder(
                            MainActivity.this);

                    alertDialog.setTitle(R.string.exit);

                    alertDialog.setMessage(R.string.exit_ask);
                    alertDialog.setCancelable(false);

                    alertDialog.setPositiveButton(R.string.yes,
                            new DialogInterface.OnClickListener() {
                                public void onClick(DialogInterface dialog, int
                                        which) {
                                    finish();
                                }
                            });

                    alertDialog.setNegativeButton(R.string.no,
                            new DialogInterface.OnClickListener() {
                                public void onClick(DialogInterface dialog, int
                                        which) {

                                    dialog.cancel();
                                }
                            });

                    alertDialog.show();
                }

                return true;
            }
        });

        selectList();
        selectFavorite();
    }

    private void CopyDB(InputStream inputStream, OutputStream outputStream)
            throws IOException {
        byte[] buffer = new byte[1024];
        int length;
        while ((length = inputStream.read(buffer)) > 0) {
            outputStream.write(buffer, 0, length);
        }
        inputStream.close();
        outputStream.close();
    }

    private void selectFavorite(){

        database = SQLiteDatabase.openOrCreateDatabase(destPath + "/md_book.db",
                null);
        Cursor cursor = database.rawQuery("SELECT * FROM main WHERE fav = 1",
                null);
        while (cursor.moveToNext()){
            String word = cursor.getString(cursor.getColumnIndex("word"));
            String definition =
                    cursor.getString(cursor.getColumnIndex("definition"));
            String trans = cursor.getString(cursor.getColumnIndex("trans"));
            String img = cursor.getString(cursor.getColumnIndex("img"));
            int id = cursor.getInt(cursor.getColumnIndex("id"));

            Structure struct = new Structure(word, definition, trans, img, id);
            struct.setWord(word);
            struct.setDefinition(definition);
            struct.setTrans(trans);
            struct.setImg(img);
            struct.setId(id);
            favorite.add(struct);
        }

    }

    private void selectList(){

        database = SQLiteDatabase.openOrCreateDatabase(destPath + "/md_book.db",
                null);
        Cursor cursor = database.rawQuery("SELECT * FROM main", null);
        while (cursor.moveToNext()){
            String word = cursor.getString(cursor.getColumnIndex("word"));
            String definition =
                    cursor.getString(cursor.getColumnIndex("definition"));
            String trans = cursor.getString(cursor.getColumnIndex("trans"));
            String img = cursor.getString(cursor.getColumnIndex("img"));
            int id = cursor.getInt(cursor.getColumnIndex("id"));

            Structure struct = new Structure(word, definition, trans, img, id);
            struct.setWord(word);
            struct.setDefinition(definition);
            struct.setTrans(trans);
            struct.setImg(img);
            struct.setId(id);
            list.add(struct);
        }

    }

}
Sam
  • 5,342
  • 1
  • 23
  • 39
  • I tried to use CopyDB(); in my code but actually my method is CopyDB(InputStream inputStream, OutputStream outputStream) and it gives error – Love Programming Feb 12 '18 at 22:00
  • Here I moved your nav and db setup to methods and call from permission granted callback. Try that and see if you are cleared up – Sam Feb 12 '18 at 22:02
  • Until you are certain you have permission handled and proper order of accessing it, I would focus on that part. Once you are sure you have permissions "before" trying to move it, if you still have an error, then I will help with the next error you get – Sam Feb 12 '18 at 22:03
  • I don't know how to thank you sir. My problem with crash on first run solved . now on first run it doesn't load database – Love Programming Feb 12 '18 at 22:14
  • Crash is gone . Only problem is with database. Now it doesn't show – Love Programming Feb 13 '18 at 00:19
  • can you elaborate a bit, what do you mean by doesn't show? Is it correctly copying it into the file system? you can see it in a file explorer app? – Sam Feb 13 '18 at 00:24
  • Yes.Database is copied successfully. But my list is empty I have no data on screen – Love Programming Feb 13 '18 at 00:27
  • Put a try/catch around your open DB call and the while loop that handles the cursor and see if you are actually opening the DB and getting values back. If you are, then your issue is adapter and ui related, if you are not, then your issues is DB access or location related – Sam Feb 13 '18 at 00:36
  • I tried try / catch but it doesn't let me . I'm really desperate. – Love Programming Feb 13 '18 at 07:13
  • Let's move to private messaging, I think we need to discuss logs, and more details about which breakpoints are being hit. Otherwise this will take a lot of time back and forth here ;) – Sam Feb 13 '18 at 15:58
  • I appreciate your help.If it's not against this forum's rule can I leave my telegram id or any other way you suggest? – Love Programming Feb 13 '18 at 17:32
  • I'm not sure how to move to direct message, but I know if you reply a couple more times it will happen automatically – Sam Feb 14 '18 at 18:35
  • my reputation is not enough to chat :( it gives error – Love Programming Feb 14 '18 at 18:45
  • oh maybe that is why it's not popping up haha, wasn't sure. well I don't know what the policy on email is here so I'll leave that at your discretion to find out if it is acceptable to share or not – Sam Feb 15 '18 at 16:28
  • I guess there is no problem . this is my telegram id : sam_program – Love Programming Feb 15 '18 at 18:27
  • not sure what telegram id is? also not sure what sam_program does? – Sam Feb 15 '18 at 19:09