Johannes Orgis Danny Preussler 
proudly presents 
More Android Code Puzzles 
Backrground © Tsahi Levent-Levi, flickr.com/photos/86979666@N00/8161660138
background © Howard Lake, flickr.com/photos/howardlake/5439888760 
How it works…. 
Mubarak ALThani, ⓘSAW †he dirty soul ☠Part I☠, CC by 2.0, flickr.com/photos/althani-cornerstone/ 
2370990198
I’ll be back 
class MyApplication extends Application { 
public void onTerminate() { 
super.onTerminate(); 
Log.i("puzzle", "terminate"); 
}} 
When I close the last activity on my phone: 
a. We see the log output immediately 
b. We see the log output only after GC ran 
c. We only see the log output when user closes 
background © Howard Lake, flickr.com/photos/howardlake/5439888760 
via task manager 
d. We never see the log output
I’ll be back 
class MyApplication extends Application { 
public void onTerminate() { 
super.onTerminate(); 
Log.i("puzzle", "terminate"); 
}} 
When I close the last activity on my phone: 
a. We see the log output immediately 
b. We see the log output only after GC ran 
c. We only see the log output when user closes 
background © Howard Lake, flickr.com/photos/howardlake/5439888760 
via task manager 
d. We never see the log output
This method is for use in emulated process environments. 
It will never be called on a production Android device, 
where processes are removed by simply killing them; no 
user code (including this callback) is executed when 
doing so. 
http://developer.android.com/reference/android/app/Application.html 
Android is [..] tricky [..], the concept of exiting the 
application is not like any other operating system [..] 
When press back from the last activity the user gets a 
feeling that the application is closed, but the app still 
remain in the memory ready to quick launch when you 
start next time. 
http://www.maxters.net/2012/11/android-last-activity-stack/ 
background © Howard Lake, flickr.com/photos/howardlake/5439888760 
I’ll be back
background © Howard Lake, flickr.com/photos/howardlake/5439888760 
Did you know? 
Did you know about 
requestWindowFeature( 
FEATURE_INDETERMINATE_PROGRESS) 
that on android 4 progress is visible by default 
and on 4.1 and higher hidden by default?
background © Howard Lake, flickr.com/photos/howardlake/5439888760 
the way of life 
protected void onCreate(Bundle arg0) { 
super.onCreate(arg0); 
trace("onCreated"); 
finish(); 
trace("finished");} 
protected void onPause() { 
super.onPause(); 
trace("onPaused");} 
protected void onStart() { 
super.onStart(); 
trace("onStarted");} 
…. 
What is the trace output here? 
a. “onCreate”, “finished”, “onStart”, “onResume”, “onPause”, “onStop”, 
“onDestroy” 
b. “onCreate”, “finished”, “onPause”, “onStop”, “onDestroy” 
c. “onCreate”, “finished”, “onDestroy” 
d. “onCreate”, “onDestroy” 
e. an exception because of calling finish from onCreate()
background © Howard Lake, flickr.com/photos/howardlake/5439888760 
the way of life 
protected void onCreate(Bundle arg0) { 
super.onCreate(arg0); 
trace("onCreated"); 
finish(); 
trace("finished");} 
protected void onPause() { 
super.onPause(); 
trace("onPaused");} 
protected void onStart() { 
super.onStart(); 
trace("onStarted");} 
…. 
What is the trace output here? 
a. “onCreate”, “finished”, “onStart”, “onResume”, “onPause”, “onStop”, 
“onDestroy” 
b. “onCreate”, “finished”, “onPause”, “onStop”, “onDestroy” 
c. “onCreate”, “finished”, “onDestroy” 
d. “onCreate”, “onDestroy” 
e. an exception because of calling finish from onCreate()
the way of life 
● finish() will stop the lifecycle creation at 
current point and starts the shutdown 
procedure from that method on 
● The current method will finish so be careful 
when using fragments: 
a simple super.onCreate() of Activity 
might start a lot of other lifecycles methods 
before finish will do it’s job 
background © Howard Lake, flickr.com/photos/howardlake/5439888760 
● Use isFinishing() if needed
Part of Application 
Theme 
background © Howard Lake, flickr.com/photos/howardlake/5439888760 
but daddy said ... 
<style name="MyTextViewStyle" parent="android:Widget.TextView"> 
<item name="android:textColor"> #F00</item> 
<item name="android:textSize"> 50dp</item> </style> 
<FrameLayout ... android:layout_width=" match_parent" 
android:layout_height=" 25dp"> 
<TextView … " wrap_content" android:text=" Hello World"/></FrameLayout> 
public View getView(int position, View convertView, ViewGroup parent) { ... 
View v = mInflater.inflate( R.layout.row, null, false); …} 
What do the rows look like: 
a. “Hello World” in 50dp red, row height wrap 
b. “Hello World” in 50dp red, row height 25dp 
c. “Hello World” in normal size, grey , row height wrap 
d. “Hello World” in normal size, grey , row height 25dp 
e. UnsupportedOperationException
background © Howard Lake, flickr.com/photos/howardlake/5439888760 
but daddy said ... 
<style name="MyTextViewStyle" parent="android:Widget.TextView"> 
<item name="android:textColor"> #F00</item> 
<item name="android:textSize"> 50dp</item> </style> 
<FrameLayout ... android:layout_width=" match_parent" 
android:layout_height=" 25dp"> 
<TextView … " wrap_content" android:text=" Hello World"/></FrameLayout> 
public View getView(int position, View convertView, ViewGroup parent) { ... 
View v = mInflater.inflate( R.layout.row, null, false); …} 
What do the rows look like: 
a. “Hello World” in 50dp red, row height wrap 
b. “Hello World” in 50dp red, row height 25dp 
c. “Hello World” in normal size, grey , row height wrap 
d. “Hello World” in normal size, grey , row height 25dp 
e. UnsupportedOperationException
background © Howard Lake, flickr.com/photos/howardlake/5439888760 
but daddy said ... 
Inflate with parent if possible
fun with menus... 
Whats the log output when clicking the menu item? 
a) “in activity”, “done in activity”, “in fragment” 
b) “in activity”, “in fragment”, “done in activity” 
c) “in fragment”, “in activity”, “done in activity” 
background © Howard Lake, flickr.com/photos/howardlake/5439888760 
Fragment with setHasOptionsMenu(true); 
... 
public boolean onOptionsItemSelected(MenuItem item) { 
Log.i("menu", "in fragment"); 
return super.onOptionsItemSelected(item); } 
Activity: 
public boolean onOptionsItemSelected(MenuItem item) { 
Log.i("menu", "in activity"); 
boolean b = super.onOptionsItemSelected(item); 
Log.i("menu", "done in activity"); 
return b;}
fun with menus... 
Whats the log output when clicking the menu item? 
a) “in activity”, “done in activity”, “in fragment” 
b) “in activity”, “in fragment”, “done in activity” 
c) “in fragment”, “in activity”, “done in activity” 
background © Howard Lake, flickr.com/photos/howardlake/5439888760 
Fragment with setHasOptionsMenu(true); 
... 
public boolean onOptionsItemSelected(MenuItem item) { 
Log.i("menu", "in fragment"); 
return super.onOptionsItemSelected(item); } 
Activity: 
public boolean onOptionsItemSelected(MenuItem item) { 
Log.i("menu", "in activity"); 
boolean b = super.onOptionsItemSelected(item); 
Log.i("menu", "done in activity"); 
return b;}
background © Howard Lake, flickr.com/photos/howardlake/5439888760 
Did you know? 
● Did you know that Cursor did not 
implement Closeable before ICS? 
● Not found in JavaDoc 
● Will lead to crash in sth like: 
Closeables.closeQuietly(...) 
● https://code.google. 
com/p/android/issues/detail?id=67052
waiting for the end 
public void onActivityResult(int req, int res, Intent dt) { 
Log.e("handle", "frag1"); 
super.onActivityResult(req, res, dt); 
Log.e("handle", "frag2");} 
Activity: 
protected void onActivityResult(int req, int res, Intent dt) { 
Log.e("handle", "activ1"); 
super.onActivityResult(req, res, dt); 
Log.e("handle", "activ2");} 
background © Howard Lake, flickr.com/photos/howardlake/5439888760 
Fragment: 
startActivityForResult(...); 
What’s the output when tasks returns? 
a) “frag1”, “frag2”, “activ1”, “activ2” 
b) “activ1”, “activ2”, “frag1”, “frag2” 
c) “activ1”, “frag1”, “frag2”, “activ2” 
d) “frag1”, “frag2” 
e) “activ1”, “activ2”
waiting for the end 
public void onActivityResult(int req, int res, Intent dt) { 
Log.e("handle", "frag1"); 
super.onActivityResult(req, res, dt); 
Log.e("handle", "frag2");} 
Activity: 
protected void onActivityResult(int req, int res, Intent dt) { 
Log.e("handle", "activ1"); 
super.onActivityResult(req, res, dt); 
Log.e("handle", "activ2");} 
background © Howard Lake, flickr.com/photos/howardlake/5439888760 
Fragment: 
startActivityForResult(...); 
What’s the output when tasks returns? 
a) “frag1”, “frag2”, “activ1”, “activ2” 
b) “activ1”, “activ2”, “frag1”, “frag2” 
c) “activ1”, “frag1”, “frag2”, “activ2” 
d) “frag1”, “frag2” 
e) “activ1”, “activ2”
background © Howard Lake, flickr.com/photos/howardlake/5439888760 
Toast 
<style name="MyTextViewStyle" parent="android:Widget.TextView"> 
<item name="android:textColor"> #F00</item> 
<item name="android:textSize"> 50dp</item> </style> 
Toast.makeText( myActivity, "Hello World", Toast.LENGTH_LONG).show(); 
What does the Toast look like: 
a. “Hello World” in 50dp, red 
b. “Hello World” in standard size, red 
c. “Hello World” in 50dp, grey“ 
d. “Hello World” in standard size, grey 
e. AndroidRuntimeException
background © Howard Lake, flickr.com/photos/howardlake/5439888760 
Toast 
<style name="MyTextViewStyle" parent="android:Widget.TextView"> 
<item name="android:textColor"> #F00</item> 
<item name="android:textSize"> 50dp</item> </style> 
Toast.makeText( myActivity, "Hello World", Toast.LENGTH_LONG).show(); 
What does the Toast look like: 
a. “Hello World” in 50dp, red 
b. “Hello World” in standard size, red 
c. “Hello World” in 50dp, grey“ 
d. “Hello World” in standard size, grey 
e. AndroidRuntimeException
Toast 
● use Toast always with the applicationcontext 
● use setView for custom views 
background © Howard Lake, flickr.com/photos/howardlake/5439888760
background © Howard Lake, flickr.com/photos/howardlake/5439888760 
Did you know? 
OnFocusChangeListener added in 
the Fragment’s onCreateView() 
method won’t get called if you request 
focus in the layout XML
background © Howard Lake, flickr.com/photos/howardlake/5439888760 
part of the queue... 
protected void onCreate(Bundle arg0) { 
super.onCreate(arg0); 
trace("before"); 
runOnUiThread(new Runnable() { 
public void run() { 
trace("delayed");} 
}); 
trace("after"); 
} 
What is the trace output here: 
a. “before”, “after”, “delayed” 
b. “before” and then random order 
c. “before”, “delayed”, “after”
background © Howard Lake, flickr.com/photos/howardlake/5439888760 
part of the queue... 
protected void onCreate(Bundle arg0) { 
super.onCreate(arg0); 
trace("before"); 
runOnUiThread(new Runnable() { 
public void run() { 
trace("delayed");} 
}); 
trace("after"); 
} 
What is the trace output here: 
a. “before”, “after”, “delayed” 
b. “before” and then random order 
c. “before”, “delayed”, “after”
part of the queue... 
// from android open source: 
public final void runOnUiThread(Runnable 
action) { 
if (Thread.currentThread() != mUiThread) { 
background © Howard Lake, flickr.com/photos/howardlake/5439888760 
mHandler.post(action); 
} else { 
action.run(); 
} 
} use Handler with post (delay) when you 
want to queue
background © Howard Lake, flickr.com/photos/howardlake/5439888760 
Did you know? 
Did you know that what happens when 
you set an onItemClickListener 
on a Spinner? :) 
java.lang.RuntimeException: 
setOnItemClickListener cannot be used with a 
spinner.
Comin’ up from behind... 
background © Howard Lake, flickr.com/photos/howardlake/5439888760 
protected void onCreate(Bundle arg0) { 
super.onCreate(arg0); 
new Thread(new Runnable() { 
public void run() { 
getFragmentManager() 
.beginTransaction() 
.add(android.R.id.content, new SomeFragment()) 
.commit(); 
}}).start(); 
} 
What happens when running this code? 
a. exception on beginTransaction 
as we are not on main thread 
b. exception on commit as we are not on main thread 
c. transaction will be done and fragment shown 
d. transaction will be done but nothing happens
Comin’ up from behind... 
background © Howard Lake, flickr.com/photos/howardlake/5439888760 
protected void onCreate(Bundle arg0) { 
super.onCreate(arg0); 
new Thread(new Runnable() { 
public void run() { 
getFragmentManager() 
.beginTransaction() 
.add(android.R.id.content, new SomeFragment()) 
.commit(); 
}}).start(); 
} 
What happens when running this code? 
a. exception on beginTransaction 
as we are not on main thread 
b. exception on commit as we are not on main thread 
c. transaction will be done and fragment shown 
d. transaction will be done but nothing happens
Comin’ up from behind... 
● “After a FragmentTransaction is committed 
with FragmentTransaction.commit(), it is 
scheduled to be executed asynchronously 
on the process's main thread.” 
http://developer.android.com/reference/android/app/FragmentManager. 
html 
● use executePendingTransactions to 
do the transaction immediately 
but then be sure you are on main thread 
background © Howard Lake, flickr.com/photos/howardlake/5439888760
background © Howard Lake, flickr.com/photos/howardlake/5439888760 
pick me, pick me 
<item android:drawable="@drawable/ thumbsup" android:state_enabled=" true" 
android:state_focused=" false" 
android:state_pressed=" false"/> 
<item android:drawable="@drawable/ thumbsdown" android:state_pressed=" true"/> 
<ImageButton … " wrap_content" 
android:src="@drawable/ mythumbsselector" 
android:focusable=" true" android:focusableInTouchMode=" true" 
android:background=" #00000000"/> 
What do you see: 
a. “thumbsup” 
b. “thumbsdown” 
c. nothing
background © Howard Lake, flickr.com/photos/howardlake/5439888760 
pick me, pick me 
<item android:drawable="@drawable/ thumbsup" android:state_enabled=" true" 
android:state_focused=" false" 
android:state_pressed=" false"/> 
<item android:drawable="@drawable/ thumbsdown" android:state_pressed=" true"/> 
<ImageButton … " wrap_content" 
android:src="@drawable/ mythumbsselector" 
android:focusable=" true" android:focusableInTouchMode=" true" 
android:background=" #00000000"/> 
What do you see: 
a. “thumbsup” 
b. “thumbsdown” 
c. nothing
background © Howard Lake, flickr.com/photos/howardlake/5439888760 
pick me, pick me 
<item android:drawable="@drawable/ thumbsup" android:state_enabled=" true" 
android:state_focused=" false" 
android:state_pressed=" false"/> 
<item android:drawable="@drawable/ thumbsdown" android:state_pressed=" true"/> 
<item android:drawable="@drawable/default" /> 
Have a default state as last item
something borrowed, something new 
protected void onNewIntent(Intent intent) { 
background © Howard Lake, flickr.com/photos/howardlake/5439888760 
trace(intent.getStringExtra("KEY") + 
":" + getIntent().getStringExtra("KEY")); 
super.onNewIntent(intent); 
trace(intent.getStringExtra("KEY")+ 
":"+getIntent().getStringExtra("KEY")); 
} 
If this activity is FLAG_ACTIVITY_SINGLE_TOP and 
we restart it with KEY=value what does it trace? 
a) “value:null”, “value:value” 
b) “value:value”, “value:value” 
c) “value:null”, “value:null”
something borrowed, something new 
protected void onNewIntent(Intent intent) { 
background © Howard Lake, flickr.com/photos/howardlake/5439888760 
trace(intent.getStringExtra("KEY") + 
":" + getIntent().getStringExtra("KEY")); 
super.onNewIntent(intent); 
trace(intent.getStringExtra("KEY")+ 
":"+getIntent().getStringExtra("KEY")); 
} 
If this activity is FLAG_ACTIVITY_SINGLE_TOP and 
we restart it with KEY=value what does it trace? 
a) “value:null”, “value:value” 
b) “value:value”, “value:value” 
c) “value:null”, “value:null”
something borrowed, something new 
getIntent() always returns you the 
original intent! 
Suggested solution on stackoverflow: 
use setIntent() in onNewIntent() 
background © Howard Lake, flickr.com/photos/howardlake/5439888760 
Let’s try!
background © Howard Lake, flickr.com/photos/howardlake/5439888760 
wind of change 
protected void onResume() { 
super.onResume(); 
Intent intent = getIntent(); 
intent.putExtra("KEY", 1 + intent.getIntExtra("KEY", 0)); 
setIntent(intent); 
showToast(valueOf(getIntent(). getIntExtra("KEY", 0)); 
} 
What is the Toast message after background 
and foreground switch? 
a. 1,2,3… 
b. 1,1,1... 
c. 0,0,0... 
d. sometimes a, sometimes b
background © Howard Lake, flickr.com/photos/howardlake/5439888760 
wind of change 
protected void onResume() { 
super.onResume(); 
Intent intent = getIntent(); 
intent.putExtra("KEY", 1 + intent.getIntExtra("KEY", 0)); 
setIntent(intent); 
showToast(valueOf(getIntent(). getIntExtra("KEY", 0)); 
} 
What is the Toast message after background 
and foreground switch? 
a. 1,2,3… 
b. 1,1,1... 
c. 0,0,0... 
d. sometimes a, sometimes b
// from android open source project: 
public void setIntent(Intent newIntent) { 
background © Howard Lake, flickr.com/photos/howardlake/5439888760 
wind of change 
mIntent = newIntent; 
} 
● Depends on if activity get recreated 
● When using “don’t keep activities” developer 
option this will always be: 1,1,1…. 
Try to avoid setIntent()! 
Always persist your state!
background © Howard Lake, flickr.com/photos/howardlake/5439888760 
Lost in transition 
<transition xmlns:android="http://schemas.android.com/apk/res/android"> 
<item android:drawable="@android:color/ transparent"/> 
<item android:drawable="@android:color/ black"/> 
</transition> 
<ImageButton ..."wrap_content" android:paddingLeft=" 100dp" 
android:src="@android:drawable/ btn_star_big_off"/> 
public void doBackgroudTransition(Imagebutton button){ 
button.setBackgroundResource(R.drawable.transitionbackground); 
} 
What does the Button look like: 
a) 
c) 
b) 
d)
background © Howard Lake, flickr.com/photos/howardlake/5439888760 
Lost in transition 
<transition xmlns:android="http://schemas.android.com/apk/res/android"> 
<item android:drawable="@android:color/ transparent"/> 
<item android:drawable="@android:color/ black"/> 
</transition> 
<ImageButton ..."wrap_content" android:paddingLeft=" 100dp" 
android:src="@android:drawable/ btn_star_big_off"/> 
public void doBackgroudTransition(Imagebutton button){ 
button.setBackgroundResource(R.drawable.transitionbackground); 
} 
What does the Button look like: 
a) 
c) 
b) 
d)
background © Howard Lake, flickr.com/photos/howardlake/5439888760 
Lost in transition 
<transition xmlns:android="http://schemas.android.com/apk/res/android"> 
<item android:drawable="@android:color/ transparent"/> 
<item android:drawable="@android:color/ black"/> 
</transition> 
<ImageButton ..."wrap_content" android:paddingLeft=" 100dp" 
android:src="@android:drawable/ btn_star_big_off"/> 
public void doBackgroudTransition(Imagebutton button){ 
button.setBackgroundResource(R.drawable.transitionbackground); 
} 
What does the Button look like: 
a) 
c) 
b) 
d)
Lost in transition 
● check your padding when using 
TransitionDrawable 
background © Howard Lake, flickr.com/photos/howardlake/5439888760
background © Howard Lake, flickr.com/photos/howardlake/5439888760 
wanna be lonely? 
"singleTask" 
The system creates the activity at the root of a 
new task and routes the intent to it. However, if 
an instance of the activity already exists, the 
system routes the intent to existing instance 
through a call to its onNewIntent() method, 
rather than creating a new one. 
Let’s try
background © Howard Lake, flickr.com/photos/howardlake/5439888760 
wanna be lonely? 
protected void onResume() { 
super.onResume(); 
… 
startActivityForResult(new Intent(....); 
trace("started"}; } 
} 
protected void onActivityResult(int req, int res, Intent data){ 
super.onActivityResult(req, res, data); 
trace("done"}; 
} 
What is the log output when we run this activity with 
android:launchMode="singleTask"? 
a. nothing, an exception is thrown in startActivityForResult 
b. “started” and “done” if started returns 
c. “started” and never “done” ignoring result 
d. “started” and immediately “done”
background © Howard Lake, flickr.com/photos/howardlake/5439888760 
wanna be lonely? 
protected void onResume() { 
super.onResume(); 
… 
startActivityForResult(new Intent(....); 
trace("started"}; } 
} 
protected void onActivityResult(int req, int res, Intent data){ 
super.onActivityResult(req, res, data); 
trace("done"}; 
} 
What is the log output when we run this activity with 
android:launchMode="singleTask"? 
a. nothing, an exception is thrown in startActivityForResult 
b. “started” and “done” if started returns 
c. “started” and never “done” ignoring result 
d. “started” and immediately “done”
wanna be lonely? 
● in single-task mode you can not use 
startActivityForResult. 
Will immediately return with: Activity. 
RESULT_CANCELED 
● “singleTask and singleInstance — are not 
appropriate for most applications, since they 
result in an interaction model that is likely to 
be unfamiliar to users and is very different 
from most other applications.” 
http://developer.android.com/guide/topics/manifest/activity-element.html 
background © Howard Lake, flickr.com/photos/howardlake/5439888760
● ...that Android’s email pattern does not see new 
international addresses like юзер@екзампл.ком as valid? 
background © Howard Lake, flickr.com/photos/howardlake/5439888760 
Did you know? 
public static final Pattern EMAIL_ADDRESS 
= Pattern.compile( 
"[a-zA-Z0-9+._%-+]{1,256}" + 
"@" + 
"[a-zA-Z0-9][a-zA-Z0-9-]{0,64}" + 
"(" + 
"." + 
"[a-zA-Z0-9][a-zA-Z0-9-]{0,25}" + 
")+" 
);
to all the people in the world 
background © Howard Lake, flickr.com/photos/howardlake/5439888760 
new Thread( 
new Runnable() { 
public void run() { 
LocalBroadcastManager.getInstance( getApplicationContext()) 
.sendBroadcast(new Intent(ACTION));} 
}).start(); 
public void onReceive(Context context, Intent intent) { 
((ArrayAdapter) getListAdapter()). notifyDataSetChanged(); 
} 
What happens: 
a. error in run() because of applicationcontext 
b. error in run() because not in MainThread 
c. error in onReceive() - notifyDatasetChanged needs MainThread 
d. no error, everything is fine, kkthxbye
to all the people in the world 
background © Howard Lake, flickr.com/photos/howardlake/5439888760 
new Thread( 
new Runnable() { 
public void run() { 
LocalBroadcastManager.getInstance( getApplicationContext()) 
.sendBroadcast(new Intent(ACTION));} 
}).start(); 
public void onReceive(Context context, Intent intent) { 
((ArrayAdapter) getListAdapter()). notifyDataSetChanged(); 
} 
What happens: 
a. error in run() because of applicationcontext 
b. error in run() because not in MainThread 
c. error in onReceive() - notifyDatasetChanged needs MainThread 
d. no error, everything is fine, kkthxbye
to all the people in the world 2 
static final String[] data = new String[]{"A","B","C"}; 
private void sendBroadcast(){ 
Intent intent = new Intent();intent.setAction(ACTION); 
intent.putExtra("EXTRA",data ); 
LocalBroadcastManager.getInstance(getActivity()).sendBroadcast(intent); 
data[0] = "D";} 
public void onReceive(Context context, Intent intent) { 
String[] mydata = intent.getStringArrayExtra("EXTRA"); 
mydata[2] = "F"; 
background © Howard Lake, flickr.com/photos/howardlake/5439888760 
} 
What is the content of data after onReceive: 
a. [A, B, C] 
b. [D, B, C] 
c. [D, B, F] 
d. Exception: ConcurrentModificationException 
e. Compiler Error: data is final and cannot be changed
to all the people in the world 2 
static final String[] data = new String[]{"A","B","C"}; 
private void sendBroadcast(){ 
Intent intent = new Intent();intent.setAction(ACTION); 
intent.putExtra("EXTRA",data ); 
LocalBroadcastManager.getInstance(getActivity()).sendBroadcast(intent); 
data[0] = "D";} 
public void onReceive(Context context, Intent intent) { 
String[] mydata = intent.getStringArrayExtra("EXTRA"); 
mydata[2] = "F"; 
background © Howard Lake, flickr.com/photos/howardlake/5439888760 
} 
What is the content of data after onReceive: 
a. [A, B, C] 
b. [D, B, C] 
c. [D, B, F] 
d. Exception: ConcurrentModificationException 
e. Compiler Error: data is final and cannot be changed
to all the people in the world 2 
● With LocalBroadcastManager you get the original 
Object reference, no serialisation 
● this is not the case for Context#sendBroadcast 
(Intent i) 
background © Howard Lake, flickr.com/photos/howardlake/5439888760
● plus.google.com/+DannyPreussler, Thanks 
background © Howard Lake, flickr.com/photos/howardlake/5439888760 
github.com/dpreussler 
● plus.google.com/+JohannesOrgis 
github.com/joorg 
● Check Wunderlist & 
Groupon Engineering blogs 
● Please Download: enviQ 
ESA satellite based 
Air Quality check app

