简体   繁体   English

代码未将数据库写入sdcard

[英]Code not writing database to sdcard

I'm using the following code to export a copy of my database to my sdcard. 我正在使用以下代码将数据库副本导出到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 该代码似乎正常运行,因为我没有任何错误,第一个Toast显示了正确的数据库名称,第二个Toast显示了输出目录应该是mnt / sdcard / student,第三个显示了最终目标应该是mnt / sdcard / student / TodaysStudentTest.db3

After that Toast fades, nothing, the final Toast never appears. 在Toast消失之后,什么都没有,最终的Toast永远不会出现。

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. 我正在三星平板电脑而不是模拟器上进行测试,我也在DroidX上运行了相同的结果,没有错误,但是没有创建文件夹。

Any ideas on what I'm doing wrong? 关于我在做什么错的任何想法吗? TIA 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. 在模拟器中运行时,我得到相同的结果-用DDMS观看-Logcat显示MAKE DIR失败。

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. 结果是文件夹不存在,然后mkdirs()失败。

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

REWRITE 改写

Here is a different approach to coping a database file, without using SQL itself or a looping buffer. 这是一种不使用SQL本身或循环缓冲区而处理数据库文件的不同方法。

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). 注意:这实际上并没有复制到sdcard,备份存储在原始数据库文件夹中(我喜欢这样做,因为您不需要 WRITE_EXTERNAL_STORAGE权限)。

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(). 使用mkdir()时,请确保已创建名为“ student”的文件夹。 it will create directory by abstract path name..so if folder "student" does not exist it wont create new folder.. or try instead mkdirs(). 它将通过抽象路径名创建目录。.因此,如果文件夹“ student”不存在,则不会创建新文件夹..或尝试改用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. Uses-permission的拼写与uses-premission错了,我读了很多遍代码,然后按自己的意愿阅读了。 valuable lesson, walk away and take a break. 宝贵的教训,走开休息一下。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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