Murach's Android Programming

Murach's Android Programming

This book teaches anyone with a basic understanding of Java how to develop Android apps at a professional level.
To start, it shows how to use the Eclipse IDE to code, test, and debug a Tip Calculator app for a smartphone or tablet. Then, it expands upon this app to show must-have Android skills such as working with layouts, widgets, events, themes, styles, menus, preferences, and fragments. Next, this book presents two more apps that illustrate Android skills you'll use every day, such as working with threads, files, adapters, intents, services, notifications, broadcast receivers, SQLite databases, content providers, and app widgets. Finally, this book presents an app that uses the Google Maps API and shows you how to submit your finished apps to the Google Play store.
The real-world apps let you see how the skills you're learning work together, and they illustrate how and when you'd use each skill. And all the content is presented in Murach distinctive "paired-pages" style that developers find so clear and time-saving for both training and reference.

Windows firewall block Remote Desktop connection - solved

As posted in "Basic setup for Microsoft Remote Desktop and Remote Desktop Client for Android". I can connect Remote Desktop Client on Android to my Windows 8.1 Pro with basic setup. But it fail to connect recently!


It's found that Windows firewall block the remote desktop connection. To fix it:

- Search setting of "firewall" in windows Search, select "Allow an app through Windows Firewall".

- It can be noticed that Public of Remote Desktop app is unchecked.

- To enable Remote Desktop for public, click on the "Change Settings" button, and click to check it. Then OK.

- Remote Desktop Client app on Android work now.

VelocityTracker and VelocityTrackerCompat

The post "VelocityTracker, track the velocity of touch events" for one touch point tracking using VelocityTracker. Together with android.support.v4.view.VelocityTrackerCompat (Helper for accessing features in VelocityTracker introduced after API level 4 in a backwards compatible fashion), we can track velocity for multi-touch tracking on post-HONEYCOMB device.



package com.example.androidvelocitytracker;

import android.os.Build;
import android.os.Bundle;
import android.os.Build.VERSION_CODES;
import android.support.v4.view.VelocityTrackerCompat;
import android.util.SparseArray;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.widget.TextView;
import android.app.Activity;

public class MainActivity extends Activity {

TextView textAvtion, textVelocityX0, textVelocityY0,
textVelocityX1, textVelocityY1;
TextView textVersion;
VelocityTracker velocityTracker = null;

static SparseArray<String> arrayVC = new SparseArray<String>();
static {
arrayVC.append(VERSION_CODES.BASE, "The original, first, version of Android.");
arrayVC.append(VERSION_CODES.BASE_1_1, "First Android update, officially called 1.1");
arrayVC.append(VERSION_CODES.CUPCAKE, "Android 1.5");
arrayVC.append(VERSION_CODES.CUR_DEVELOPMENT, "Magic version number...");
arrayVC.append(VERSION_CODES.DONUT, "Android 1.6");
arrayVC.append(VERSION_CODES.ECLAIR, "Android 2.0");
arrayVC.append(VERSION_CODES.ECLAIR_0_1, "Android 2.0.1");
arrayVC.append(VERSION_CODES.ECLAIR_MR1, "Android 2.1");
arrayVC.append(VERSION_CODES.FROYO, "Android 2.2");
arrayVC.append(VERSION_CODES.GINGERBREAD,"Android 2.3");
arrayVC.append(VERSION_CODES.GINGERBREAD_MR1, "Android 2.3.3");
arrayVC.append(VERSION_CODES.HONEYCOMB, "Android 3.0");
arrayVC.append(VERSION_CODES.HONEYCOMB_MR1, "Android 3.1");
arrayVC.append(VERSION_CODES.HONEYCOMB_MR2, "Android 3.2");
arrayVC.append(VERSION_CODES.ICE_CREAM_SANDWICH,"Android 4.0");
arrayVC.append(VERSION_CODES.ICE_CREAM_SANDWICH_MR1,"Android 4.0.3");
arrayVC.append(VERSION_CODES.JELLY_BEAN, "Android 4.1");
arrayVC.append(VERSION_CODES.JELLY_BEAN_MR1, "Android 4.2");
arrayVC.append(VERSION_CODES.JELLY_BEAN_MR2, "Android 4.3");
arrayVC.append(VERSION_CODES.KITKAT, "Android 4.4");
}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textAvtion = (TextView) findViewById(R.id.action);
textVelocityX0 = (TextView) findViewById(R.id.velocityx0);
textVelocityY0 = (TextView) findViewById(R.id.velocityy0);
textVelocityX1 = (TextView) findViewById(R.id.velocityx1);
textVelocityY1 = (TextView) findViewById(R.id.velocityy1);

textVersion = (TextView)findViewById(R.id.version);
int version = Build.VERSION.SDK_INT;
String BuildVersion = arrayVC.get(version, "unknown");
textVersion.setText(BuildVersion);
}

