简体   繁体   中英

Code not writing database to sdcard

I'm using the following code to export a copy of my database to my sdcard.

public class AgUtility extends AgActivity{

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
     setContentView(R.layout.utility);
    try {
        backupDatabase(getBaseContext());
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}        
public static void backupDatabase(Context context) throws IOException {


    // Open your local db as the input stream
    String inFileName = "data/data/com.agmanagement.todaysstudent/databases/todaysstudent.db";
    Toast.makeText(context, "FileName Is "+ inFileName, Toast.LENGTH_LONG).show();
    Log.i("The File In Is ", inFileName);

    File dbFile = new File(inFileName);
    FileInputStream fis = new FileInputStream(dbFile);

    File outputDirectory = new File(
            Environment.getExternalStorageDirectory() + "/student/");
    outputDirectory.mkdir();
    Log.d("MAKE DIR", dbFile.mkdir() + "");
    String backupFileName = "/TodaysStudentTest.db3"; 
    String outFileName = outputDirectory + backupFileName;
    Toast.makeText(context, "Database backup names is " + outFileName , Toast.LENGTH_LONG)
    .show();  

    // Open the empty db as the output stream
    OutputStream output = new FileOutputStream(outFileName);

    // transfer bytes from the inputfile to the outputfile
    byte[] buffer = new byte[1024];
    int length;
    while ((length = fis.read(buffer)) > 0) {
        output.write(buffer, 0, length);
    }
    // Close the streams
    output.flush();
    output.close();
    fis.close();

    Toast.makeText(context, "Database backup complete", Toast.LENGTH_LONG)
            .show();
}
}

The code seems to work properly, in that I don't get any errors the first Toast shows the correct database name, the second toast shows the output directory should be mnt/sdcard/student and the third shows the final target should be mnt/sdcard/student/TodaysStudentTest.db3

After that Toast fades, nothing, the final Toast never appears.

In my manifest I have

I am testing this on a Samsung Tablet and not on the emulator, i've also run it on a DroidX with the same result, no errors, but no folder is created.

Any ideas on what I'm doing wrong? TIA

The permissions I'm using are

     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> 
 <uses-permission android:name="android.permission.READ_PHONE_STATE" /> 
 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 
 <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
 <uses-permission android:name="android.permission.INTERNET" /> 
 <uses-permission android:name="android.premission.WRITE_EXTERNAL_STORAGE" />
 <uses-permission android:name="android.permission.SET_DEBUG_APP" />
 <uses-permission android:name="android.permission.CAMERA"/>
 <uses-permission android:name="android.permission.READ_CALENDAR"/>
 <uses-permission android:name="android.permission.WRITE_CALENDAR"/>

I get the same results when running in the emulator - watching with the DDMS - Logcat show MAKE DIR fails.

I've tested for state with this

        if (Environment.MEDIA_MOUNTED.equals(state)) {
         // We can read and write the media
         mExternalStorageAvailable = mExternalStorageWriteable = true;
            Toast.makeText(getBaseContext(), "We Can Read And Write To The SDCARD", Toast.LENGTH_LONG).show();
            } else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
         // We can only read the media
                mExternalStorageAvailable = true;
                mExternalStorageWriteable = false;
                Toast.makeText(getBaseContext(), "We Can Read The SDCARD", Toast.LENGTH_LONG).show();
            } else {
                // Something else is wrong. It may be one of many other states, but all we need
                //  to know is we can neither read nor write
                mExternalStorageAvailable = mExternalStorageWriteable = false;
                Toast.makeText(getBaseContext(), "We Can't read or write", Toast.LENGTH_LONG).show();
            }

And it shows I'm supposed to be able to read and write, so there's something wrong with how I'm writing. I added this to also text

       boolean success = false;
        if(!outputDirectory.exists()){
            Toast.makeText(getBaseContext(), "Folder Doesn't Exist ", Toast.LENGTH_LONG)
            .show();  
            success = outputDirectory.mkdirs();
        }
        if (!success){ 
            Toast.makeText(getBaseContext(), "Folder Not Created ", Toast.LENGTH_LONG)
            .show();  
        }
        else{
            Toast.makeText(getBaseContext(), "Folder Created ", Toast.LENGTH_LONG)
            .show();  
        }

Results are folder does not exist, and then mkdirs() fails.

在尝试写入文件之前,尝试手动创建文件。

REWRITE

Here is a different approach to coping a database file, without using SQL itself or a looping buffer.

NOTE: This isn't actually copied to the sdcard, the backup is stored in the original databases folder (which I like because you do not need WRITE_EXTERNAL_STORAGE permission).

public class FileIO extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        DBHelper db = new DBHelper(this);

        try { 
            copyFile();
        } catch (IOException ioe) {
            ioe.printStackTrace();
        } finally {
            Log.i("Main", "Complete");
            db.close();
            finish();
        }
    }

    public void copyFile() throws IOException {
        File data = Environment.getDataDirectory();
        String state = Environment.getExternalStorageState();

        /* Create file first
            FileOutputStream created = openFileOutput("copyFile.db", MODE_WORLD_READABLE);
            created.close();
        */

        String currentDBPath = "/data/<your_path>/databases/data.db";
        String backupDBPath = "/data/<your_path>/databases/copyByFile.db";
        File currentDB = new File(data, currentDBPath);
        File backupDB = new File(data, 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();
        }
        else
            Log.i("Main", "Current db does not exist");
    }
}

please make sure you have already created folder named "student" as you are using mkdir(). it will create directory by abstract path name..so if folder "student" does not exist it wont create new folder.. or try instead mkdirs(). it will created parent folder if necessary.

Important to remember to check spelling. uses-permission was mis-spelled as uses-premission, I had read the code so many times I read it as I wanted it to be. valuable lesson, walk away and take a break.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM