11 July 2016

Introducing now: Madmin. Your personal budget management app.


What is Madmin?

 It’s a (totally) free mobile application built in to help you take control of your money flow. Made for non-complex budgets. Start educating yourself by using this tool now and be able to make good future decisions.

Install it here.

  Why Madmin?

 There is a bunch of similar applications intended to provide you the same out there on the market, but what differs Madmin from the other ones is the proposal to bring discipline to your financial life. Discipline is what will put you back on the track of money health. The first step for a well-controlled budget is visibility, and Madmin gives you a clear overview of the paths whose your money takes since it reaches your pocket. Furthermore, you need to compare those paths’ flows to eventually do balance “expenses traffic” according to your needs. After that analysis you’ll be ready for the next step: Decision-making.

  How does it work?

 There’s no automatic inputs. No bank account integration. The intention here is self-education and to achieve that, you must do each input by yourself. After all, automatic data inputs from bank account history, for example, usually don't contain information regarding the kind of expense. And the kind of expense is crucial for keeping track on how you are spending your income. These kinds of expenses (or incomes) are playfully organized into boxes in Madmin. Each box represents a destination for your spent money (i.e. health, education, entertainment, etc.). By default there are some ready-for-use boxes when you install Madmin, but you can (and must) create your own ones. You can also delete them if they make no sense anymore for your needs. Be aware that when you delete an already used box, each and every data inside it will vanish away as well. We highly recommend you to keep the boxes, even if you are not using them. That's to keep tracking of the average expenses. Anyway, you are free to do delete a box. Mistakes happen while creating or using a box and therefore deletions may be necessary. Once you’ve have created your own boxes, you are ready to start using Madmin. Each expense and/ or income can be input inside each box and we recommend that you do that immediately after buying something or receiving money. Madmin works within monthly periods of date and you can only make an input within the current period. If you are buying something on December 31th at 11:55 PM you should be quick to input your expense because you have only five minutes to do that! Don’t get pissed off about that! This is just part of the self-education process. Madmin intentionally closes past periods to help you get used to register your expense immediately and this feature will keep you on the track of good practices for achieving your goals using this app. After the first month using Madmin, data will be computed and you will be gifted with the most useful and impressive feature: the balance and average expenses along with an embedded bar chart, right on the main screen of the application. This bar chart clearly shows you whenever you are having expenses over (red) or under (green) the box expenses average. Averages are computed using monthly data by each box. The chart shows which boxes are over or under average and the percentage of expenses per box. That means if you have spent $ 500 with education in a given month and it was your only expense on that period, therefore the “Education” box will be shown up with a full bar on the chart (100%). If you have more than a month of application usage (and thus an average is available) and your average expenses with education is $ 500 or under, then bar will be green, otherwise it will be red. At this point you will have all you need to make decisions about how to spend your money. You can avoid keep spending money on a box that is red, for example. But have in mind that good decisions only can be made when you have precise information, which means that you must not lose any data input. Please note that the balance only can be computed if you have inserted any income. Monthly incomes (like salary, for example) can be inserted on the main screen of the application. You can also input individual incomes per box. Have in mind that incomes are not on focus in Madmin world. Of course it’s part of the process of analysis but the most important is having your expenses updated. Planning future decisions is a complex task that may demand more than Madmin can offer. But what Madmin offers to you is the ability to start this process so you can have the chance to keep things in control on shortly, in order to get ready for reaching higher skies. Everything made simple. Madly simple!

  Questions you may find useful How to create a new box? 

Touch the Madmin logo in the upper-left corner to show the main menu. There you will find an option to create a new box. Type in a name for that box and confirm. Madly simple!

