Pippo's blog

it is all about software development

This is annoying

by filipesperandio

You can read the title as “How to make your recently created android app’s file visible”.

I am recetly playing around with Android Platform and around goods and bads this is just annoying. Android has an complex user mode mecanism to segregate application namespace. It is based on linux user mode and each application has its own, well, user. It is OK and brings up a good security policy but has some trade offs as well.

Going specific to what I want to say about files: You do have many ways to write a file with your app to the external storage media. External media being the same place you see your files when you download any the browser.
Once you have your file writen it doesn’t mean that you gonna find it through any file explorer when naviagting to your phone storage using your computer. You find the file using a android file manager within the phone though.

So, tell me what is annoying, damn!

This is annoying: to make your file let’s say ‘visible’, you have to run this code:

1
MediaScannerConnection.scanFile(context, new String[] {filePath}, null, null);

Why? I don’t know! It is the way it was thought. I think this is stupid! I didn’t want to dig further so I stopped here!

Just one more tip, for easy file handling, use apache commons-io. Add this to your pom.xml if using maven:

1
2
3
4
5
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>

Than you are able to use it like this:

1
2
3
4
5
import org.apache.commons.io.FileUtils;

FileUtils.readFileToString(new File(filePath));

FileUtils.write(file, txt);
Comments

One more for heroku

by filipesperandio

Horn making noise! Something wrong happened in production! Taking a look in the logs it seems to be some bad data in the database making the app misbehave, just a internal API which wasn’t being carefully handling exceptions with unexpected data.

First thought was: probably the last code we deployed to STAGING is good enough and can better handle the exception.

How to make sure of that? It is a rails app so I want to deploy new code to the server and migrate the DB schema to the last one. How can I be sure I wont waste my time deploying the new version and it gonna work with the DB with the current state?

Heroku helped me a lot on that, these are the steps I took:

  • Backing up the PROD DB
1
2
3
heroku addons:add pgbackups --app PROD
heroku pgbackups:capture --app PROD
heroku pgbackups:url --app PROD # => DUMP_FILE_URL
  • Instantiate a new postgresql instance for your staging app
1
2
3
4
heroku addons:add heroku-postgresql:dev # => NEW_DB_URL
heroku addons:add pgbackups --app STAGING
heroku pgbackups:restore NEW_DB_URL <DUMP_FILE_URL>
heroku config:set DATABASE_URL=<NEW_DB_URL> # next time your app deploy it will point to the new DB
  • New deploy and migration We do have in this project a rake task that handles deployment steps for me including db migration so I run:
1
rake deploy:staging

or if you don’t have similar thing:

1
2
3
4
heroku maintenance:on --app STAGING
git push staging master
heroku run db:migrate --app STAGING
heroku maintenance:off --app STAGING
  • Smoke tests Check if everything looks good

  • Production deploy Now you know if a new deploy will make any damage to your production server, in case we are good:

1
rake deploy:production

… which does similar steps as above, but for production app instead!

Comments

One Month Playing With Calatrava

by filipesperandio

Last month we started a study group around mobile subject here at ThoughtWorks, Porto Alegre office. It is being great for the group to grow up and learn how software development for mobile platform looks like: different challenges and different way of think software development. Most of us in the group are mainly Web developers.

Well, the group decided to give a chance to Calatrava - which is a very interesting project also started within ThoughtWorks and create a simple To Do app to exercise the framework. Quoting them:

Calatrava is a cross-platform mobile framework that lets you share the core logic of your application across iOS, Android and Mobile Web, but unlike other XP toolkits it allows you to always write the highest quality native UI you need.

Although the framework still on a early stage I got very impressed by the things I could made with it and want to share some screens with you.

These are my first Android and iOS apps! \o/
All sharing the same WebView with same Coffee/JavaScript ‘backend’ code!
Check the source on Github.

Comments

Facebook SDK Wrapper

by filipesperandio

Recently I had to use Facebook JS SDK on a site I am working on. The API is kind of nice, you can do a lot of stuff with it having the benefit to control everything on your javascript code.

The problem I went through began when I needed to run more actions after some api call and since everything is based on callbacks I could see the callback hell pattern coming.

I am using AngularJS a lot these days, some weeks back I was reading the $http object documentation and how it is built with the promise/defer solution. Turned out that I wanted to apply that to my Facebook code, I didn’t want to depend on many other libraries (nhé, it depends on underscorejs anyways…) so I wrote my own defer/promise implementation. Of course I read some references before writing it and I recommend that you make use of some proved working frameworks, like Q.

Well, it was nice to challenge myself to write the wrapper and you can use it by your own risk: Facebook Wrapper

… you can simply instatiate the object to see the available methods (you need to load FB SDK before doing so):

1
var fb = new FacebookWrapper(window.FB);

… you can also use my Defer/Promise implementation if you want, it works sort of like this:

1
2
3
4
5
6
7
8
9
10
function wrapper() {
  var q = new Queue();
  function_that_handles_a_callback('something', function(data) { q.resolve(data) });
  return q.promise;
}
function doSomethingElseAfter(response) {
  // something else with the response/data 
}

wrapper().success(doSomethingElseAfter);

Enjoy!

Comments