Sunday, June 21, 2015

Extract DB From Your Android App - With Little Agony

So we all know how this goes right... some devices allow you access to your debuggable application's db files via a file browser and some don't. There is now right or wrong way for doing this so my solution will work on ALL devices though requires a little setup.

I really wonder how other people do it but here is the most aggravating way of doing it:

  1. Add a line in the code to copy the db file to the SDCard.
  2. Run the application and make it copy the file.
  3. Browse the SDCard and transfer the file to your computer.
  4. Open the file on your computer.

This seem like "Come on these are only few steps I'll manage" --- Sorry my time is valuable and this crappy way is not an acceptable solution.

So I've wasted 10 minutes on a setup that allows me to open my app's db file in less than 10 seconds...

I've installed Node.js and created this little server script which is running on my local machine:

var http = require('http');
var fs = require('fs');
http.createServer(function(request, response) {
 response.writeHead(200);
 var destinationFile = fs.createWriteStream("mydbfile.db");
 request.pipe(destinationFile);

 var fileSize = request.headers['content-length'];
 var uploadedBytes = 0;

 request.on('data', function(d) {
  uploadedBytes += d.length;
  var p = (uploadedBytes / fileSize) * 100;
  console.log("Uploading " + parseInt(p) + "%");
 });

 request.on('end', function() {
  response.end("File Upload Complete");
 });

}).listen(11225, function() {
 console.log("server started");
});


In my app code I have a button(it is actually an entire debug menu) that only exists in a debug version, otherwise visibility is set to GONE, and when I click on that button:

case FETCH_DB:
 HttpRequest request = new HttpRequest();
 request.setUrl(Environments.MyLocalServer.getBaseUrl() + "/upload");
 try {
  byte[] dbFile = Tools.readFullyAsByteArray(new FileInputStream(getDatabasePath("mydbfile.db")));
  request.setBodyAsByteArray(dbFile);
  getManager(HttpManager.class).executeRequestAsync(request);
 } catch (IOException e) {
  e.printStackTrace();
 }
 break;

If this code is not clear, it takes the file turns it to a byte array(yes I don't care about efficiency here its a debug function!!) adds it to a HttpRequest and sends it to my local server, where is lands in a designated folder and then in two clicks I can view my db!


THE END!