Can I rename a box?

 Yes, you can! Simply hold pressing over the box until the menu appears. Choose “Edit” and type in a new name for the box. That’s all!

  Should I delete a box? How can I do it?

 Although you can do it, it’s highly recommended that you only delete a box if it’s empty or in cases when you are quite sure that the box is useless. Any data inserted inside the box will be deleted, no matter if the box is empty in the current month. To get rid of a box, hold pressing over it until the menu appears. Choose “Delete” and confirm.

  How do I input an expense?

 Touch a box and in the box screen touch the red button on the lower right side. Choose a description and the value. Confirm. Good job!

  How do I delete an expense/ income?

 Touch a box and in the next screen touch and hold an income or expense you want to delete and confirm the operation in the next step.

Why should I input an income inside a box?

 Let’s imagine the following scenario: You are drinking some good Polish beers with a good new friend and then you pay the bill in the end of this pleasant evening. Considering you are a very ruled person, you immediately input your expense within your “Pubs/ Leisure” box. But your friend won't let you pay the entire bill because it’s the first hang out you both enjoy together and he/ she thus gives you half part of the expense. In this case you should register this money you’ve just received from your friend. It makes all the sense registering it inside that same box (“Pubs/ Leisure”), right? This is just a sample of how incomes sometimes are categorized and therefore must be kept inside a box.

  How do I input an income inside a box?

 Touch a box and in the next screen touch the red button on the lower-right corner. Choose a description and the value. Confirm. Good job!

  Why should I input an income outside a box?

 Any income that may be spent under any category (box) should be a monthly income. A classical example is the salary. You can add any monthly incomes you need.

  How do I input an income outside a box (monthly income)?

 In the main screen, touch the green button at the center bottom and type in a description and a value. Confirm. Done.

  How can I delete or modify a monthly income?

 Touch the Madmin logo on the upper-left corner to show the main menu. There you will find an option to manage incomes. Any income inserted in the selected month will be shown there. You can either delete or edit an income by touching and holding over it and selecting the proper option.

  Madmin only renders current month’s data. How can I see past months incomes/ expenses?

You have two options for changing the current visualization period. One of them is using the main menu by touching the Madmin logo on the upper left corner on the main screen. Another one is touching the date on the upper right corner on that same screen. Choose the month/ year and confirm.

Why can’t I input an income/ expense after changing the period of visualization?

 Because we want to help you create an habit of using Madmin whenever that an expense happens. It’s all about discipline. That's a help for you to achieve your goals having consistent and updated information.

  How is my data stored by Madmin?

 We believe that the best guardian for your information is yourself. That’s why Madmin keeps all your data stored in your own device. There is no information kept on cloud.

  How can I prevent losing my data?

 Madmin has a feature that you can use to prevent losing all your expenses and incomes. It’s the Backup/ Restore feature where you can store a full copy of your Madmin database wherever you find more convenient: a cloud storage service (like Google Drive, Dropbox, etc), email, message services, external storage and so on. You can also chose a database backup file to restore from any of those services. It is strongly recommended that you make periodic (weekly if possible) backup of your data. Do never clear the application data (from OS settings) unless you have a backup file to restore later on, or you will be cleaning all information about your expenses/ incomes and so you will have to start from scratch!

  How to create a backup of my data?

 Touch the Madmin logo on the upper-left corner to show the main menu. There you will find an option for data backup, select it. On the next step you must type in an email address and confirm the backup. This email address field may be filled with your phone account's default email, but you can type in any other address of your choice. This address is used just in case you want to send the backup by email (which is the default option), but you can choose between any other option of storing the database copy in the next step. For example, you can opt for sending it out to Google Drive, Skype, etc. The available options depends upon installed and available apps and current Operational System. Please send the file properly using your chosen email/ storage app to complete the backup operation. A madmin.mad file is received in this case.

  How to restore backup data?

 Touch the Madmin logo on the upper-left corner to show the main menu. There you will find an option for data backup, select it and choose restore in the next step. Once you have created a backup file of your data, you can chose it now using your default file management app. We recommend you to close Madmin and re-open it again in order to ensure that the data are updated. Note: If you don’t have any file manager installed then you'll be not able to restore a file. If the backup file was generated in a previous database version (prior than the current one) you will not be able to restore it - Therefore it’s highly recommended that you generate a backup file right after updating the app.

  How can I give feedback about Madmin?

 Please you are very welcome to let us know how much do you like or not Madmin. Feel free to send an email to the developer: saulojoonior@gmail.com

