0

I have written code to back up my sqlite db to a file on my Android phone (Sony Ericsson X-8 w/ version 2.1.1 of Android).

I have put the code below for reference, but before reading it, I stress that it works fine on the X-8. [Any suggestions for improvement are still most welcome!] It is when I run it on a Sony Ericsson Xperia Arc w/ version 4.0.4 of Android that I have problems.

The file is not written to the SD card. It's very hard to debug, because as you may know, hooking up the phone to the computer via USB card can stop the file from being written anyhow (see for example: Android FileWriter not working on Sony Ericsson Arc but works on another phone).

In any case, going through the code in the debugger results in no problems and one is led to believe the file is written. In my manifest, I do have:

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

I am stumped as to what is going on. Did something change between versions 2 and 4 of Android in regards to the file system? Is it phone specific?

Any ideas would be much appreciated. -Dave

                        String packageName = "com.xxx.receiver";
                    String dbName = "Receiver";
                    //File sd = Environment.getExternalStorageDirectory();   
                    File sd = new File(Environment.getExternalStorageDirectory(), "xxx"); // "xxx" is never created on Arc!
                    if (!sd.exists()) { 
                        sd.mkdirs(); 
                    } 
                    File data = Environment.getDataDirectory();     
                    if (sd.canWrite())
                    {                    
                        String currentDBPath = "//data//"+ packageName +"//databases//"+ dbName; 
                        String backupDBPath = dbName;   
                        File currentDB = new File(data, currentDBPath); 
                        File backupDB = new File(sd, backupDBPath);    
                        FileChannel src = new FileInputStream(currentDB).getChannel();  
                        FileChannel dst = new FileOutputStream(backupDB).getChannel();   
                        dst.transferFrom(src, 0, src.size());    
                        src.close();                      
                        dst.close();                  
                        //Toast.makeText(SettingsAdapter.this.getContext(), backupDB.toString(), Toast.LENGTH_LONG).show(); 
                    }               
Community
  • 1
  • 1
Dave
  • 8,095
  • 14
  • 56
  • 99
  • 1
    What does `sd.getAbsolutePath()` return before the `if( !sd.exists() )`? – 323go Feb 28 '13 at 21:59
  • 323go, On both phones (the one that works and the one that doesn't) sd.getAbsolutePath() gives /mnt/sdcard/xxx. – Dave Feb 28 '13 at 22:40
  • Have you tried finding that path (`/mnt/sdcard`) in the adb shell? Then try an mkdir from there? – 323go Feb 28 '13 at 23:30
  • 1
    323go, The Xperia Arc is bizarre! Tried you suggestion and created directory "yyy" on both phones with adb shell. That worked. BUT, "yyy" does not appear on Xperia Arc in Windows Explorer. BUT, I can now see my original "xxx" directory AND sqlite db I need. It "magically" appeared. Thank you! It makes me wonder if the "yyy" directory will show up in Windows Explorer eventually. Thanks for the intro to adb shell; that seems like it will be useful and possibly more accurate than Windows Explorer. Consider putting comments in answer, and I'd be happy and grateful to mark! – Dave Mar 01 '13 at 00:19
  • How are you connecting to the device? MTP or Mass Storage? If you're connecting via MTP, then folders (in Windows Explorer) don't get refreshed until you trigger a media rescan. – 323go Mar 01 '13 at 02:47
  • At this point, I'm pretty sure you have an issue the file not being picked up by the MediaScanner. I'll post the standard code I use to have Android recognize newly added files as an answer (because code doesn't format well in comments). If it doesn't resolve your issue, please let me know and I'll remove it as to not confuse other readers. – 323go Mar 01 '13 at 02:53
  • Could you say how to trigger a media rescan in Windows Explorer in Windows XP and Windows 7. Is it possible from Explorer. Or perhaps through adb? – Dave Mar 01 '13 at 20:22
  • You could trigger it through adb by sending the broadcast through activity manager: `./adb shell am broadcast -a android.intent.action.MEDIA_MOUNTED ...` – 323go Mar 02 '13 at 04:02

1 Answers1

0

In Android starting with ICS, USB connections offer the devices as a media device by default, not a USB Mass Storage device. The advantage of that is that external storage doesn't "disappear" when you plug in the USB cable, which of course makes debugging much easier. The disadvantage is that you'll need to let Android know explicitly when you've added a file (or files).

However, it's not terribly hard:

File sd = new File(Environment.getExternalStorageDirectory(), "xxx" );
...
// create your file in xxx
... 
sendBroadcast( 
    new Intent( Intent.ACTION_MEDIA_MOUNTED, 
                Uri.fromFile( sd ) ) 
              ) 
    );

As a side-note, rather than hard coding the database path, you can use this:

context.getDatabasePath( dbName );
323go
  • 14,143
  • 6
  • 33
  • 41
  • Many thanks for your answer and, more importantly, your comments to my original post. – Dave Mar 01 '13 at 05:31