@Override
public boolean onTouchEvent(MotionEvent event) {

int action = event.getActionMasked();
int index = event.getActionIndex();
int pointerId = event.getPointerId(index);

switch (action) {
case MotionEvent.ACTION_DOWN:
if (velocityTracker == null) {
velocityTracker = VelocityTracker.obtain();
} else {
velocityTracker.clear();
}
velocityTracker.addMovement(event);

if(pointerId == 0){
textVelocityX0.setText("X-velocity (pixel/s): 0");
textVelocityY0.setText("Y-velocity (pixel/s): 0");
}else if(pointerId == 1){
textVelocityX1.setText("X-velocity (pixel/s): 0");
textVelocityY1.setText("Y-velocity (pixel/s): 0");
}

break;
case MotionEvent.ACTION_MOVE:
velocityTracker.addMovement(event);
velocityTracker.computeCurrentVelocity(1000);
//1000 provides pixels per second

float xVelocity = VelocityTrackerCompat.getXVelocity(
velocityTracker, pointerId);

float yVelocity = VelocityTrackerCompat.getYVelocity(
velocityTracker, pointerId);

if(pointerId == 0){
textVelocityX0.setText("X-velocity (pixel/s): " + xVelocity);
textVelocityY0.setText("Y-velocity (pixel/s): " + yVelocity);
}else if(pointerId == 1){
textVelocityX1.setText("X-velocity (pixel/s): " + xVelocity);
textVelocityY1.setText("Y-velocity (pixel/s): " + yVelocity);
}

break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
velocityTracker.recycle();
break;
}

return true;
}

}

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:autoLink="web"
android:text="http://arteluzevida.blogspot.com/"
android:textStyle="bold" />

<TextView
android:id="@+id/version"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

<TextView
android:id="@+id/action"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

<TextView
android:text="pointer 0"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/velocityx0"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/velocityy0"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:text="pointer 1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/velocityx1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/velocityy1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

</LinearLayout>



download filesDownload the files.

Get the Android version of device

The static final int Build.VERSION.SDK_INT store user-visible SDK version of the framework; its possible values are defined in Build.VERSION_CODES.

This exercise use Android's SparseArrays to store SDK_INT-Build.VERSION_CODES pairs. SparseArrays map integers to Objects. Unlike a normal array of Objects, there can be gaps in the indices. It is intended to be more memory efficient than using a HashMap to map Integers to Objects, both because it avoids auto-boxing keys and its data structure doesn't rely on an extra entry object for each mapping.


Get the Android version of device
Get the Android version of device

package com.example.androidversion;

import android.os.Build;
import android.os.Build.VERSION_CODES;
import android.os.Bundle;
import android.util.SparseArray;
import android.widget.TextView;
import android.app.Activity;

public class MainActivity extends Activity {

static SparseArray<String> arrayVC = new SparseArray<String>();
static {
arrayVC.append(VERSION_CODES.BASE, "The original, first, version of Android.");
arrayVC.append(VERSION_CODES.BASE_1_1, "First Android update, officially called 1.1");
arrayVC.append(VERSION_CODES.CUPCAKE, "Android 1.5");
arrayVC.append(VERSION_CODES.CUR_DEVELOPMENT, "Magic version number...");
arrayVC.append(VERSION_CODES.DONUT, "Android 1.6");
arrayVC.append(VERSION_CODES.ECLAIR, "Android 2.0");
arrayVC.append(VERSION_CODES.ECLAIR_0_1, "Android 2.0.1");
arrayVC.append(VERSION_CODES.ECLAIR_MR1, "Android 2.1");
arrayVC.append(VERSION_CODES.FROYO, "Android 2.2");
arrayVC.append(VERSION_CODES.GINGERBREAD,"Android 2.3");
arrayVC.append(VERSION_CODES.GINGERBREAD_MR1, "Android 2.3.3");
arrayVC.append(VERSION_CODES.HONEYCOMB, "Android 3.0");
arrayVC.append(VERSION_CODES.HONEYCOMB_MR1, "Android 3.1");
arrayVC.append(VERSION_CODES.HONEYCOMB_MR2, "Android 3.2");
arrayVC.append(VERSION_CODES.ICE_CREAM_SANDWICH,"Android 4.0");
arrayVC.append(VERSION_CODES.ICE_CREAM_SANDWICH_MR1,"Android 4.0.3");
arrayVC.append(VERSION_CODES.JELLY_BEAN, "Android 4.1");
arrayVC.append(VERSION_CODES.JELLY_BEAN_MR1, "Android 4.2");
arrayVC.append(VERSION_CODES.JELLY_BEAN_MR2, "Android 4.3");
arrayVC.append(VERSION_CODES.KITKAT, "Android 4.4");
}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main);

TextView textView = new TextView(this);
setContentView(textView);

int version = Build.VERSION.SDK_INT;
String BuildVersion = arrayVC.get(version, "unknown");

textView.setText(BuildVersion);
}

}


VelocityTracker, track the velocity of touch events

It's a example of using Android's VelocityTracker. It's a helper for tracking the velocity of touch events, for implementing flinging and other such gestures. Use obtain() to retrieve a new instance of the class when you are going to begin tracking. Put the motion events you receive into it with addMovement(MotionEvent). When you want to determine the velocity call computeCurrentVelocity(int) and then call getXVelocity(int) and getYVelocity(int) to retrieve the velocity for each pointer id.


VelocityTracker
Example of using Android's VelocityTracker

package com.example.androidvelocitytracker;

import android.os.Bundle;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.widget.TextView;
import android.app.Activity;

public class MainActivity extends Activity {

TextView textAvtion, textVelocityX, textVelocityY,
textMaxVelocityX, textMaxVelocityY;
VelocityTracker velocityTracker = null;

float maxXVelocity;
float maxYVelocity;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textAvtion = (TextView) findViewById(R.id.action);
textVelocityX = (TextView) findViewById(R.id.velocityx);
textVelocityY = (TextView) findViewById(R.id.velocityy);
textMaxVelocityX = (TextView) findViewById(R.id.maxvelocityx);
textMaxVelocityY = (TextView) findViewById(R.id.maxvelocityy);
}