Install now Madmin for free.

Privacy Policy
Toyshop Studio built the Madmin app as a Free app. This SERVICE is provided by Toyshop Studio at no cost and is intended for use as is.
This page is used to inform website visitors regarding my policies with the collection, use, and disclosure of Personal Information if anyone decided to use my Service.
If you choose to use my Service, then you agree to the collection and use of information in relation to this policy. The Personal Information that I collect is used for providing and improving the Service. I will not use or share your information with anyone except as described in this Privacy Policy.
The terms used in this Privacy Policy have the same meanings as in our Terms and Conditions, which is accessible at Madmin unless otherwise defined in this Privacy Policy.
Information Collection and Use
For a better experience, while using our Service, I may require you to provide us with certain personally identifiable information. The information that I request is retained on your device and is not collected by me in any way
The app does use third party services that may collect information used to identify you.
Link to privacy policy of third party service providers used by the app
Log Data
I want to inform you that whenever you use my Service, in a case of an error in the app I collect data and information (through third party products) on your phone called Log Data. This Log Data may include information such as your device Internet Protocol (“IP”) address, device name, operating system version, the configuration of the app when utilizing my Service, the time and date of your use of the Service, and other statistics.
Cookies are files with a small amount of data that are commonly used as anonymous unique identifiers. These are sent to your browser from the websites that you visit and are stored on your device's internal memory.
This Service does not use these “cookies” explicitly. However, the app may use third party code and libraries that use “cookies” to collect information and improve their services. You have the option to either accept or refuse these cookies and know when a cookie is being sent to your device. If you choose to refuse our cookies, you may not be able to use some portions of this Service.
Service Providers
I may employ third-party companies and individuals due to the following reasons:
  • To facilitate our Service;
  • To provide the Service on our behalf;
  • To perform Service-related services; or
  • To assist us in analyzing how our Service is used.
I want to inform users of this Service that these third parties have access to your Personal Information. The reason is to perform the tasks assigned to them on our behalf. However, they are obligated not to disclose or use the information for any other purpose.
I value your trust in providing us your Personal Information, thus we are striving to use commercially acceptable means of protecting it. But remember that no method of transmission over the internet, or method of electronic storage is 100% secure and reliable, and I cannot guarantee its absolute security.
Links to Other Sites
This Service may contain links to other sites. If you click on a third-party link, you will be directed to that site. Note that these external sites are not operated by me. Therefore, I strongly advise you to review the Privacy Policy of these websites. I have no control over and assume no responsibility for the content, privacy policies, or practices of any third-party sites or services.
Children’s Privacy
These Services do not address anyone under the age of 13. I do not knowingly collect personally identifiable information from children under 13. In the case I discover that a child under 13 has provided me with personal information, I immediately delete this from our servers. If you are a parent or guardian and you are aware that your child has provided us with personal information, please contact me so that I will be able to do necessary actions.
Changes to This Privacy Policy
I may update our Privacy Policy from time to time. Thus, you are advised to review this page periodically for any changes. I will notify you of any changes by posting the new Privacy Policy on this page. These changes are effective immediately after they are posted on this page.
Contact Us
If you have any questions or suggestions about my Privacy Policy, do not hesitate to contact me.

Apresentamos Madmin: Seu gestor de orçamento pessoal simples e didático.


O que é Madmin?

 É um aplicativo móvel (totalmente) gratuito desenvolvido para ajudá-lo a assumir o controle de seu dinheiro, fornecendo uma visão geral e ampla de seu fluxo financeiro para que você seja capaz de tomar boas decisões.

