Resizing images for different android screen densities

Resizing images to look good in different android screen densities can be tricky.
There are a few "density buckets" in android, they are: LDPI, MDPI, HDPI, XHDPI, XXHDPI and XXXHDPI.
PPI and DPI are basically the same for these calculations, they mean pixels or dots per inch.
Use these steps to get the best results:
  • Resize the image to be the smallest possible size that still looks good on the device you're testing on.
  • Find out the DPI of the device you are testing on by googling "device model PPI", for example, googling "moto g 2014 ppi" gives out 294 PPI.
  • Choose the correct density bucket your device is closest to:
    • LPDI – 0.75 * MDPI size (120 PPI)
    • MDPI – default (160 PPI)
    • TVDPI - 1.33 * MDPI size (213 PPI)
    • HDPI – 1.5 * MDPI size (240 PPI)
    • XHDPI – 2 * MDPI size (320 PPI)
    • XXHDPI – 3 * MDPI size (480 PPI)
      1. XXXHDPI – 4 * MDPI size (640 PPI)
    • Resize your image for all other sizes using the ratios between the buckets, for example: to move from XHDPI to HDPI, multiply by the ratio between the two buckets: 240 divided by 320 is 0.75, so the HDPI image should be 0.75 the size of the XHDPI one.
    • Notice that the steps are not consistent:
      • the jump from XHDPI to XXHDPI is 1.5 = 480/320
      • the jump from XXHDPI to XXXHDPI is 1.33 = 640/480

    Approximate string matching cheat sheet

    1. Levenshtein distance : if the pattern is coil, foil differs by one substitution, coils by one insertion, oil by one deletion, and foal by two substitutions.
    2. Damerau–Levenshtein distance : Like Levenshtein but including transpositions among its allowable operations.
    3. Jaro–Winkler distance : designed and best suited for short strings such as person names.
    4. Smith–Waterman algorithm : performs local sequence alignment for determining similar regions between two strings, instead of looking at the total sequence.
    5. Needleman–Wunsch algorithm : divides a large sequence into a series of smaller problems and uses the solutions to the smaller problems to reconstruct a solution to the larger problem.
    6. Soundex : a phonetic algorithm for indexing names by sound, as pronounced in English.
    7. Metaphone : improves on Soundex by using variations and inconsistencies in English spelling and pronunciation.

    A note to designers


    • Your job is to make things simpler, not cooler.
    • Restrain the product people from adding unnecessary features.
    • Save time for the engineering team, not make their lives harder.
    • Make sure that form follows function.

    Forgive the early adopter

    This is a letter to my friends and my colleagues.
    I'm truly asking your forgiveness.
    Forgive me for switching between messaging apps every few weeks.
    Forgive me for forcing you to use my unfinished apps and services.
    Forgive me for being mad at you when you buy the "wrong" phone, laptop or TV set.
    Forgive the early adopter in me :-)

    I really appreciate the fact that you're willing to go through all the beta phases and stick with it.
    Your devotion will not be overlooked when our robot overlords take over us and appoint me as one of their liaisons.

    Stop Complexity Insanity

    Whatever you're doing, stop, breath, and listen to these folks:


    • Isaac Newton - "Nature is pleased with simplicity. And nature is no dummy"
    • Leonardo da Vinci - "Simplicity is the ultimate sophistication"
    • Antoine de Saint ExupĂ©ry - "Perfection is attained, not when there is nothing more to add, but when there is nothing more to take away."
    • 1 Corinthians 14:33 - For God is not a God of confusion but of peace. As in all the churches of the saints.
    • Bruce Lee - "It is not a daily increase, but a daily decrease. Hack away at the inessentials."
    • Oded H. Breiner - "Remove to Improve."

    Apprenticeship-based education system


    • Each person will be allowed to choose his "master" and be his apprentice (e.g. a high school student can choose an experienced software developer as a "master").
    • In exchange for education, the master will get cheap labour (e.g. manual QA, or even personal help like cleaning).
    • Down to this point, it is very similar to the apprenticeship model that was common in the later Middle Ages and came to be supervised by craft guilds and town governments.
    • Here's the difference: back then, a master had high motivation to make his apprentice a good craftsman because he would often get him to work for him later on. Today, this model is rare because of the wide volatility in workplaces, and because of big companies.
    • So as an extra incentive, masters should get a cut of their apprentice's wage for a few years after the apprenticeship is over, but only if a certain wage level is achieved.
    • Benefits
      • Cheaper education to be paid by students in the future and only if their education was successful.
      • Higher quality education achieved by one-on-one sessions.
    • Dangers
      • Misuse of students by charlatans.
      • Hard to measure quality of teachers (masters).
    • Solutions to dangers
      • A rating system measured by the amount of money transferred from graduates to masters.
      • The more money that is transferred, the better was the education because the apprentice earns more.

    Android wear SDK impressions

    Android wear is extremely tied to intents and notifications.

    Everything is managed using NotificationCompat API. If an app has standard notifications they will appear in the watch, and all the buttons in the notification will be available in the watch.

    Everything in the watch has to be pro-active, besides apps that can register to a closed set of voice intents.

    It has a few of interesting tweaks to notifications:
    1. You can add a button to a notification that sends voice2text into the app.
    2. You can stack multiple notifications.
    3. Notifications can have pages for added data.
    4. Notifications can have an image background.

    why Android's search bar is dumb


    Pardon the rant but...
    Google's idea of a search bar is pretty darn useless.
    A search bar is supposed to be ready for text input the second you touch it.

    But no! it is too complicated for all-mighty G to create such a simple thing.
    Instead, when you touch that widget up there, it just opens the search app!
    Why waste so much space for what is essentially just a fucking icon!?!?!?

    I've been waiting on Google for 3 years to fix this, but now I'm putting my foot down!

    Google - you don't want to fix this?
    I'll fix it myself!

    Hello mrQuery
    mrQuery is a home button replacement that takes the solution to this problem to the next level.
    When you set mrQuery as your launcher it makes your android act like it's on cocaine.

    • Tap the home button, and get the keyboard open right away, start keying a name of an app and it launches immediately.
    • Access your favorite contacts and various system settings from the same box.
    • Every app you launch is added to a small "history" view above the search-bar for even faster access.


    Check it out on the play store.

    FAIL entrepreneurship

    F.A.I.L entrepreneurship:

    Fail
    Analyse
    Iterate
    Learn


    Fail
    As soon as you can, you are nothing without failures, they are the fuel for everything: motivation, learning and change. more...

    Analyse
    Analyse! Analyse! Analyse! set sensors on every possible data and decision point, every user click, tap and interaction. more...


    Iterate
    Repeat and try again, get into the FAIL loop, do the shortest iterations possible, every time you do a long iteration it's like running with your eyes closed. You have to zoom-out and re-iterate. more...


    Learn
    From your analysis and failures, commit to learning ahead of time. "If we fail at this, we learn that". more...

    Adding a jar to Android Studio

    Should be pretty simple right?
    Well, the UI doesn't support it right now but it is pretty simple to handle manually, so you'll have to open your build.gradle file that should be in:
    /projectName/

    And add the following:
    dependencies {
        compile files('libs/jarFileName.jar')
    }


    Example:

    buildscript {
        repositories {
            maven { url 'http://repo1.maven.org/maven2' }
        }
        dependencies {
            classpath 'com.android.tools.build:gradle:0.4'
        }
    }
    apply plugin: 'android'

    dependencies {
        compile files('libs/android-support-v4.jar')
        compile files('libs/MixpanelAPI.jar')
    }

    android {
        compileSdkVersion 17
        buildToolsVersion "17.0.0"

        defaultConfig {
            minSdkVersion 14
            targetSdkVersion 16
        }
    }