More android code puzzles

  • 1.
    Johannes Orgis DannyPreussler proudly presents More Android Code Puzzles Backrground © Tsahi Levent-Levi, flickr.com/photos/86979666@N00/8161660138
  • 2.
    background © HowardLake, flickr.com/photos/howardlake/5439888760 How it works…. Mubarak ALThani, ⓘSAW †he dirty soul ☠Part I☠, CC by 2.0, flickr.com/photos/althani-cornerstone/ 2370990198
  • 3.
    I’ll be back class MyApplication extends Application { public void onTerminate() { super.onTerminate(); Log.i("puzzle", "terminate"); }} When I close the last activity on my phone: a. We see the log output immediately b. We see the log output only after GC ran c. We only see the log output when user closes background © Howard Lake, flickr.com/photos/howardlake/5439888760 via task manager d. We never see the log output
  • 4.
    I’ll be back class MyApplication extends Application { public void onTerminate() { super.onTerminate(); Log.i("puzzle", "terminate"); }} When I close the last activity on my phone: a. We see the log output immediately b. We see the log output only after GC ran c. We only see the log output when user closes background © Howard Lake, flickr.com/photos/howardlake/5439888760 via task manager d. We never see the log output
  • 5.
    This method isfor use in emulated process environments. It will never be called on a production Android device, where processes are removed by simply killing them; no user code (including this callback) is executed when doing so. http://developer.android.com/reference/android/app/Application.html Android is [..] tricky [..], the concept of exiting the application is not like any other operating system [..] When press back from the last activity the user gets a feeling that the application is closed, but the app still remain in the memory ready to quick launch when you start next time. http://www.maxters.net/2012/11/android-last-activity-stack/ background © Howard Lake, flickr.com/photos/howardlake/5439888760 I’ll be back
  • 6.
    background © HowardLake, flickr.com/photos/howardlake/5439888760 Did you know? Did you know about requestWindowFeature( FEATURE_INDETERMINATE_PROGRESS) that on android 4 progress is visible by default and on 4.1 and higher hidden by default?
  • 7.
    background © HowardLake, flickr.com/photos/howardlake/5439888760 the way of life protected void onCreate(Bundle arg0) { super.onCreate(arg0); trace("onCreated"); finish(); trace("finished");} protected void onPause() { super.onPause(); trace("onPaused");} protected void onStart() { super.onStart(); trace("onStarted");} …. What is the trace output here? a. “onCreate”, “finished”, “onStart”, “onResume”, “onPause”, “onStop”, “onDestroy” b. “onCreate”, “finished”, “onPause”, “onStop”, “onDestroy” c. “onCreate”, “finished”, “onDestroy” d. “onCreate”, “onDestroy” e. an exception because of calling finish from onCreate()
  • 8.
    background © HowardLake, flickr.com/photos/howardlake/5439888760 the way of life protected void onCreate(Bundle arg0) { super.onCreate(arg0); trace("onCreated"); finish(); trace("finished");} protected void onPause() { super.onPause(); trace("onPaused");} protected void onStart() { super.onStart(); trace("onStarted");} …. What is the trace output here? a. “onCreate”, “finished”, “onStart”, “onResume”, “onPause”, “onStop”, “onDestroy” b. “onCreate”, “finished”, “onPause”, “onStop”, “onDestroy” c. “onCreate”, “finished”, “onDestroy” d. “onCreate”, “onDestroy” e. an exception because of calling finish from onCreate()
  • 9.
    the way oflife ● finish() will stop the lifecycle creation at current point and starts the shutdown procedure from that method on ● The current method will finish so be careful when using fragments: a simple super.onCreate() of Activity might start a lot of other lifecycles methods before finish will do it’s job background © Howard Lake, flickr.com/photos/howardlake/5439888760 ● Use isFinishing() if needed
  • 10.
    Part of Application Theme background © Howard Lake, flickr.com/photos/howardlake/5439888760 but daddy said ... <style name="MyTextViewStyle" parent="android:Widget.TextView"> <item name="android:textColor"> #F00</item> <item name="android:textSize"> 50dp</item> </style> <FrameLayout ... android:layout_width=" match_parent" android:layout_height=" 25dp"> <TextView … " wrap_content" android:text=" Hello World"/></FrameLayout> public View getView(int position, View convertView, ViewGroup parent) { ... View v = mInflater.inflate( R.layout.row, null, false); …} What do the rows look like: a. “Hello World” in 50dp red, row height wrap b. “Hello World” in 50dp red, row height 25dp c. “Hello World” in normal size, grey , row height wrap d. “Hello World” in normal size, grey , row height 25dp e. UnsupportedOperationException
  • 11.
    background © HowardLake, flickr.com/photos/howardlake/5439888760 but daddy said ... <style name="MyTextViewStyle" parent="android:Widget.TextView"> <item name="android:textColor"> #F00</item> <item name="android:textSize"> 50dp</item> </style> <FrameLayout ... android:layout_width=" match_parent" android:layout_height=" 25dp"> <TextView … " wrap_content" android:text=" Hello World"/></FrameLayout> public View getView(int position, View convertView, ViewGroup parent) { ... View v = mInflater.inflate( R.layout.row, null, false); …} What do the rows look like: a. “Hello World” in 50dp red, row height wrap b. “Hello World” in 50dp red, row height 25dp c. “Hello World” in normal size, grey , row height wrap d. “Hello World” in normal size, grey , row height 25dp e. UnsupportedOperationException
  • 12.
    background © HowardLake, flickr.com/photos/howardlake/5439888760 but daddy said ... Inflate with parent if possible
  • 13.
    fun with menus... Whats the log output when clicking the menu item? a) “in activity”, “done in activity”, “in fragment” b) “in activity”, “in fragment”, “done in activity” c) “in fragment”, “in activity”, “done in activity” background © Howard Lake, flickr.com/photos/howardlake/5439888760 Fragment with setHasOptionsMenu(true); ... public boolean onOptionsItemSelected(MenuItem item) { Log.i("menu", "in fragment"); return super.onOptionsItemSelected(item); } Activity: public boolean onOptionsItemSelected(MenuItem item) { Log.i("menu", "in activity"); boolean b = super.onOptionsItemSelected(item); Log.i("menu", "done in activity"); return b;}
  • 14.
    fun with menus... Whats the log output when clicking the menu item? a) “in activity”, “done in activity”, “in fragment” b) “in activity”, “in fragment”, “done in activity” c) “in fragment”, “in activity”, “done in activity” background © Howard Lake, flickr.com/photos/howardlake/5439888760 Fragment with setHasOptionsMenu(true); ... public boolean onOptionsItemSelected(MenuItem item) { Log.i("menu", "in fragment"); return super.onOptionsItemSelected(item); } Activity: public boolean onOptionsItemSelected(MenuItem item) { Log.i("menu", "in activity"); boolean b = super.onOptionsItemSelected(item); Log.i("menu", "done in activity"); return b;}
  • 15.
    background © HowardLake, flickr.com/photos/howardlake/5439888760 Did you know? ● Did you know that Cursor did not implement Closeable before ICS? ● Not found in JavaDoc ● Will lead to crash in sth like: Closeables.closeQuietly(...) ● https://code.google. com/p/android/issues/detail?id=67052
  • 16.
    waiting for theend public void onActivityResult(int req, int res, Intent dt) { Log.e("handle", "frag1"); super.onActivityResult(req, res, dt); Log.e("handle", "frag2");} Activity: protected void onActivityResult(int req, int res, Intent dt) { Log.e("handle", "activ1"); super.onActivityResult(req, res, dt); Log.e("handle", "activ2");} background © Howard Lake, flickr.com/photos/howardlake/5439888760 Fragment: startActivityForResult(...); What’s the output when tasks returns? a) “frag1”, “frag2”, “activ1”, “activ2” b) “activ1”, “activ2”, “frag1”, “frag2” c) “activ1”, “frag1”, “frag2”, “activ2” d) “frag1”, “frag2” e) “activ1”, “activ2”
  • 17.
    waiting for theend public void onActivityResult(int req, int res, Intent dt) { Log.e("handle", "frag1"); super.onActivityResult(req, res, dt); Log.e("handle", "frag2");} Activity: protected void onActivityResult(int req, int res, Intent dt) { Log.e("handle", "activ1"); super.onActivityResult(req, res, dt); Log.e("handle", "activ2");} background © Howard Lake, flickr.com/photos/howardlake/5439888760 Fragment: startActivityForResult(...); What’s the output when tasks returns? a) “frag1”, “frag2”, “activ1”, “activ2” b) “activ1”, “activ2”, “frag1”, “frag2” c) “activ1”, “frag1”, “frag2”, “activ2” d) “frag1”, “frag2” e) “activ1”, “activ2”
  • 18.
    background © HowardLake, flickr.com/photos/howardlake/5439888760 Toast <style name="MyTextViewStyle" parent="android:Widget.TextView"> <item name="android:textColor"> #F00</item> <item name="android:textSize"> 50dp</item> </style> Toast.makeText( myActivity, "Hello World", Toast.LENGTH_LONG).show(); What does the Toast look like: a. “Hello World” in 50dp, red b. “Hello World” in standard size, red c. “Hello World” in 50dp, grey“ d. “Hello World” in standard size, grey e. AndroidRuntimeException
  • 19.
    background © HowardLake, flickr.com/photos/howardlake/5439888760 Toast <style name="MyTextViewStyle" parent="android:Widget.TextView"> <item name="android:textColor"> #F00</item> <item name="android:textSize"> 50dp</item> </style> Toast.makeText( myActivity, "Hello World", Toast.LENGTH_LONG).show(); What does the Toast look like: a. “Hello World” in 50dp, red b. “Hello World” in standard size, red c. “Hello World” in 50dp, grey“ d. “Hello World” in standard size, grey e. AndroidRuntimeException
  • 20.
    Toast ● useToast always with the applicationcontext ● use setView for custom views background © Howard Lake, flickr.com/photos/howardlake/5439888760
  • 21.
    background © HowardLake, flickr.com/photos/howardlake/5439888760 Did you know? OnFocusChangeListener added in the Fragment’s onCreateView() method won’t get called if you request focus in the layout XML
  • 22.
    background © HowardLake, flickr.com/photos/howardlake/5439888760 part of the queue... protected void onCreate(Bundle arg0) { super.onCreate(arg0); trace("before"); runOnUiThread(new Runnable() { public void run() { trace("delayed");} }); trace("after"); } What is the trace output here: a. “before”, “after”, “delayed” b. “before” and then random order c. “before”, “delayed”, “after”
  • 23.
    background © HowardLake, flickr.com/photos/howardlake/5439888760 part of the queue... protected void onCreate(Bundle arg0) { super.onCreate(arg0); trace("before"); runOnUiThread(new Runnable() { public void run() { trace("delayed");} }); trace("after"); } What is the trace output here: a. “before”, “after”, “delayed” b. “before” and then random order c. “before”, “delayed”, “after”
  • 24.
    part of thequeue... // from android open source: public final void runOnUiThread(Runnable action) { if (Thread.currentThread() != mUiThread) { background © Howard Lake, flickr.com/photos/howardlake/5439888760 mHandler.post(action); } else { action.run(); } } use Handler with post (delay) when you want to queue
  • 25.
    background © HowardLake, flickr.com/photos/howardlake/5439888760 Did you know? Did you know that what happens when you set an onItemClickListener on a Spinner? :) java.lang.RuntimeException: setOnItemClickListener cannot be used with a spinner.
  • 26.
    Comin’ up frombehind... background © Howard Lake, flickr.com/photos/howardlake/5439888760 protected void onCreate(Bundle arg0) { super.onCreate(arg0); new Thread(new Runnable() { public void run() { getFragmentManager() .beginTransaction() .add(android.R.id.content, new SomeFragment()) .commit(); }}).start(); } What happens when running this code? a. exception on beginTransaction as we are not on main thread b. exception on commit as we are not on main thread c. transaction will be done and fragment shown d. transaction will be done but nothing happens
  • 27.
    Comin’ up frombehind... background © Howard Lake, flickr.com/photos/howardlake/5439888760 protected void onCreate(Bundle arg0) { super.onCreate(arg0); new Thread(new Runnable() { public void run() { getFragmentManager() .beginTransaction() .add(android.R.id.content, new SomeFragment()) .commit(); }}).start(); } What happens when running this code? a. exception on beginTransaction as we are not on main thread b. exception on commit as we are not on main thread c. transaction will be done and fragment shown d. transaction will be done but nothing happens
  • 28.
    Comin’ up frombehind... ● “After a FragmentTransaction is committed with FragmentTransaction.commit(), it is scheduled to be executed asynchronously on the process's main thread.” http://developer.android.com/reference/android/app/FragmentManager. html ● use executePendingTransactions to do the transaction immediately but then be sure you are on main thread background © Howard Lake, flickr.com/photos/howardlake/5439888760
  • 29.
    background © HowardLake, flickr.com/photos/howardlake/5439888760 pick me, pick me <item android:drawable="@drawable/ thumbsup" android:state_enabled=" true" android:state_focused=" false" android:state_pressed=" false"/> <item android:drawable="@drawable/ thumbsdown" android:state_pressed=" true"/> <ImageButton … " wrap_content" android:src="@drawable/ mythumbsselector" android:focusable=" true" android:focusableInTouchMode=" true" android:background=" #00000000"/> What do you see: a. “thumbsup” b. “thumbsdown” c. nothing
  • 30.
    background © HowardLake, flickr.com/photos/howardlake/5439888760 pick me, pick me <item android:drawable="@drawable/ thumbsup" android:state_enabled=" true" android:state_focused=" false" android:state_pressed=" false"/> <item android:drawable="@drawable/ thumbsdown" android:state_pressed=" true"/> <ImageButton … " wrap_content" android:src="@drawable/ mythumbsselector" android:focusable=" true" android:focusableInTouchMode=" true" android:background=" #00000000"/> What do you see: a. “thumbsup” b. “thumbsdown” c. nothing
  • 31.
    background © HowardLake, flickr.com/photos/howardlake/5439888760 pick me, pick me <item android:drawable="@drawable/ thumbsup" android:state_enabled=" true" android:state_focused=" false" android:state_pressed=" false"/> <item android:drawable="@drawable/ thumbsdown" android:state_pressed=" true"/> <item android:drawable="@drawable/default" /> Have a default state as last item
  • 32.
    something borrowed, somethingnew protected void onNewIntent(Intent intent) { background © Howard Lake, flickr.com/photos/howardlake/5439888760 trace(intent.getStringExtra("KEY") + ":" + getIntent().getStringExtra("KEY")); super.onNewIntent(intent); trace(intent.getStringExtra("KEY")+ ":"+getIntent().getStringExtra("KEY")); } If this activity is FLAG_ACTIVITY_SINGLE_TOP and we restart it with KEY=value what does it trace? a) “value:null”, “value:value” b) “value:value”, “value:value” c) “value:null”, “value:null”
  • 33.
    something borrowed, somethingnew protected void onNewIntent(Intent intent) { background © Howard Lake, flickr.com/photos/howardlake/5439888760 trace(intent.getStringExtra("KEY") + ":" + getIntent().getStringExtra("KEY")); super.onNewIntent(intent); trace(intent.getStringExtra("KEY")+ ":"+getIntent().getStringExtra("KEY")); } If this activity is FLAG_ACTIVITY_SINGLE_TOP and we restart it with KEY=value what does it trace? a) “value:null”, “value:value” b) “value:value”, “value:value” c) “value:null”, “value:null”
  • 34.
    something borrowed, somethingnew getIntent() always returns you the original intent! Suggested solution on stackoverflow: use setIntent() in onNewIntent() background © Howard Lake, flickr.com/photos/howardlake/5439888760 Let’s try!
  • 35.
    background © HowardLake, flickr.com/photos/howardlake/5439888760 wind of change protected void onResume() { super.onResume(); Intent intent = getIntent(); intent.putExtra("KEY", 1 + intent.getIntExtra("KEY", 0)); setIntent(intent); showToast(valueOf(getIntent(). getIntExtra("KEY", 0)); } What is the Toast message after background and foreground switch? a. 1,2,3… b. 1,1,1... c. 0,0,0... d. sometimes a, sometimes b
  • 36.
    background © HowardLake, flickr.com/photos/howardlake/5439888760 wind of change protected void onResume() { super.onResume(); Intent intent = getIntent(); intent.putExtra("KEY", 1 + intent.getIntExtra("KEY", 0)); setIntent(intent); showToast(valueOf(getIntent(). getIntExtra("KEY", 0)); } What is the Toast message after background and foreground switch? a. 1,2,3… b. 1,1,1... c. 0,0,0... d. sometimes a, sometimes b
  • 37.
    // from androidopen source project: public void setIntent(Intent newIntent) { background © Howard Lake, flickr.com/photos/howardlake/5439888760 wind of change mIntent = newIntent; } ● Depends on if activity get recreated ● When using “don’t keep activities” developer option this will always be: 1,1,1…. Try to avoid setIntent()! Always persist your state!
  • 38.
    background © HowardLake, flickr.com/photos/howardlake/5439888760 Lost in transition <transition xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@android:color/ transparent"/> <item android:drawable="@android:color/ black"/> </transition> <ImageButton ..."wrap_content" android:paddingLeft=" 100dp" android:src="@android:drawable/ btn_star_big_off"/> public void doBackgroudTransition(Imagebutton button){ button.setBackgroundResource(R.drawable.transitionbackground); } What does the Button look like: a) c) b) d)
  • 39.
    background © HowardLake, flickr.com/photos/howardlake/5439888760 Lost in transition <transition xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@android:color/ transparent"/> <item android:drawable="@android:color/ black"/> </transition> <ImageButton ..."wrap_content" android:paddingLeft=" 100dp" android:src="@android:drawable/ btn_star_big_off"/> public void doBackgroudTransition(Imagebutton button){ button.setBackgroundResource(R.drawable.transitionbackground); } What does the Button look like: a) c) b) d)
  • 40.
    background © HowardLake, flickr.com/photos/howardlake/5439888760 Lost in transition <transition xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@android:color/ transparent"/> <item android:drawable="@android:color/ black"/> </transition> <ImageButton ..."wrap_content" android:paddingLeft=" 100dp" android:src="@android:drawable/ btn_star_big_off"/> public void doBackgroudTransition(Imagebutton button){ button.setBackgroundResource(R.drawable.transitionbackground); } What does the Button look like: a) c) b) d)
  • 41.
    Lost in transition ● check your padding when using TransitionDrawable background © Howard Lake, flickr.com/photos/howardlake/5439888760
  • 42.
    background © HowardLake, flickr.com/photos/howardlake/5439888760 wanna be lonely? "singleTask" The system creates the activity at the root of a new task and routes the intent to it. However, if an instance of the activity already exists, the system routes the intent to existing instance through a call to its onNewIntent() method, rather than creating a new one. Let’s try
  • 43.
    background © HowardLake, flickr.com/photos/howardlake/5439888760 wanna be lonely? protected void onResume() { super.onResume(); … startActivityForResult(new Intent(....); trace("started"}; } } protected void onActivityResult(int req, int res, Intent data){ super.onActivityResult(req, res, data); trace("done"}; } What is the log output when we run this activity with android:launchMode="singleTask"? a. nothing, an exception is thrown in startActivityForResult b. “started” and “done” if started returns c. “started” and never “done” ignoring result d. “started” and immediately “done”
  • 44.
    background © HowardLake, flickr.com/photos/howardlake/5439888760 wanna be lonely? protected void onResume() { super.onResume(); … startActivityForResult(new Intent(....); trace("started"}; } } protected void onActivityResult(int req, int res, Intent data){ super.onActivityResult(req, res, data); trace("done"}; } What is the log output when we run this activity with android:launchMode="singleTask"? a. nothing, an exception is thrown in startActivityForResult b. “started” and “done” if started returns c. “started” and never “done” ignoring result d. “started” and immediately “done”
  • 45.
    wanna be lonely? ● in single-task mode you can not use startActivityForResult. Will immediately return with: Activity. RESULT_CANCELED ● “singleTask and singleInstance — are not appropriate for most applications, since they result in an interaction model that is likely to be unfamiliar to users and is very different from most other applications.” http://developer.android.com/guide/topics/manifest/activity-element.html background © Howard Lake, flickr.com/photos/howardlake/5439888760
  • 46.
    ● ...that Android’semail pattern does not see new international addresses like юзер@екзампл.ком as valid? background © Howard Lake, flickr.com/photos/howardlake/5439888760 Did you know? public static final Pattern EMAIL_ADDRESS = Pattern.compile( "[a-zA-Z0-9+._%-+]{1,256}" + "@" + "[a-zA-Z0-9][a-zA-Z0-9-]{0,64}" + "(" + "." + "[a-zA-Z0-9][a-zA-Z0-9-]{0,25}" + ")+" );
  • 47.
    to all thepeople in the world background © Howard Lake, flickr.com/photos/howardlake/5439888760 new Thread( new Runnable() { public void run() { LocalBroadcastManager.getInstance( getApplicationContext()) .sendBroadcast(new Intent(ACTION));} }).start(); public void onReceive(Context context, Intent intent) { ((ArrayAdapter) getListAdapter()). notifyDataSetChanged(); } What happens: a. error in run() because of applicationcontext b. error in run() because not in MainThread c. error in onReceive() - notifyDatasetChanged needs MainThread d. no error, everything is fine, kkthxbye
  • 48.
    to all thepeople in the world background © Howard Lake, flickr.com/photos/howardlake/5439888760 new Thread( new Runnable() { public void run() { LocalBroadcastManager.getInstance( getApplicationContext()) .sendBroadcast(new Intent(ACTION));} }).start(); public void onReceive(Context context, Intent intent) { ((ArrayAdapter) getListAdapter()). notifyDataSetChanged(); } What happens: a. error in run() because of applicationcontext b. error in run() because not in MainThread c. error in onReceive() - notifyDatasetChanged needs MainThread d. no error, everything is fine, kkthxbye
  • 49.
    to all thepeople in the world 2 static final String[] data = new String[]{"A","B","C"}; private void sendBroadcast(){ Intent intent = new Intent();intent.setAction(ACTION); intent.putExtra("EXTRA",data ); LocalBroadcastManager.getInstance(getActivity()).sendBroadcast(intent); data[0] = "D";} public void onReceive(Context context, Intent intent) { String[] mydata = intent.getStringArrayExtra("EXTRA"); mydata[2] = "F"; background © Howard Lake, flickr.com/photos/howardlake/5439888760 } What is the content of data after onReceive: a. [A, B, C] b. [D, B, C] c. [D, B, F] d. Exception: ConcurrentModificationException e. Compiler Error: data is final and cannot be changed
  • 50.
    to all thepeople in the world 2 static final String[] data = new String[]{"A","B","C"}; private void sendBroadcast(){ Intent intent = new Intent();intent.setAction(ACTION); intent.putExtra("EXTRA",data ); LocalBroadcastManager.getInstance(getActivity()).sendBroadcast(intent); data[0] = "D";} public void onReceive(Context context, Intent intent) { String[] mydata = intent.getStringArrayExtra("EXTRA"); mydata[2] = "F"; background © Howard Lake, flickr.com/photos/howardlake/5439888760 } What is the content of data after onReceive: a. [A, B, C] b. [D, B, C] c. [D, B, F] d. Exception: ConcurrentModificationException e. Compiler Error: data is final and cannot be changed
  • 51.
    to all thepeople in the world 2 ● With LocalBroadcastManager you get the original Object reference, no serialisation ● this is not the case for Context#sendBroadcast (Intent i) background © Howard Lake, flickr.com/photos/howardlake/5439888760
  • 52.
    ● plus.google.com/+DannyPreussler, Thanks background © Howard Lake, flickr.com/photos/howardlake/5439888760 github.com/dpreussler ● plus.google.com/+JohannesOrgis github.com/joorg ● Check Wunderlist & Groupon Engineering blogs ● Please Download: enviQ ESA satellite based Air Quality check app