Instale agora Madmin

  Porque Madmin?

 Existe lá fora uma variedade de aplicativos semelhantes destinados a fornecer-lhe o mesmo, mas o que difere Madmin dos demais é a proposta de trazer disciplina para sua vida financeira. Disciplina é o que vai colocá-lo de volta no caminho da saúde financeira. O primeiro passo para um orçamento bem controlado é a visibilidade, e Madmin lhe provém uma visão clara dos caminhos pelo qual seu dinheiro circula apos atingir seu bolso. Além disso, é preciso comparar o fluxo desses caminhos para eventualmente equilibrar "o tráfego de despesas" de acordo com suas necessidades. Após essa análise, você estará pronto para o próximo passo: a tomada de decisão.

  Como funciona?

 Não existem lançamentos automáticos. Sem integração de conta bancária e essa é a idéia. A intenção aqui é prover auto-educação e para isso, você deve fazer cada lançamento por si próprio. Além disso, quando você tem um aplicativo que provê lançamentos automáticos provenientes de sua conta bancária, por exemplo, você pode perder informações sobre o tipo de despesa, a motivação dela. Tipo de despesa é crucial para o rastreamento de como você está gastando sua receita. Esses tipos de despesas (ou rendimentos) são divertidamente organizados por caixas no Madmin. Cada caixa representa uma destinação do seu dinheiro gasto (ou seja, saúde, educação, entretenimento, etc.). Por padrão, existem algumas caixas já criadas quando você instala o Madmin pela primeira vez, mas você pode (e deve) criar suas próprias. Você também pode excluí-las se elas não fazem mais sentido para suas necessidades. Esteja ciente de que quando você excluir um caixa já utilizada, todos os dados dentro dela serão excluídos também. É altamente recomendável manter as caixas, mesmo quando você não estiver mais as utilizando. Um dia você pode precisar dela novamente por algum motivo. De qualquer forma, você é livre para fazê-lo, afinal, erros ocorrem. Uma vez que você criou suas caixas, você está pronto para começar a utilizar o Madmin. Cada lançamento de despesa e / ou receita pode ser inserido dentro de cada caixa e recomendamos que você faça isso no momento em que pagar ou receber algo. Madmin funciona dentro de períodos mensais de data e você só pode fazer um lançamento dentro do período atual. Se você está comprando algo em 31 de dezembro às 23:55 você deve ser rápido para registrar sua despesa porque você tem apenas cinco minutos para fazer isso! Não fique chateado por isso, isto é apenas parte do processo de auto-educação. Madmin faz isso intencionalmente para ajudá-lo a registrar suas despesas no ato e irá mantê-lo no caminho de uma boa prática para alcançar seus objetivos usando este aplicativo. Após o primeiro mês utilizando Madmin, os dados serão computados e você será presenteado com o recurso mais útil e impressionante: o saldo mensal e despesas médias juntamente com um gráfico de barras incorporado na listagem da tela principal do aplicativo. Este gráfico de barras mostra claramente sempre que você está tendo as despesas acima (vermelho) ou dentro da média (verde). As médias são calculadas usando os dados mensais por cada caixa. O gráfico mostra quando cada caixa está acima ou dentro da média, e a proporção (percentagem) de despesas por caixa. Isso significa que se você gastou $ 500 em educação em um determinado mês e essa foi sua única despesa dentro desse período, logo, a caixa "Educação" será exibida com uma barra cheia no gráfico (100%). Se você tiver mais de um mês de uso do aplicativo (com uma média de gastos disponível) e seus gastos médios com educação é de $ 500 ou menos, logo, a barra do gráfico será verde, caso contrário será vermelha. A essa altura você terá tudo o que você precisa para tomar decisões sobre como gastar o seu dinheiro. Você pode evitar vir a gastar dinheiro em uma caixa que está vermelha, por exemplo. Mas tenha em mente que boas decisões só podem ser feitas quando você tem informações precisas, o que significa que você não deve perder nenhuma entrada de dados pelo caminho. Note que o balanço mensal só pode ser computado se tiver inserido qualquer rendimento no mês. Receitas mensais (como salário, por exemplo) podem ser registradas na tela principal do aplicativo. Você também pode inserir receitas individuais por caixa. Tenha em mente que os rendimentos não são o foco no mundo Madmin. É claro que é parte do processo de análise, mas o mais importante é ter suas despesas atualizadas. Planejar futuras decisões é uma tarefa complexa que pode exigir mais do que Madmin pode oferecer no momento. Mas o que Madmin oferece é a capacidade de iniciar este processo, para manter o controle financeiro, para futuramente alcançar vôos mais altos. Tudo isso de maneira simples. Madly simple!

  Perguntas que você poderá considerar útil Como criar uma nova caixa?

 Toque o logotipo Madmin no canto superior-esquerdo para mostrar o menu principal. Lá você encontrará uma opção para criar uma nova caixa. Digite um nome para essa caixa e confirme. Simples!

  Posso mudar o nome de uma caixa?

 Sim você pode! Basta manter pressionando sobre uma caixa até que o menu de opções apareça. Escolha "Editar" e digite um novo nome para a caixa. Isso é tudo!

  Devo excluir uma caixa? Como eu posso fazer isso?

 Embora você possa fazer isso, é altamente recomendável que você somente exclua uma caixa se a mesma estiver vazia (se você em nenhum momento a utilizou) ou em casos quando você está completamente certo de que a caixa não terá mais utilidade para análises futuras. Quaisquer dados inseridos na caixa algum dia serão eliminados. Para se livrar de uma caixa, mantenha pressionando sobre ela até que o menu de opções apareça. Escolha "Excluir" e confirme.

  Como registro uma despesa?

 Toque em uma caixa e na tela seguinte no botão vermelho no canto inferior-direito. Insira uma descrição e o valor. Confirme. Bom trabalho!

  Como faço para excluir uma receita / despesa?

 Toque em uma caixa e na tela seguinte toque e mantenha pressionado sobre a receita ou gasto que você deseja excluir, selecione a opção de excluir e confirme a operação.

  Por que eu deveria lançar receita em uma caixa?

 Vamos imaginar o seguinte cenário: Você está bebendo algumas boas cervejas polonesas com um bom novo amigo e, em seguida, você paga a conta no final dessa agradável noite. Considerando que você é uma pessoa muito regrada, você imediatamente registra a sua despesa em sua caixa "Bares / Lazer". Mas seu amigo, não querendo deixá-lo pagar a conta inteira por ser a primeira bebedeira juntos, insiste e lhe paga metade da conta. Nesse caso, você deve inserir o dinheiro que acabou de receber de seu amigo. Faz todo o sentido registra-la na mesma caixa ( "Bares / Lazer"), certo? Esse é apenas um exemplo de como a renda por vezes é categorizada e, portanto, deve ser mantida dentro de uma caixa.

  Como faço para inserir uma receita dentro de uma caixa?

 Toque em uma caixa e, na tela seguinte toque no botão vermelho no canto inferior-direito. Escolha uma descrição e o valor. Confirme. Bom trabalho!

  Por que eu lançaria uma receita fora de qualquer caixa?

 Qualquer receita que pode ser gasta em qualquer categoria (caixa) deve ser tratada como uma renda mensal. Um exemplo clássico é o salário. Você pode adicionar qualquer renda mensal que você precisar.

  Como faço para lançar uma receita fora de qualquer caixa (receita mensal)?

 Na tela principal, toque no botão verde na parte inferior-central e digite uma descrição e um valor. Confirme. Feito.

  Como posso excluir ou modificar uma receita mensal?

 Toque o logotipo Madmin no canto superior-esquerdo para mostrar o menu principal. Lá você encontrará uma opção para gerenciar as receitas. Qualquer receita registrada no mês selecionado será mostrado lá. Você pode apagar ou editar uma receita tocando e segurando sobre ela e selecionando a opção adequada.

  Madmin processa somente os dados do mês atual. Como posso ver últimos meses de rendas / despesas?

 Você tem duas opções para alterar o período de visualização atual. Uma delas é usando o menu principal tocando o logotipo Madmin no canto superior-esquerdo da tela principal. Outra é tocar a data no canto superior-direito, na mesma tela. Escolha o mês / ano e confirme.

  Por que não posso introduzir uma receita / despesa depois de alterar o período de visualização?

 Porque nós queremos ajudá-lo a criar um hábito de usar Madmin no ato sempre que uma despesa acontece. Trata-se de disciplina para ajudá-lo a atingir suas metas graças a informações consistentes e atualizadas.

  Como meus dados são armazenados pelo Madmin?

 Acreditamos que o melhor guardião para suas informações é você mesmo. É por isso que Madmin mantém todos os seus dados armazenados no seu próprio dispositivo. Não há nenhuma informação armazenada na nuvem.

  Como posso evitar perder os meus dados?

 Madmin tem um recurso que você pode usar para evitar a perda de todas as suas informações de despesas / receitas. É a cópia/ restauração onde você pode armazenar uma cópia completa do seu banco de dados de Madmin, onde quer que você ache mais conveniente: um serviço de armazenamento na nuvem (como o Google Drive, Dropbox, etc), e-mail, serviços de mensagens, armazenamento externo e assim por diante. Você também pode escolher um arquivo de backup de banco de dados para restaurar a partir de qualquer desses serviços. É altamente recomendável que você faça uma cópia periódica (semanalmente, se possível) dos seus dados. Não limpe os dados do aplicativo (via configurações do SO) a menos que você tenha um arquivo de backup para restaurar mais tarde, ou você estará excluindo todas as informações sobre as suas despesas e receitas. Assim você vai ter que começar do zero!

  Como criar uma cópia de segurança dos meus dados?

 Toque o logotipo Madmin no canto superior-esquerdo para mostrar o menu principal. Lá você encontrará uma opção para cópia de dados, selecione-o. Na próxima etapa, você deve digitar um endereço de e-mail para confirmar o backup. Este campo de endereço de e-mail poderá estar preenchido com o e-mail de sua conta padrão configurada no dispositivo, mas você pode digitar qualquer outro endereço de sua escolha. Esse endereço é utilizado apenas no caso de você desejar enviar a cópia de segurança por e-mail (que é a opção padrão), mas você pode escolher entre qualquer outra opção para armazenar a cópia do banco de dados na próxima etapa. Por exemplo, você pode optar por enviar para o Google Drive, Skype, etc. As opções disponíveis dependerão dos aplicativos instalados e disponíveis no sistema operacional atual. Envie o arquivo utilizando seu aplicativo de e-mail / storage escolhido para concluir a operação de backup. Um arquivo madmin.mad é recebido/ armazenado neste caso.

  Como restaurar dados de backup?

 Toque o logotipo Madmin no canto superior-esquerdo para mostrar o menu principal. Lá você encontrará uma opção para cópia de dados, selecione-o e escolha restaurar na próxima etapa. Depois de ter criado um arquivo de backup de seus dados, você pode seleciona-lo agora utilizando seu aplicativo de gerenciamento de arquivos padrão. Recomendamos fechar e abrir Madmin novamente, a fim de garantir que os dados estejam atualizados com a recuperação de backup. Nota: Se você não possui qualquer gerenciador de arquivos instalado no seu dispositivo não será possível restaurar um arquivo. Se o arquivo de backup foi gerado em um banco de dados versão anterior (antes que o aplicativo instalado atual), você não será capaz de restaurá-lo - Por isso, é altamente recomendável que você gere uma cópia dos dados logo após uma atualização de versão do Madmin.

  Como posso dar feedback sobre Madmin?

 Por favor, você é muito bem-vindo para nos informar o quanto você gosta ou não de Madmin. Sinta-se livre para enviar um e-mail para o desenvolvedor: saulojoonior@gmail.com Sugestões também serão muito bem recebidas!