@Override
public boolean onTouchEvent(MotionEvent event) {

int action = event.getActionMasked();

switch (action) {
case MotionEvent.ACTION_DOWN:
if (velocityTracker == null) {
velocityTracker = VelocityTracker.obtain();
} else {
velocityTracker.clear();
}
velocityTracker.addMovement(event);
maxXVelocity = 0;
maxYVelocity = 0;

textVelocityX.setText("X-velocity (pixel/s): 0");
textVelocityY.setText("Y-velocity (pixel/s): 0");
textMaxVelocityX.setText("max. X-velocity: 0");
textMaxVelocityY.setText("max. Y-velocity: 0");

break;
case MotionEvent.ACTION_MOVE:
velocityTracker.addMovement(event);
velocityTracker.computeCurrentVelocity(1000);
//1000 provides pixels per second

float xVelocity = velocityTracker.getXVelocity();
float yVelocity = velocityTracker.getYVelocity();

if(xVelocity > maxXVelocity){
//max in right side
maxXVelocity = xVelocity;
}

if(yVelocity > maxYVelocity){
//Max in down side
maxYVelocity = yVelocity;
}

textVelocityX.setText("X-velocity (pixel/s): " + xVelocity);
textVelocityY.setText("Y-velocity (pixel/s): " + yVelocity);
textMaxVelocityX.setText("max. X-velocity: " + maxXVelocity);
textMaxVelocityY.setText("max. Y-velocity: " + maxYVelocity);

break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
velocityTracker.recycle();
break;
}

return true;
}

}

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:autoLink="web"
android:text="http://arteluzevida.blogspot.com/"
android:textStyle="bold" />

<TextView
android:id="@+id/action"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

<TextView
android:id="@+id/velocityx"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/maxvelocityx"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

<TextView
android:id="@+id/velocityy"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/maxvelocityy"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

</LinearLayout>



Next: VelocityTracker and VelocityTrackerCompat to track velocity for multi-touch case.

Android Security Cookbook

Android Security Cookbook
Practical recipes to delve into Android's security mechanisms by troubleshooting common vulnerabilities in applications and Android OS versions
Overview
  • Analyze the security of Android applications and devices, and exploit common vulnerabilities in applications and Android operating systems
  • Develop custom vulnerability assessment tools using the Drozer Android Security Assessment Framework
  • Reverse-engineer Android applications for security vulnerabilities
  • Protect your Android application with up to date hardening techniques
In Detail
Android Security Cookbook discusses many common vulnerabilities and security related shortcomings in Android applications and operating systems. The book breaks down and enumerates the processes used to exploit and remediate these vulnerabilities in the form of detailed recipes and walkthroughs.
The book also teaches readers to use an Android Security Assessment Framework called Drozer and how to develop plugins to customize the framework.
Other topics covered include how to reverse-engineer Android applications to find common vulnerabilities, and how to find common memory corruption vulnerabilities on ARM devices. In terms of application protection this book will show various hardening techniques to protect application components, the data stored, secure networking. In summary, Android Security Cookbook provides a practical analysis into many areas of Android application and operating system security and gives the
What you will learn from this book
  • Set up the Android development tools and frameworks
  • Engage in Application security concepts
  • Use the Drozer Android Security Assessment Framework
  • Customize and develop your own plugins for the Drozer Framework
  • Exploit, enumerate, and analyze common application level exploits
  • Protect applications from common vulnerabilities and exploits
  • Reverse-engineer applications for common code level vulnerabilities
  • Secure application networking, SSL/TLS
  • Encryption to protect application data
Approach
"Android Security Cookbook' breaks down and enumerates the processes used to exploit and remediate Android app security vulnerabilities in the form of detailed recipes and walkthroughs.
Who this book is written for
"Android Security Cookbook" is aimed at anyone who is curious about Android app security and wants to be able to take the necessary practical measures to protect themselves; this means that Android application developers, security researchers and analysts, penetration testers, and generally any CIO, CTO, or IT managers facing the impeding onslaught of mobile devices in the business environment will benefit from reading this book.


Creating Dynamic UI with Android Fragments

Creating Dynamic UI with Android Fragments
Leverage the power of Android fragments to develop dynamic user interfaces for your apps
Overview
  • Learn everything you need to know to provide dynamic multi-screen UIs within a single activity
  • Integrate the rich UI features demanded by today’s mobile users
  • Understand the basics of using fragments and how to use them to create more adaptive and dynamic user experiences
In Detail
To create a dynamic and multi-pane user interface on Android, you need to encapsulate UI components and activity behaviors into modules that you can swap into and out of your activities. You can create these modules with the fragment class, which behaves somewhat like a nested activity that can define its own layout and manage its own lifecycle. When a fragment specifies its own layout, it can be configured in different combinations with other fragments inside an activity to modify your layout configuration for different screen sizes (a small screen might show one fragment at a time, but a large screen can show two or more).
Creating Dynamic UI with Android Fragments shows you how to create modern Android applications that meet the high expectations of today’s users. You will learn how to incorporate rich navigation features like swipe-based screen browsing and how to create adaptive UIs that ensure your application looks fantastic whether run on a low cost smartphone or the latest tablet.
This book looks at the impact fragments have on Android UI design and their role in both simplifying many common UI challenges and providing new ways to incorporate rich UI behaviors.
You will learn how to use fragments to create UIs that automatically adapt to device differences. We look closely at the roll of fragment transactions and how to work with the Android back stack. Leveraging this understanding, we then explore several specialized fragment-related classes like ListFragment and DialogFragment as well as rich navigation features like swipe-based screen browsing.
What you will learn from this book
  • Understand the role and capabilities of fragments
  • Explore the fragment-oriented features of Android Studio
  • Create an app UI that works effectively on smartphones and tablets
  • Use fragments to create engaging navigation capabilities like swipe-based screen browsing
  • Work with special purpose fragment classes like ListFragment and DialogFragment
  • Dynamically manage fragments using the FragmentTransaction class
  • Learn appropriate application design for communicating between fragments
  • Efficiently handle fragment creation and lifecycle
  • Simplify cross-thread UI handling with fragments
  • Form multi-screen UIs that run within a single activity
