मैं डेटाबेस फ़ाइल को फ़ोन मेमोरी में निर्यात करने के लिए निम्न कोड का उपयोग करता हूं। यह एंड्रॉइड 24 पर ठीक काम करता है, लेकिन एपीआई 28 पर यह केवल एक खाली फाइल देता है:

public void exportDatabse() {
    try {
        if (sd.canWrite()) {
            String backupDBPath = "nameBCK.db";
            File currentDB = new File(MainActivity.this.getDatabasePath("dataBaseName.db").getPath());
            File backupDB = new File(sd, backupDBPath);
            if (currentDB.exists()) {
                FileChannel src = new FileInputStream(currentDB).getChannel();
                FileChannel dst = new FileOutputStream(backupDB).getChannel();
                dst.transferFrom(src, 0, src.size());
                src.close();
                dst.close();
                Toast.makeText(this,getString(R.string.stSuccess2),
                        Toast.LENGTH_LONG).show();
            }
        }

        else {
            REQUEST_TYPE=0;
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE);}

    } catch (Exception e) {
        Toast.makeText(this,getString(R.string.stFaild),Toast.LENGTH_LONG).show();
    }
}

और मैं भंडारण को लिखने की अनुमति का अनुरोध करने के लिए onRequestPermissionsResult का भी उपयोग करता हूं।

@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {
        case REQUEST_CODE:
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                if (REQUEST_TYPE==0) exportDatabse();
                if (REQUEST_TYPE==1) importDB();
            } else {
                if (REQUEST_TYPE==0) Toast.makeText(this,getString(R.string.stFaild2),Toast.LENGTH_LONG).show();
                if (REQUEST_TYPE==1) Toast.makeText(this,getString(R.string.stFaild3),Toast.LENGTH_LONG).show();
                Log.e("value", "Permission Denied, You cannot use local drive .");
            }
            break;
        default:
            throw new IllegalStateException("Unexpected value: " + requestCode);
    }
}
0
Ahmed 5 जून 2020, 03:52
फ़ाइल दृष्टिकोण के बजाय AssetManager के माध्यम से context.getAssets() का उपयोग करने का प्रयास करें और जांचें कि क्या समस्या अभी भी होती है।
 – 
Mohamed Alaa
5 जून 2020, 18:20

2 जवाब

इस प्रश्न का उत्तर मैं पहले ही दे चुका हूँ। यह समस्या केवल Android 28 पर होती है।

संपर्क

  public class DataBase extends SQLiteOpenHelper {

private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "database.db";
private static String DATABASE_PATH = "";
private static String LAST_DATABASE_PATH = "";
private SQLiteDatabase mDataBase;
private final Context ctx;

public DataBase2(@Nullable Context context) {
    super(context, DATABASE_NAME, null, DATABASE_VERSION);
    DATABASE_PATH = context.getDatabasePath(DATABASE_NAME).getPath();
    this.ctx = context;

    if (!checkIfDBExists()) {
        createDataBase();
    }

    File dbFile = new File(Environment.getDataDirectory().getPath()+"/data/"+ BuildConfig.APPLICATION_ID +"/databases");
    if (dbFile.isDirectory()) {
        String[] child = dbFile.list();
        assert child != null;
        for (int i = 0; i < child.length; i++) {
            if (!(child[i].equals("database.db") || child[i].equals(DATABASE_NAME))) {
                new File(dbFile, child[i]).delete();
            }
        }
    }
}

public void createDataBase() {
    this.getReadableDatabase();
    this.close();
    try {
        copyDataBase();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    try {
        File DbFile = ctx.getDatabasePath(DATABASE_NAME);
        if (DbFile.exists()) {
            copyDataBase();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

private boolean checkIfDBExists() {
    File dbFile = new File(DATABASE_PATH);
    return dbFile.exists();
}



public void openDataBase() {
    close();
    mDataBase = SQLiteDatabase.openDatabase(DATABASE_PATH, null, CREATE_IF_NECESSARY);
}

private void copyDataBase() throws IOException {
    InputStream mInput = ctx.getAssets().open("database.db");
    String outfileName = DATABASE_PATH;
    OutputStream mOutput = new FileOutputStream(outfileName);
    byte[] buffer = new byte[1024];
    int mLength;
    while ((mLength = mInput.read(buffer)) > 0) {
        mOutput.write(buffer, 0, mLength);
    }
    mOutput.flush();
    mInput.close();
    mOutput.close();
}

@Override
public void onCreate(SQLiteDatabase db) {
}


@Override
public synchronized void close() {
    if (mDataBase != null)
        mDataBase.close();

    SQLiteDatabase.releaseMemory();
    super.close();
}
}
0
Javad Dehban 5 जून 2020, 07:22

मुझे दो चीजों में समाधान मिला

SQliteDatabase का उपयोग करके पहले अक्षम लिखें आगे लॉगिंग लिखें जैसे यहां कहा गया है:

Environment.getExternalStorageDirectory () एपीआई स्तर २९ जावा में पदावनत

पर्यावरण के बजाय सेकेंड का उपयोग getExternalFilesDir (), getExternalCacheDir (), या getExternalMediaDir () (संदर्भ पर विधियां) .... जैसा कि यहां कहा गया है:

Environment.getExternalStorageDirectory () एपीआई स्तर २९ जावा में पदावनत

इन दो चीजों ने मेरे लिए इस मुद्दे को हल कर दिया।

0
Ahmed 5 जून 2020, 18:54