Clique aqui e instale gratuitamente Madmin

11 May 2016

Be aware: Why the HashSet doesn't contain my object?

Let's consider the following dummy class:

class MyClass {

    int uniqueId;

    public void setUniqueId(int uniqueId) {
        this.uniqueId = uniqueId;

    public int hashCode() {
        return uniqueId; //Of course you will never do this in real life. Right? :)

    public boolean equals(Object obj) {
        return obj.hashCode() == this.hashCode(); //Only to clarify things as well... :)

And now, please consider the following snippet:

MyClass myObject = new MyClass();

Set mySet = new HashSet(0);

myObject.hashCode(); // output: 1
mySet.iterator().next().hashCode(); // output: 1
mySet.contains(myObject.hashCode()); //output: false

People may say that a HashSet.contains() call will fail due to not proper overriding of equals() and hashCode() and they can be right.
Actually they are right most of the times. But here we have a (not so usual, but it happens) situation where the objects' hash are the same and the equals() returns true, but the contains() method still returns false.

How come?
When we go deeper into the Java's HashSet's code, we can figure out that it stores the added object's hash code as a key into a HashMap, so it can lookup later on for that key in a get() operation or, in our situation, to determine whenever the collection contains or not the given object. The problem here is that, when we add the object, it's hash is "0" because we haven't set the unique ID yet (which determines the object's hash code in this example), and that is the information the HashSet will use to locate our object afterwards.
In a nutshell, the HashSet.contains() method makes use of the hash code of an object to locate it and as this hash code is stored in the moment that the object is added to the collection, it will not change. It's a curious situation, cause, as you may add the object again and again after changing it's hash code, the HashSet may contain two or more identical objects inside it! Try it.

22 February 2016

How it all started (O começo)

Back in 2002, when I used to play for hours with former Micromedia's Flash™ and used to think my future would be working with some sort of digital design, I sketched a few lines that would be years later an inspiration for my first personal portfolio website.
It was the drawing of a kind of loft apartment. At that time I had a few Flash jobs done and I wished to showcase them in a website. From that point, I had a continuous flow of ideas, like having an elevator as the website's preloader and having some interactivity with users.
As the ideas were coming, I had to bring life to things, so I had to learn some scripting and that was the way I found to make myself a programmer.
What you'll see clicking the image preview below (Adobe Flash™ plugin required), is my former website like it was, back in 2007. Enjoy all it's interactivity and use the help at the top right corner as necessary. In spite its old fashioned website style, I still find myself having fun rediscoverying all of those "easter eggs" that I myself have put in it.

Em 2002, eu costumava brincar bastante com Flash™ (ex-Macromedia) e até pensava em trabalhar com algum tipo de design digital algum dia. Foi quando esbocei algumas linhas que seriam anos mais tarde uma inspiração para o meu primeiro site de portfólio pessoal.
Tratava-se do desenho de uma espécie de loft. Naquela época, eu tinha alguns trabalhos em Flash e eu queria apresentá-los em um site. Desde então, comecei a ter várias ideias, como a de que o preloader do site fosse um elevador e de ter alguma interatividade com os usuários.
À medida em que as idéias surgiam, eu tinha que trazer vida às coisas, foi quando tive que aprender um pouco de script e me tornar um programador.
O que você vai ver, clicando na imagem abaixo (requer instalação do plugin Adobe Flash™), é o meu ex-website como ele era em 2007. Desfrute de toda a sua interatividade e, se necessário, use a ajuda no canto superior direito. Apesar de um site antigo, eu ainda me divirto redescobrindo todos os "easter eggs" que eu mesmo coloquei nele.

09 February 2016

Android: Reading SQLite databases selected by the user

Hello people!
After long hours, days and months... I'm back in the saddle again!
I'm here to describe a problem I was facing regarding an android application development. The exception I was fighting is the same as described in this thread: android-could-not-open-database

But my problem was quite different because the file I was trying to open is chosen via an Intent. I mean, the scenario is that an user chooses a database file to overwrite the current one used by the application. This is a manual backup/ recovery procedure where the user first backs-up its data and sends via email or whatever it wants to. After, he/ she grabs the file from the storage (after downloading it from email or whatever) and overwrite the current database.

But this procedure must be obviously validated regarding the file type and the version of the (SQLite) database. The version of the backed-up database must be the same as the current one for the application keep working.
The exception was thrown when I was trying to get the SQLiteDatabase from the chosen file:
SQLiteDatabase db = SQLiteDatabase.openDatabase(file.getPath(), null, SQLiteDatabase.OPEN_READONLY);
And the exception was:
SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database 
It's important to say that this procedure worked fine using an emulator, but it failed in my real device (Motorola XT1058 with Android 5.5 Lollipop).
I had in my manifest the permissions set correctly:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
And the file I was trying to read from SQLite was obtained in the result of the Intent used to get the file from the user's folder:

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode) {
            case FILE_SELECT_CODE:
                if (resultCode == RESULT_OK) {
                    Uri uri = data.getData();
                    try {
                        InputStream fileInputStream = getContentResolver().openInputStream(data.getData());
                        BackupFile file  = new BackupFile(fileInputStream, uri.getPath());
                        BackupData backupData = new SQLiteBackupData(context, file);
                        DataSecurityEvent dataSecurityEvent = new SQLiteRecovery(backupData);
                        new BackupDataAsyncTask(context, dataSecurityEvent).execute();
                    } catch (FileNotFoundException e) {
                        ToastOnMiddle.makeText(context, context.getString(R.string.recover_fail), 

        super.onActivityResult(requestCode, resultCode, data);

Note that the file used by the recovery validation procedure was the same chosen by the user. After hours I could figure out that this was the problem. My device didn't make use of an external storage and the downloaded files was stored internally. That was the difference between the device and emulator. Then, I changed my code to create a temporary file and fill its content with the content of the file grabbed by the user. This way, the file managed afterwards by the recovery component was located in the temp folder and no permission problem would happen. This is how the code looks like after the refactor:

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode) {
            case FILE_SELECT_CODE:
                if (resultCode == RESULT_OK) {
                    Uri uri = data.getData();
                    try {
                        InputStream fileInputStream = getContentResolver().openInputStream(data.getData());
                        File tempFile = File.createTempFile(uri.getLastPathSegment(), null, context.getCacheDir());

                        FileChannel originChannel = ((FileInputStream)fileInputStream).getChannel();
                        FileOutputStream destOutput = new FileOutputStream(tempFile);
                        FileChannel destChannel = destOutput.getChannel();
                        originChannel.transferTo(0, fileInputStream.available(), destChannel);

                        BackupFile file  = new BackupFile(new FileInputStream(tempFile), tempFile.getPath());
                        BackupData backupData = new SQLiteBackupData(context, file, new SQLiteBackupDataValidator(file));
                        DataSecurityEvent dataSecurityEvent = new SQLiteRecovery(backupData);
                        List<DataSecurityEvent> events = new ArrayList<DataSecurityEvent>(0);
                        new BackupDataAsyncTask(context, events).execute();
                    } catch (IOException e) {
                        ToastOnMiddle.makeText(context, context.getString(R.string.recover_fail), 
                    } catch (BackupDataException bde) {
                        ToastOnMiddle.makeText(context, getExceptionMessageValue(bde.getMessage()), 
        super.onActivityResult(requestCode, resultCode, data);

Note that I used FileChannel to fill the temp file with the selected file content.
I don't know exactly yet why this problem occurs when trying to create or open a SQLite database directly from an internal storage folder. If someone can explain in the comments below, I would be very glad! =)
Lesson learned: Do not get a database file from a file chooser intent and try to use it directly to create or open a SQLite database. You better off using a temporary file instead.