Approach
A fast-paced tutorial that guides you through everything you need to know about dynamic UI design for Android devices.
Who this book is written for
This book is for developers with a basic understanding of Android programming who would like to improve the appearance and usability of their applications. Whether you’re looking to create a more interactive user experience, create more dynamically adaptive UIs, provide better support for tablets and smartphones in a single app, reduce the complexity of managing your app UIs, or you are just trying to expand your UI design philosophy, then this book is for you.

The Beautiful Design Winter 2013 Collection on Google Play

Posted by Marco Paglia, Android Design Team


While beauty’s in the eye of the beholder, designing apps for a platform also requires an attention to platform norms to ensure a great user experience. The Android Design site is an excellent resource for designers and developers alike to get familiar with Android’s visual, interaction, and written language. Many developers have taken advantage of the tools and techniques provided on the site, and every now and then we like to showcase a few notable apps that go above and beyond the guidelines.


This summer, we published the first Beautiful Design collection on Google Play. Today, we're refreshing the collection with a new set of apps just in time for the holiday season.


As a reminder, the goal of this collection is to highlight beautiful apps with masterfully crafted design details such as beautiful presentation of photos, crisp and meaningful layout and typography, and delightful yet intuitive gestures and transitions.


The newly updated Beautiful Design Winter 2013 collection includes:




Timely (by Bitspin), a clock app that takes animation to a whole new level. Screen transitions are liquid smooth and using the app feels more like playing with real objects than fussing around with knobs and buttons. If you’ve ever wondered if setting an alarm could be fun, Timely unequivocally answers “yes”.




Circa, a news reader that’s fast, elegant and full of beautiful design details throughout. Sophisticated typography and banner image effects, coupled with an innovative and "snappy" interaction, makes reading an article feel fast and very, very fun.




Etsy, an app that helps you explore a world of wonderful hand-crafted goods with thoughtfully designed screen transitions, beautifully arranged layouts, and subtle flourishes like a blur effect that lets you focus on the task at hand. This wonderfully detailed app is an absolute joy to use.



Airbnb, The Whole Pantry, Runtastic Heart Rate Pro, Tumblr, Umano, Yahoo! Weather… each with delightful design details.






Grand St. and Pinterest, veterans of the collection from this summer.



If you’re an Android developer, make sure to play with some of these apps to get a sense for the types of design details that can separate good apps from great ones. And remember to review the Android Design guidelines and the Android Design in Action video series for more ideas on how to design your next beautiful Android app.




Learning Mobile App Development: A Hands-on Guide to Building Apps with iOS and Android

Learning Mobile App Development: A Hands-on Guide to Building Apps with iOS and Android
- The Only Tutorial Covering BOTH iOS and Android—for students and professionals alike!



Now, one book can help you master mobile app development with both market-leading platforms: Apple’s iOS and Google’s Android. Perfect for both students and professionals, Learning Mobile App Development is the only tutorial with complete parallel coverage of both iOS and Android. With this guide, you can master either platform, or both—and gain a deeper understanding of the issues associated with developing mobile apps.

You’ll develop an actual working app on both iOS and Android, mastering the entire mobile app development lifecycle, from planning through licensing and distribution.
Each tutorial in this book has been carefully designed to support readers with widely varying backgrounds and has been extensively tested in live developer training courses. If you’re new to iOS, you’ll also find an easy, practical introduction to Objective-C, Apple’s native language.

All source code for this book, organized by chapter, is available at https://github.com/LearningMobile/BookApps

Coverage includes
  • Understanding the unique design challenges associated with mobile apps
  • Setting up your Android and iOS development environments
  • Mastering Eclipse development tools for Android and Xcode 5 tools for iOS
  • Designing interfaces and navigation schemes that leverage each platform’s power
  • Reliably integrating persistent data into your apps
  • Using lists (Android) or tables (iOS) to effectively present data to users
  • Capturing device location, displaying it, and using it in your apps
  • Accessing hardware devices and sensors
  • Publishing custom apps internally within an organization
  • Monetizing your apps on Apple’s AppStore or the Google Play marketplace, as well as other ways of profiting from app development, such as consulting and developer jobs

Implement Socket on Android to communicate with Raspberry Pi

There is a post "Java exercise - Implement client and server to communicate using Socket" in my another blog, Hello Raspberry Pi. In which, both host (implement ServerSocket and Socket) and client (implement Socket) are run on Raspberry Pi to setup communication between application via socket. Actually both the host and client can run on any PC with Java.

The client side in the post is ported to Android in this exercise, setup Socket in AsyncTask, to communicate with Raspberry Pi. The updated version of Host (run socket operation in background thread) run on Raspberry Pi or any other PC is here.

Implement Socket on Android to communicate with Raspberry Pi
Implement Socket on Android
MainActivity.java
package com.example.androidclient;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.net.UnknownHostException;

import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends Activity {

TextView textResponse;
EditText editTextAddress, editTextPort;
Button buttonConnect, buttonClear;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

editTextAddress = (EditText)findViewById(R.id.address);
editTextPort = (EditText)findViewById(R.id.port);
buttonConnect = (Button)findViewById(R.id.connect);
buttonClear = (Button)findViewById(R.id.clear);
textResponse = (TextView)findViewById(R.id.response);

buttonConnect.setOnClickListener(buttonConnectOnClickListener);

buttonClear.setOnClickListener(new OnClickListener(){

@Override
public void onClick(View v) {
textResponse.setText("");
}});
}

OnClickListener buttonConnectOnClickListener =
new OnClickListener(){

@Override
public void onClick(View arg0) {
/*
* You have to verify editTextAddress and
* editTextPort are input as correct format.
*/

MyClientTask myClientTask = new MyClientTask(
editTextAddress.getText().toString(),
Integer.parseInt(editTextPort.getText().toString()));
myClientTask.execute();
}};

public class MyClientTask extends AsyncTask<Void, Void, Void> {

String dstAddress;
int dstPort;
String response;

MyClientTask(String addr, int port){
dstAddress = addr;
dstPort = port;
}

@Override
protected Void doInBackground(Void... arg0) {

try {
Socket socket = new Socket(dstAddress, dstPort);
InputStream inputStream = socket.getInputStream();
ByteArrayOutputStream byteArrayOutputStream =
new ByteArrayOutputStream(1024);
byte[] buffer = new byte[1024];

int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1){
byteArrayOutputStream.write(buffer, 0, bytesRead);
}

socket.close();
response = byteArrayOutputStream.toString("UTF-8");

} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}

@Override
protected void onPostExecute(Void result) {
textResponse.setText(response);
super.onPostExecute(result);
}

}

}


Layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context=".MainActivity" >

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:autoLink="web"
android:text="http://arteluzevida.blogspot.com/"
android:textStyle="bold" />
<EditText
android:id="@+id/address"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="dstAddress" />
<EditText
android:id="@+id/port"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="dstPort" />
<Button
android:id="@+id/connect"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Connect..."/>
<Button
android:id="@+id/clear"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Clear"/>
<TextView
android:id="@+id/response"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>

</LinearLayout>


AndroidManifest.xml have to be modified to add <uses-permission android:name="android.permission.INTERNET"/>



download filesDownload the files.

or Download and install the APK file.



Cross-post with Hello Raspberry Pi

Install the new Google Mobile Ads SDK for Android

Google have made some big changes recently to the SDK for Android; it's now included as part of Google Play services 4.0.

If you're an Android developer you'll be familiar with Google Play services, a unified platform which makes it easy to integrate Google features into your Android apps, delivered through the Play Store and updated at regular intervals. Now that AdMob is part of the package, a key benefit is that changes to the Google Mobile Ads SDK for Android get pushed seamlessly to users through Google Play services. For most SDK updates you don’t need to update your apps each time it changes, saving you development time. Follow these instructions to install the SDK. 

ActionBarCompat with ShareActionProvider to update dynamic content

Last exercise "ActionBarCompat with ShareActionProvider" setup share content in onCreateOptionsMenu(). The share data will not be updated after then. In this exercise, ShareIntent will be updated when user update content.

In my experiment, onOptionsItemSelected() will not be called when Share menu item clicked. So a TextWatcher is implemented when any EditText changed, to update ShareIntent.

ActionBarCompat with ShareActionProvider to update dynamic content
ActionBarCompat with ShareActionProvider to update dynamic content
Modify layout to add EditTexts for user to enter email address, title and content.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context=".MainActivity" >

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:autoLink="web"
android:text="http://arteluzevida.blogspot.com/"
android:textStyle="bold" />

<EditText
android:id="@+id/fieldemailaddress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textEmailAddress"
android:hint="email address" />
<EditText
android:id="@+id/fieldemailtitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Hello from android-er.blogspot.com"
android:hint="email title"/>
<EditText
android:id="@+id/fieldemailcontent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="email content"/>

</LinearLayout>

/res/menu/main.xml, same as before.
<menu 
xmlns:myapp="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android" >

<item
android:id="@+id/action_share"
android:title="Share"
myapp:actionProviderClass="android.support.v7.widget.ShareActionProvider"
myapp:showAsAction="always|withText" />
<item
android:id="@+id/action_settings"
myapp:showAsAction="always|withText"
android:title="@string/action_settings"/>

</menu>

MainActivity.java
package com.example.testactionbarcompat;

import android.content.Intent;
import android.os.Bundle;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.ShareActionProvider;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends ActionBarActivity {

EditText fieldEmailAddress, fieldEmailTitle, fieldEmailContent;

private ShareActionProvider myShareActionProvider;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);
fieldEmailAddress = (EditText)findViewById(R.id.fieldemailaddress);
fieldEmailTitle = (EditText)findViewById(R.id.fieldemailtitle);
fieldEmailContent = (EditText)findViewById(R.id.fieldemailcontent);

fieldEmailAddress.addTextChangedListener(myTextWatcher);
fieldEmailTitle.addTextChangedListener(myTextWatcher);
fieldEmailContent.addTextChangedListener(myTextWatcher);
}

/*
* update ActionProvider by calling setShareIntent()
* When any EditText changed
*/
TextWatcher myTextWatcher = new TextWatcher(){

@Override
public void afterTextChanged(Editable s) {
setShareIntent();
}

@Override
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {}

@Override
public void onTextChanged(CharSequence s, int start,
int before, int count) {}
};

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);

//add MenuItem(s) to ActionBar using Java code
MenuItem menuItem_Info = menu.add(0, R.id.menuid_info, 0, "Info");
menuItem_Info.setIcon(android.R.drawable.ic_menu_info_details);
MenuItemCompat.setShowAsAction(menuItem_Info,
MenuItem.SHOW_AS_ACTION_ALWAYS|MenuItem.SHOW_AS_ACTION_WITH_TEXT);

//Handle share menu item
MenuItem shareItem = menu.findItem(R.id.action_share);
myShareActionProvider = (ShareActionProvider)
MenuItemCompat.getActionProvider(shareItem);
setShareIntent();

//return true;
return super.onCreateOptionsMenu(menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
// TODO Auto-generated method stub
//return super.onOptionsItemSelected(item);
switch (item.getItemId()) {
case R.id.action_share:
//It never called in my experiment
Toast.makeText(this, "Share", Toast.LENGTH_SHORT).show();
setShareIntent();
return false;
case R.id.action_settings:
//match with /res/menu/main.xml
Toast.makeText(this, "Setting", Toast.LENGTH_SHORT).show();
return true;
case R.id.menuid_info:
//match with defined in onCreateOptionsMenu()
Toast.makeText(this, "Info", Toast.LENGTH_SHORT).show();
return true;
default:
return super.onOptionsItemSelected(item);
}
}

//Set the share intent
private void setShareIntent(){

Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("plain/text");
intent.putExtra(Intent.EXTRA_EMAIL,
new String[]{fieldEmailAddress.getText().toString()});
intent.putExtra(Intent.EXTRA_SUBJECT,
fieldEmailTitle.getText().toString());
intent.putExtra(Intent.EXTRA_TEXT,
fieldEmailContent.getText().toString());

myShareActionProvider.setShareIntent(intent);
}

}


download filesDownload the files.



Visit: ActionBarCompat Step-by-step

ActionBarCompat with ShareActionProvider

This exercise implement MenuItem of Share action in ActionBarCompat, and ShareActionProvider to share text if user click on the Share on the Share item. Base on last exercise "Handle onOptionsItemSelected() for ActionBarCompat".

ActionBarCompat with Share ShareActionProvider
ActionBarCompat with Share ShareActionProvider

Modify /res/menu/main.xml to add new item of action_share.
<menu 
xmlns:myapp="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android" >

<item
android:id="@+id/action_share"
android:title="Share"
myapp:actionProviderClass="android.support.v7.widget.ShareActionProvider"
myapp:showAsAction="always|withText" />
<item
android:id="@+id/action_settings"
myapp:showAsAction="always|withText"
android:title="@string/action_settings"/>

</menu>

MainActivity.java.
package com.example.testactionbarcompat;

import android.content.Intent;
import android.os.Bundle;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.ShareActionProvider;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;

public class MainActivity extends ActionBarActivity {

private ShareActionProvider myShareActionProvider;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);
}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);

//add MenuItem(s) to ActionBar using Java code
MenuItem menuItem_Info = menu.add(0, R.id.menuid_info, 0, "Info");
menuItem_Info.setIcon(android.R.drawable.ic_menu_info_details);
MenuItemCompat.setShowAsAction(menuItem_Info,
MenuItem.SHOW_AS_ACTION_ALWAYS|MenuItem.SHOW_AS_ACTION_WITH_TEXT);

//Handle share menu item
MenuItem shareItem = menu.findItem(R.id.action_share);
myShareActionProvider = (ShareActionProvider)
MenuItemCompat.getActionProvider(shareItem);
setShareIntent();

return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
// TODO Auto-generated method stub
//return super.onOptionsItemSelected(item);
switch (item.getItemId()) {
case R.id.action_settings:
//match with /res/menu/main.xml
Toast.makeText(this, "Setting", Toast.LENGTH_SHORT).show();
return true;
case R.id.menuid_info:
//match with defined in onCreateOptionsMenu()
Toast.makeText(this, "Info", Toast.LENGTH_SHORT).show();
return true;
default:
return super.onOptionsItemSelected(item);
}
}

//Set the share intent
private void setShareIntent(){

Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("plain/text");
intent.putExtra(Intent.EXTRA_TEXT, "Hello from android-er.blogspot.com");

myShareActionProvider.setShareIntent(intent);
}

}


download filesDownload the files.

Next:
ActionBarCompat with ShareActionProvider to update dynamic content


Visit: ActionBarCompat Step-by-step

Pro Android Graphics

Pro Android Graphics is a comprehensive goldmine of knowledge and techniques that will help you design, create, and optimize 2D graphics for use in your Android Jelly Bean applications. Android application developer and expert multimedia producer Wallace Jackson of Mind Taffy Design shows you how to leverage Android's powerful graphics APIs in conjunction with professional open source graphics design tools such as GIMP 2.8.6 and more.

You’ll learn about:
  • The foundational graphics concepts behind the three core new media areas (digital imaging, digital video, and 2D animation) which relate to graphics design, and how to optimize these new media assets for your Android applications across iTVs, tablets, eReaders, game consoles, and smartphones.
  • Digital imaging techniques for Android apps design, including graphics design layouts and graphical user interface elements, and how to use image compositing techniques to take your digital imaging to far higher levels.
  • Advanced image compositing and blending techniques, using Android’s PorterDuff, NinePatch, and LayerDrawable classes.
  • Advanced 2D animation techniques, using Android’s Animation and AnimationDrawable classes.
  • Digital video optimization, playback, and streaming, using open source 3D (Terragen 3) and video (VirtualDub) applications, as well as professional video editing applications such as Squeeze Pro 9. You’ll use these software packages with Android’s VideoView and MediaPlayer classes, and add compositing to enhance your end-users’ digital video experience.

What you’ll learn

  • How to build graphics rich Android apps and games
  • What are the key Android Graphics support APIs: Images, Animation and Video Concepts
  • What are the digital imaging techniques for Android apps
  • What are the advanced animation techniques for Android apps
  • How to do digital video optimization for Android apps

Who this book is for

Pro Android Graphics is written for experienced Android developers and advanced multimedia artisans, especially those who want to create rich, vibrant-looking graphics-related applications.

Table of Contents

  1. Android Digital Imaging: Formats, Concepts, and Optimization
  2. Android Digital Video: Formats, Concepts, and Optimization
  3. Android Frame Animation: XML, Concepts, and Optimization
  4. Android Procedural Animation: XML, Concepts, and Optimization
  5. Android DIP: Device-Independent Pixel Graphics Design
  6. Android UI Layouts: Graphics Design Using the ViewGroup Class
  7. Android UI Widgets: Graphics Design using the View Class
  8. Advanced ImageView: More Graphics Design Using ImageView
  9. Advanced ImageButton: Creating a Custom Multi-State ImageButton
  10. Using 9-Patch Imaging Techniques to Create Scalable Imaging Elements
  11. Advanced Image Blending: Using Android PorterDuff Classes
  12. Advanced Image Compositing: Using the LayerDrawable Class
  13. Digital Image Transitions: Using the TransitionDrawable Class
  14. Frame-Based Animation: Using the AnimationDrawable Class
  15. Procedural Animation: Using the Animation Classes
  16. Advanced Graphics: Mastering the Drawable Class
  17. Interactive Drawing: Using Paint and Canvas Classes Interactively
  18. Playing Captive Video Using the VideoView and MediaPlayer Classes
  19. Streaming Digital Video from an External Media Server


Pro iOS and Android Apps for Business: with jQuery Mobile, node.js, and MongoDB

With Pro iOS and Android Apps for Business, you can take your web development experience and apply it toward creating a full-featured business app, from soup to nuts.  Frank Zammetti shows you how to create a client app using jQuery Mobile wrapped in PhoneGap, and how to create a node.js-based server that uses MongoDB as its data store.

You never have to deal with learning Objective-C, Java or any other difficult-to-learn language.  Instead, you can build on your existing HTML5, JavaScript and CSS experience to quickly and effectively build any app your business needs.  You can apply this knowledge to iOS and Android apps as well as other mobile platforms since the technologies used support most modern mobile platforms as well.

You'll learn:
  • How to design a full-featured app, including requirements like offline access
  • How to build the client-side of the app using jQuery Mobile, including adding stub code for calling the node.js server
  • How to create a simple server with node.js and interact with it using REST
  • How to use MongoDB with node.js for data storage
  • How to use PhoneGap to ready your app for mobile deployment
  • How to test and debug your app on iOS and Android
Pro iOS and Android Apps for Business is for experienced web developers who need to get up to speed quickly in building iOS and Android apps for business.  Are you ready to join the mobile revolution using the same technologies you already use to build great web applications?  If so, this is the book for you!

What you’ll learn

  • How to design a full-featured app, including requirements like offline access
  • How to build the client-side of the app using jQuery Mobile, including adding stub code for calling the node.js server
  • How to create a simple server with node.js and interact with it using REST
  • How to use MongoDB with node.js for data storage
  • How to use PhoneGap to ready your app for mobile deployment
  • How to test and debug your app on iOS and Android

Who this book is for

Experienced web devs who need to get up to speed quickly in building iOS and Android apps for business. HTML/CSS/JavaScript experience highly recommended.

Table of Contents

Part I: The Client
Chapter 1 – Designing My Mobile Organizer 
Chapter 2 - Introducing jQuery and jQuery Mobile 
Chapter 3 - Writing the Application with jQuery Mobile, Part I 
Chapter 4 - Writing the Application with jQuery Mobile, Part II

Part II: The Server
Chapter 5 - Introducing node.js 
Chapter 6 - Introducing MongoDB 
Chapter 7 - Writing the Server with node.js and MongoDB, Part I 
Chapter 8 - Writing the Server with node.js and MongoDB, Part II 

Part III: Putting It All Together
Chapter 9 - Introducing Phonegap 
Chapter 10 - The Final Build: Going Mobile With Phonegap 


Handle onOptionsItemSelected() for ActionBarCompat

This example override onOptionsItemSelected() method to handle user click on Options Menu in ActionBarCompat.

user click on Options Menu in ActionBarCompat
user click on Options Menu in ActionBarCompat
Modify MainActivity.java in last exercise "Add MenuItem to ActionBarCompat using Java", override onOptionsItemSelected(). Get the id of the clicked menu item by calling item.getItemId(), then compare with the id(s) defined.

 @Override
public boolean onOptionsItemSelected(MenuItem item) {
// TODO Auto-generated method stub
//return super.onOptionsItemSelected(item);
switch (item.getItemId()) {
case R.id.action_settings:
//match with /res/menu/main.xml
Toast.makeText(this, "Setting", Toast.LENGTH_SHORT).show();
return true;
case R.id.menuid_info:
//match with defined in onCreateOptionsMenu()
Toast.makeText(this, "Info", Toast.LENGTH_SHORT).show();
return true;
default:
return super.onOptionsItemSelected(item);
}
}




download filesDownload the files.

Next:
ActionBarCompat with Share ShareActionProvider



Visit: ActionBarCompat Step-by-step

Add MenuItem to ActionBarCompat using Java

We are going to add MenuItem, menuItem_Info, to ActionBarCompat using Java code.

With new menuItem_Info
New MenuItem of menuItem_Info added using Java code
Modify exercise from last exercise "Example of using ActionBarCompat with android-support-v7-appcompat".

To add new MenuItem dynamically, we have to assign new id to it. Create a new file, /res/values/ids.xml, to define our of ID:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="menuid_info" type="id"/>
</resources>


Modify onCreateOptionsMenu() method in MainActivity.java to add new MenuItem using Java code:
package com.example.testactionbarcompat;

import android.os.Bundle;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;

public class MainActivity extends ActionBarActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);

//add MenuItem(s) to ActionBar using Java code
MenuItem menuItem_Info = menu.add(0, R.id.menuid_info, 0, "Info");
menuItem_Info.setIcon(android.R.drawable.ic_menu_info_details);
MenuItemCompat.setShowAsAction(menuItem_Info,
MenuItem.SHOW_AS_ACTION_IF_ROOM|MenuItem.SHOW_AS_ACTION_WITH_TEXT);

return true;
}

}

download filesDownload the files.



Visit: ActionBarCompat Step-by-step

Example of using ActionBarCompat with android-support-v7-appcompat

This exercise show the steps to modify the auto-generated "Hello World" by Android ADT/Eclipse, to implement ActionBarCompat, with backward-compatible Action Bar back to Android 2.1.

ActionBarCompat
ActionBarCompat on Nexus One running Android 2.3.6
- Before start our new project, you have to "Create library project with the appcompat v7 support library".

- New a Android Application Project as normal.

- Right click on the project, select Properties, select Android tab on the left box, scroll down on the right to make sure the check box of "is Library" is un-checked, and click the Add button to add library of "android-support-v7-appcompat". then click OK.

android-support-v7-appcompat
add library of android-support-v7-appcompat
- Modify AndroidManifest.xml, change android:theme inside to "@style/Theme.AppCompat". And make sure android:minSdkVersion is equal or higher than 7, Android 2.1.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.testactionbarcompat"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" />

<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/Theme.AppCompat" >
<activity
android:name="com.example.testactionbarcompat.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>


- Modify menu resources file, /res/menu/main.xml.
Add a new xmlns, xmlns:myapp="http://schemas.android.com/apk/res-auto". You can choice any name (myapp in my example) you want. But it has to be matched with the name space in .
 Modify to define myapp:showAsAction="always".
<menu 
xmlns:myapp="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android" >

<item
android:id="@+id/action_settings"
android:orderInCategory="100"
myapp:showAsAction="always"
android:title="@string/action_settings"/>

</menu>


- Modify MainActivity to extend ActionBarActivity with android.support.v7.app.ActionBarActivity imported.
package com.example.testactionbarcompat;

import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;

public class MainActivity extends ActionBarActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}

}

- Now it can be re-build to generate app with Action Bar running on devices of Android 2.1 or higher.


Next:
Add MenuItem to ActionBarCompat using Java



Visit: ActionBarCompat Step-by-step

Changes to the SecretKeyFactory API in Android 4.4

random_droid


In order to encrypt data, you need two things: some data to encrypt and an encryption key. The encryption key is typically a 128- or 256-bit integer. However, most people would rather use a short passphrase instead of a remembering a 78-digit number, so Android provides a way to generate an encryption key from ASCII text inside of javax.crypto.SecretKeyFactory.



Beginning with Android 4.4 KitKat, we’ve made a subtle change to the behavior of SecretKeyFactory. This change may break some applications that use symmetric encryption and meet all of the following conditions:




  1. Use SecretKeyFactory to generate symmetric keys, and

  2. Use PBKDF2WithHmacSHA1 as their key generation algorithm for SecretKeyFactory, and

  3. Allow Unicode input for passphrases



Specifically, PBKDF2WithHmacSHA1 only looks at the lower 8 bits of Java characters in passphrases on devices running Android 4.3 or below. Beginning with Android 4.4, we have changed this implementation to use all available bits in Unicode characters, in compliance with recommendations in PCKS #5.



Users using only ASCII characters in passphrases will see no difference. However, passphrases using higher-order Unicode characters will result in a different key being generated on devices running Android 4.4 and later.



For backward compatibility, we have added a new key generation algorithm which preserves the old behavior: PBKDF2WithHmacSHA1And8bit. Applications that need to preserve compatibility with older platform versions (pre API 19) and meet the conditions above can make use of this code:



import android.os.Build;

SecretKeyFactory factory;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
// Use compatibility key factory -- only uses lower 8-bits of passphrase chars
factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1And8bit");
} else {
// Traditional key factory. Will use lower 8-bits of passphrase chars on
// older Android versions (API level 18 and lower) and all available bits
// on KitKat and newer (API level 19 and higher).
factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
}