Slatedroid info

Everything about android tablet pc [slatedroid]

Samsung possibly bringing mobile image sensors with 1.0μm pixels to the Galaxy Note 5?

Posted by wicked July - 29 - 2015 - Wednesday Comments Off

samsung_logo_with_peopleSamsung has just announced they have a new image sensor with 1.0μm-pixel-based 16 megapixel CMOS image sensor for mobile devices. Basically it’s a smaller chip. The real question is will it be in the Galaxy Note 5?

The soon to be released Galaxy Note 5 is a larger device, but a smaller image sensor would help to reduce the camera bulge. This new chip, known as S5K3P3, is 20% smaller in height than previous generations. It allows manufactures to develop mobile devices with minimal camera protrusion while still keeping a higher resolution camera.

Kyushik Hong, Vice President and Head of S.LSI Marketing at Samsung Electronics said.

“As a trendsetter in the mobile image sensor business, we are pleased to be the first to deliver the most advanced 1.0μm-pixel imager, which meets both high-resolution and slim design requirements for smartphone cameras.” “Starting with 16Mp sensor, Samsung plans to further expand 1.0μm-pixel product category and lead the image sensor market for high performing slim mobile devices.”

Combining S5K3P3 with Samsung’s ISOCELL technology will work by dramatically reducing color crosstalk of neighboring pixels by adding physical barriers between each pixel. This increases light sensitivity and effectively controls the collection of photons. This makes a much higher color fidelity everywhere, but especially in low light situations.

The new S5K3P3 image sensors are available today.

Source: Businesswire

Come comment on this article: Samsung possibly bringing mobile image sensors with 1.0μm pixels to the Galaxy Note 5?

How to get Location address in an Android app

Posted by wicked July - 28 - 2015 - Tuesday Comments Off

aa-geocode-times-square

In previous tutorials, we have discussed how to get location data, as well as using location data to implement a simple device location tracking system using the ThingSpeak API. For this tutorial, we are going to use the Geocoder class to translate a given address into its latitude and longitude values (geocoding), and also translate a latitude and longitude value into an address (reverse geocoding).

Preparation

From Wikipedia, Geocoding uses a description of a location, such as a postal address or place name, to find geographic coordinates. Reverse geocoding, on the other hand, uses geographic coordinates to find a description of the location.

A geocoder is either a piece of software or a service that implements a geocoding process. The Android API contains a Geocoder class that can use either a location name or a location’s latitude and longitude values to get further details about an address (it can perform both forward and reverse geocoding). The returned address details include address name, country name, country code, postal code and more.

App Layout

Our app is going to use both forward and reverse geocoding to get location address, and the app layout reflects this. The layout contains two EditTexts for Latitude and Longitude respectively, and an EditText for address name input. Beneath these, we have two RadioButtons, to select if we are fetching an address using the location’s latitude/longitude values, or using the address name. There is a Button, that begins the geocoding lookup when clicked, a ProgressBar, to show the user that the lookup task is running in the background, and a TextView to show the result received.

aa-geocode-layout

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    tools:context=".FileActivity">

    <EditText
        android:id="@+id/latitudeEdit"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/latitude"
        android:inputType="numberDecimal|numberSigned"/>

    <EditText
        android:id="@+id/longitudeEdit"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/latitudeEdit"
        android:hint="@string/longitude"
        android:inputType="numberDecimal|numberSigned"/>

    <EditText
        android:id="@+id/addressEdit"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/longitudeEdit"
        android:minLines="4"
        android:hint="@string/address"
        android:scrollHorizontally="false"
        android:scrollbars="vertical"
        android:enabled="false"/>

    <RadioGroup
        android:id="@+id/radioGroup"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/addressEdit"
        android:layout_centerHorizontal="true"
        android:orientation="horizontal">

        <RadioButton
            android:id="@+id/radioLocation"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="@string/use_location"
            android:checked="true"
            android:onClick="onRadioButtonClicked"/>

        <RadioButton
            android:id="@+id/radioAddress"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="@string/use_address"
            android:onClick="onRadioButtonClicked"/>
    </RadioGroup>

    <Button
        android:id="@+id/actionButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/radioGroup"
        android:layout_centerHorizontal="true"
        android:text="@string/fetch"
        android:onClick="onButtonClicked"/>

    <TextView
        android:id="@+id/infoText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/actionButton"/>

    <ProgressBar
        android:id="@+id/progressBar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/actionButton"
        android:layout_centerHorizontal="true"
        android:visibility="invisible"/>

</RelativeLayout>

Fetching the Address

Geocoder has two methods for fetching an Address, getFromLocation(), which uses latitude and longitude, and getFromLocationName(), which uses the location’s name. Both methods return a list of Address objects. An Address contains information like address name, country, latitude and longitude, whereas Location contains latitude, longitude, bearing and altitude among others. Remember that the Geocoder methods above block the thread they are executed in, and should never be called from the app’s UI thread.

To perform a long running task in the background, we can use an AsyncTask. However, the AsyncTask is not recommended for operations like the Geocoder lookup, because it can take a potentially long time to return. AsyncTask’s should be used for comparatively shorter operations. While we can (and did) use the AsyncTask, as per the Android developer recommendations and best practices, we would use an IntentService. An IntentService extends Service, and operations run in it can take as long as necessary. An IntentService holds no reference to the Activity it was started from, and so, the activity can be rebuilt (like when the device is rotated), without affecting the IntentService’s tasks, unlike the AsyncTask. (NB: We actually used an AsyncTask, and it worked just as well. As a bonus, the activity, using an AsyncTask is available in the github project as MainActivityWithAsyncTask)

Using the IntentService

We extend IntentService and define GeocodeAddressIntentService. An IntentService is started much like an Activity. We build an Intent, and start the service by calling Context.startService() method.

Before defining the class, we include our GeocodeAddressIntentService in the AppManifest. Don’t forget to also include the INTERNET permission. In my case, while developing/testing on a Nexus 5 Lollipop device, the network calls just silently failed prior to including the INTERNET permission. So, if you do not get any response, first confirm that you have requested the INTERNET permission.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.sample.foo.simplegeocodeapp">

        <uses-permission android:name="android.permission.INTERNET"/>

    <application
        ...
        <service
            android:name=".GeocodeAddressIntentService"
            android:exported="false"/>
    </application>

</manifest>

To use our IntentService, we must implement the onHandleIntent(Intent) method. This is the entry point for IntentService’s, much like the onCreate() is the entry point for Activity’s. In the code snippet below, take notice of the ResultReceiver object. When your IntentService has completed it’s task, it should have a way to send the results back to the invoking Activity. That is where the ResultReceiver comes in, and we’ll discuss it’s implementation in a bit.

public class GeocodeAddressIntentService extends IntentService {

    protected ResultReceiver resultReceiver;
    private static final String TAG = "FetchAddyIntentService";

    public GeocodeAddressIntentService() {
        super("GeocodeAddressIntentService");
    }
    ...
    @Override
    protected void onHandleIntent(Intent intent) {
        Geocoder geocoder = new Geocoder(this, Locale.getDefault());
        List<Address> addresses = null;

        resultReceiver = intent.getParcelableExtra(Constants.RECEIVER);
        int fetchType = intent.getIntExtra(Constants.FETCH_TYPE_EXTRA, 0);
    ...
    }
}

The code snippet below contains the actual forward or reverse geocoding lookup calls. We determine if the search uses location name, or location latitude/longitude values, and call the appropriate method. If using location name, we call the Geocoder.getFromLocationName() method, and if using latitude/longitude, we call Geocoder.getFromLocation() method. You can specify a maximum number of addresses to be returned. In our sample, we request for a maximum of one (1) address. Note that an address name can refer to more than one location, spread across multiple countries. In a production app, you might want to fetch more than one, and have an algorithm determine which is the most likely required address.

        if(fetchType == Constants.USE_ADDRESS_NAME) {
            String name = intent.getStringExtra(Constants.LOCATION_NAME_DATA_EXTRA);
            try {
                addresses = geocoder.getFromLocationName(name, 1);
            } catch (IOException e) {
                errorMessage = "Service not available";
                Log.e(TAG, errorMessage, e);
            }
        }
        else if(fetchType == Constants.USE_ADDRESS_LOCATION) {
            Location location = intent.getParcelableExtra(
                    Constants.LOCATION_DATA_EXTRA);

            try {
                addresses = geocoder.getFromLocation(
                        location.getLatitude(), location.getLongitude(), 1);
            } catch (IOException ioException) {
                errorMessage = "Service Not Available";
                Log.e(TAG, errorMessage, ioException);
            } catch (IllegalArgumentException illegalArgumentException) {
                errorMessage = "Invalid Latitude or Longitude Used";
                Log.e(TAG, errorMessage + ". " +
                        "Latitude = " + location.getLatitude() + ", Longitude = " +
                        location.getLongitude(), illegalArgumentException);
            }
        }
        else {
            errorMessage = "Unknown Type";
        }

        if (addresses == null || addresses.size()  == 0) {
            if (errorMessage.isEmpty()) {
                errorMessage = "Not Found";
            }
            deliverResultToReceiver(Constants.FAILURE_RESULT, errorMessage, null);
        } else {
            for(Address address : addresses) {
                String outputAddress = "";
                for(int i = 0; i < address.getMaxAddressLineIndex(); i++) {
                    outputAddress += " --- " + address.getAddressLine(i);
                }
            }
            Address address = addresses.get(0);
            ArrayList<String> addressFragments = new ArrayList<String>();

            for(int i = 0; i < address.getMaxAddressLineIndex(); i++) {
                addressFragments.add(address.getAddressLine(i));
            }
(R.string.address_found));
            deliverResultToReceiver(Constants.SUCCESS_RESULT,
                    TextUtils.join(System.getProperty("line.separator"),
                            addressFragments), address);
        }

deliverResultToReceiver is a simple method, that handles returning the results of the operation to the invoking Activity, through the ResultReceiver.

    private void deliverResultToReceiver(int resultCode, String message, Address address) {
        Bundle bundle = new Bundle();
        bundle.putParcelable(Constants.RESULT_ADDRESS, address);
        bundle.putString(Constants.RESULT_DATA_KEY, message);
        resultReceiver.send(resultCode, bundle);
    }

We implemented the ResultReceiver as an inner class in the MainActivity.

    class AddressResultReceiver extends ResultReceiver {
        public AddressResultReceiver(Handler handler) {
            super(handler);
        }

        @Override
        protected void onReceiveResult(int resultCode, final Bundle resultData) {
            if (resultCode == Constants.SUCCESS_RESULT) {
                final Address address = resultData.getParcelable(Constants.RESULT_ADDRESS);
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        progressBar.setVisibility(View.INVISIBLE);
                        infoText.setText("Latitude: " + address.getLatitude() + "\n" +
                                "Longitude: " + address.getLongitude() + "\n" +
                                "Address: " + resultData.getString(Constants.RESULT_DATA_KEY));
                    }
                });
            }
            else {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        progressBar.setVisibility(View.INVISIBLE);
                        infoText.setText(resultData.getString(Constants.RESULT_DATA_KEY));
                    }
                });
            }
        }

aa-geocode-the-louvre

Starting the IntentService is pretty similar to starting a new Activity. We build an Intent, put in the necessary Extras, and call Context.startService(Intent). The Extras we bundle in the Intent is dependent on if we are performing a forward or reverse lookup.

    public void onButtonClicked(View view) {
        Intent intent = new Intent(this, GeocodeAddressIntentService.class);
        intent.putExtra(Constants.RECEIVER, mResultReceiver);
        intent.putExtra(Constants.FETCH_TYPE_EXTRA, fetchType);
        if(fetchType == Constants.USE_ADDRESS_NAME) {
            if(addressEdit.getText().length() == 0) {
                Toast.makeText(this, "Please enter an address name", Toast.LENGTH_LONG).show();
                return;
            }
            intent.putExtra(Constants.LOCATION_NAME_DATA_EXTRA, addressEdit.getText().toString());
        }
        else {
            if(latitudeEdit.getText().length() == 0 || longitudeEdit.getText().length() == 0) {
                Toast.makeText(this,
                        "Please enter latitude/longitude values",
                        Toast.LENGTH_LONG).show();
                return;
            }
            Location location = new Location("");
            location.setLatitude(Double.parseDouble(latitudeEdit.getText().toString()));
            location.setLongitude(Double.parseDouble(longitudeEdit.getText().toString()));
            intent.putExtra(Constants.LOCATION_DATA_EXTRA, location);
        }
        progressBar.setVisibility(View.VISIBLE);
        Log.e(TAG, "Starting Service");
        startService(intent);
    }

aa-geocode-times-square

Conclusion

While it is all well and good tracking a user’s location, for your app to truly amaze, showing users an address name for a given location will almost always be more useful than the corresponding latitude and longitude values.

The complete source code is available on GitHub, and can be forked, downloaded, copied and used as desired.

If you followed our previous tutorials on using the ThingSpeak API to track a device’s location, and how to get and use an Android device’s location, try to integrate geocoding and get location address in both apps. Have fun coding, and share your challenges and successes in the comments below.

Top rookie Android developer mistakes

Posted by wicked July - 23 - 2015 - Thursday Comments Off

android developer development Alper Çuğun

Android is a fantastic platform to develop for. Its development tools are free, easy to come by, and available for Windows, MAC and Linux computers. Android has excellent developer documentation, it is the dominant mobile operating system, and it is available on phones, tablets, watches, TVs and cars. Developing and publishing an Android app is also incredibly easy and straight forward, considering that there are multiple Android app stores available, unlike the single app store for iOS and Windows.

The Android platform has matured quite a lot since September 2008, when version 1.0 was released. The first version of the SDK was released in November 2007, using Eclipse IDE and the ADT plugin. The tools available to developers has grown in leaps and bounds, as has the API, and today, the preferred (and officially sanctioned) method is using the Android Studio IDE. Android Studio is based on the IntelliJ IDE, and is designed to ease android app development. It achieves this in many ways, a few of which include

  • Tools to catch performance, compatibility and usability problems during design/development
  • Ability to preview layout designs for multiple devices during design/development
  • Support for Google Cloud Messaging and App Engine integration with an Android app
  • Templates to create and manage android projects
  • Templates to create and manage smartphone, tablet, watch, TV and Auto apps

and a whole lot more.

Android Studio has been designed to alert developers to issues with their code, and helps alert beginner coders to a lot of the most common errors they can make. But the IDE can only do so much to protect new (and sometimes even experienced) developers from themselves.

In this article, we discuss some of the most common mistakes made by a rookie Android developers, in no particular order. Even some experienced developers fall prey to some of these mistakes sometimes, so hopefully you will find this rundown useful. Let’s begin!

Using iOS design language

z-e1-camera-3

This is relatively (comparatively) rare, but many developers coming from an iOS background tend to design their apps like iOS apps, rather than like Android apps. Both platforms are incredibly similar, but awfully different. An Android app should fit in with the Android system of doing things, while an iOS app should fit in with the iOS way of doing things. If you intend to develop for the Android platform, you must read the Android design guidelines first. At the very least peruse the document, so that you have a general understanding of the Android ecosystem. You do not want to confuse users with a jarring interface, different from every other app they use daily. Differentiate your app with features and functionality, and personalize with colors and logos.

Not using Intents

Intents are a key part of the Android system. They are a means of requesting for data or an action from another app component (could be the same app, or another, completely different app). There are loads of actions your app might want to perform, and rather than re-implementing these actions, you simply ask the Android system to pick the best suited app for that task. For example, an app requires to pick a contact, with phone number, from the device. Rather than reading the contacts database, and implementing a List to show the user all contacts that have a phone number, and then implementing the logic to select a contact, an experienced developer would simply use the following code snippet

private void pickContact() {
    Intent pickContactIntent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
    pickContactIntent.setType(ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE);
    startActivityForResult(pickContactIntent, PICK_CONTACT_REQUEST);
}

There are a ton of actions that can be performed using Intents, including taking pictures/videos, sharing content, playing videos, setting reminders and alarms, and much more. Developers can even define their own filters for intents.

Not using fragments

During the dark days of Android development, before Honeycomb (Ice Cream Sandwich for phones), Android apps were built using only activities and services. After the great awakening, the concept of fragments was introduced to the API. A fragment is a mini activity, that can be embedded (and combined with other fragments) in an activity. This enables developers build UIs that able to easily adapt and switch between tablet and phone sized devices.

Developing for the current Android version

android version shares july 2015

Android has a well discussed fragmentation problem. The current version of Android, as of writing, is Lollipop version 5.1.1. Lollipop version 5.0 was released on November 12 2014, and over eight months later, Lollipop adoption stands at a measly 12%. Android M, the next version of Android is already available to developers and beta testers, and it is expected to be released around November 2015. Each version of Android introduces new APIs and a rookie Android developer would be tempted to immediately use the new APIs for apps. Doing this would greatly reduce the number of potential users for your app.

An experienced Android developer, on the other hand, would check for the availability of the new APIs in the Android Support Library, and use that instead. The Android Support Library package is a set of code libraries that provide backward-compatible versions of Android framework APIs as well as features that are only available through the library APIs.

At the other extreme, be wary of attempting to support really old devices. Supporting devices with Ice Cream Sandwich and above covers close to 95% of all current android devices.

Developing for a single (or two) screen

Google Nexus

There are literally thousands of different Android devices in the market today, with different screen sizes and resolutions, and app widgets scale and look different on devices. The Android design specs contains guidelines on best practices for designing layouts. When designing for Android, developers should use dp (density independent pixels) for specifying image and widget sizes, and sp (scaleable pixels) for fonts. Check out our previous articles on why you should test on a range of devices, and how to economically test your app on a range of devices.

Experienced Android developers will switch between preview devices in Android Studio during design/development. Rookie Android developers, on the other hand, are more likely to assume that since it works great on their Samsung Galaxy S6 and/or LG G4, it would look equally good on the Galaxy Ace 2 and Moto G (or vice versa).

Blocking the main (UI) thread

For every Android application, on launch, the system creates a thread of execution, called the main (or UI) thread. This thread is in charge of dispatching touch/tap events to the app widgets, drawing and updating widgets, and general interactions with the user. By default, all code executed by an app is executed on the main thread. This used to pose a problem – when long running operations are performed on this thread, the app appears to be frozen or hung. This was such a problem, especially with apps that attempted to fetch network resources, that on newer versions of Android, apps cannot make network calls on the main thread. Other possibly long running tasks that shouldn’t be performed on the main thread include

  • Loading bitmaps
  • Writing/Reading from database/file
  • Complex calculations

Below is a sample code for downloading an image from a separate thread and displaying it in an ImageView in response to a click event.

public void onClick(View v) {
    new Thread(new Runnable() {
        public void run() {
            final Bitmap bitmap =
                    loadImageFromNetwork("http://example.com/image.png");
            mImageView.post(new Runnable() {
                public void run() {
                    mImageView.setImageBitmap(bitmap);
                }
            });
        }
    }).start();
}

An experienced developer never wants his app to appear to be frozen. Also, the Android system alerts users with an Application Not Responding (ANR) if the main thread is blocked for a given period (5 seconds for activities). For possible long running tasks, consider using an AsyncTask. Also, consider using a ProgressBar while your app is performing a background task.

Not reading the docs

The Android Developer website is a comprehensive and extensive resource for Android app design, development and distribution. There are guides, tutorials, best practices, guidelines, specifications as well as API documentation. The website is regularly updated, and every aspiring Android developer must have this as a top bookmark. In addition, rookie Android developers will benefit immensely from StackOverflow. StackOverflow is an online community of developers, where users ask questions regarding any programming issues/challenges they face, and other professionals answer these questions. Virtually every problem a new developer can run into has been experienced, asked and answered on StackOverflow.

Deeply nested view hierarchy

Russian-Matroshka no bg

A common rookie mistake is assuming that using basic layout structures leads to efficient layouts. Actually, every widget and layout added to the app increases the time spent drawing the app layout. Particularly, using the layout_weight parameter can be quite expensive during rendering. It is better to use a single RelativeLayout, and align the widgets in relation to each other. A flat, shallow and wide layout performs better than a narrow and deep layout. The Lint tool, bundled with Android Studio, can help optimize app layout files by recommending actions such as

  • Use compound drawables: A LinearLayout with a single ImageView and TextView will be more efficient as a single compound drawable
  • Useless parent: A layout with children, but whose removal wouldn’t affect the final appearance
  • Useless leaf: A layout with no children and no background
  • Deep Layouts: The maximum nest depth is 10. Ideally, app layouts should be 2-3 levels deep

Misunderstanding bitmaps/images

Bitmaps and images can, and do, use significant memory resources. Most rookie Android developers run into the dreaded OutOfMemoryError when loading and/or displaying collections of images. Before an image is drawn on screen, it must first be loaded in memory. For example, loading a 2448×3264 ARGB_8888 image requires 4 * 2448 * 3264 bytes when loaded. That is about 32MB memory allocation needed for a single image. If the image ends up being displayed as on an ImageView that’s 200×200 pixels in size, the memory allocation needed is actually only 4 * 200 * 200 bytes (about 160KB). Loading the entire image, only to display it on a 200×200 widget just used almost 32MB memory space, rather that 160KB.

Experienced developers know to use Bitmap.createScaledBitmap() when loading Bitmaps. Also, a rookie Android developer would be tempted to load images in the main thread. Check out the Android developer page on displaying bitmaps efficiently.

Assuming mobile app equals small project

This is a mistake seen all too often from almost everyone except experienced Android developers, or those with an experience in software development. Many new and aspiring Android developers somehow think that the fact that they are building an app for mobile devices means that it is a small project that shouldn’t require much prior planning, or can be completed in a weekend of pizza and coffee fueled coding binge. This is horrendously far from reality. Android app development is no different from any other software development project, and requires specifications, schedules/timelines, bug tracking, and a release and maintenance plan.


Android Developer Newsletter

Do you want to know more? Subscribe to our Android Developer Newsletter. Just type in your email address below to get all the top developer news, tips & links once a week in your inbox:


PS. No spam, ever. Your email address will only ever be used for Android Dev Weekly.

Conclusion

Android development, much like software development, is a fun and rewarding pastime (or work, if you call it that). The above is a non exhaustive list of some common mistakes newbie Android developers tend to make. There is only one way to become an experienced Android developer, and that is to keep developing apps. Did we leave something out? What silly mistakes did you make when starting out? Holler in the comments, some of us might still be making those mistakes.

Using the ThingSpeak API to track a device’s location

Posted by wicked July - 22 - 2015 - Wednesday Comments Off

We have previously demonstrated how to use a web API from your Android app, and we have also discussed how to get and use location data in your Android app. In this tutorial, we will utilize both of these lessons, and show how you can track a device’s location using a remote web API. The remote web API we selected is the Thingspeak API.

aa_thingspeak_logo

For this article, we will develop an Android application that gets the device’s location information, and sends the latitude/longitude data to a ThingSpeak channel. We will then fetch the last location data from the ThingSpeak channel, and compute the distance from the last updated location to a location entered by the user. A simple (and obvious) use of this is parents who wish to track their children, or employers tracking employees. The ThingSpeak channel can also be viewed using a browser.

Getting Started

First thing you should do is to register for a ThingSpeak account. It is, at the time of writing, completely free. After registration, you will need to create a channel. You can have multiple channels, but each channel has a unique ID, and a special Channel write API_KEY, that can be used to write or read data to the channel. For a private channel, you can generate read API_KEYs, that can only read data from the channel.

While creating your channel, you might notice a Latitude and Longitude field. These are used for static devices, and are not suitable for our use case. ThingSpeak allows for the tracking of up to eight different fields, named field1 through field8. We add latitude as field1, and longitude as field2. You can access the ThingSpeak documentation online on their Support page

aa_thingspeak_fields

App Layout

aa_thingspeak_layout

Our app layout displays the current device latitude and longitude. Beneath these is a button, enabling us begin and pause location tracking. Whenever the app receives a location update, the values of the TextViews are updated, and the new location data is immediately sent to the ThingSpeak channel. There are two EditTexts, into which the user can enter latitude and longitude values to compare against the device’s location. Clicking on the “Get Distance” button will fetch the last updated location from the thingspeak channel, and perform a Location.distanceTo() to compute the distance between both Locations.
Our activity_main.xml is a simple RelativeLayout.

<RelativeLayout 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:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/latitudeText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/latitude"
        android:textSize="20sp"/>

    <TextView
        android:id="@+id/latitudeUpdate"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/latitudeText"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:text="0.00"
        android:textSize="20sp"/>

    <TextView
        android:id="@+id/longitudeText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/latitudeText"
        android:text="@string/longitude"
        android:textSize="20sp"/>

    <TextView
        android:id="@+id/longitudeUpdate"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/longitudeText"
        android:layout_below="@id/latitudeUpdate"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:text="0.00"
        android:textSize="20sp"/>

    <Button
        android:id="@+id/locationController"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_below="@id/longitudeUpdate"
        android:text="@string/resume"
        android:onClick="toggleLocationUpdates" />

    <EditText
        android:id="@+id/latitudeTarget"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/locationController"
        android:hint="@string/target_latitude"/>

    <EditText
        android:id="@+id/longitudeTarget"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/latitudeTarget"
        android:hint="@string/target_longitude"/>

    <Button
        android:id="@+id/notificationController"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/longitudeTarget"
        android:layout_centerHorizontal="true"
        android:text="@string/get_distance"
        android:onClick="compareLocation" />

    <TextView
        android:id="@+id/distanceText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/notificationController"
        android:gravity="center"/>

    <ProgressBar
        android:id="@+id/progressBar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/notificationController"
        android:layout_centerHorizontal="true"
        android:visibility="gone"/>

</RelativeLayout>

Updating your channel

Recall our previous article on fetching location data? For this app, we are using the GPS_PROVIDER. If your application runs in the background (as a service), consider using the PASSIVE_PROVIDER, or use a longer refresh time.

In the code snippet below, when the “Begin Tracking” button is clicked, we request location updates from the GPS_PROVIDER every two minutes (2 * 60 * 1000). However, if the button reads “Pause Tracking”, we ask the LocationManager to stop sending updates.

    public void toggleLocationUpdates(View view) {
        if(!checkLocation())
            return;

        Button button = (Button) view;
        if(button.getText().equals(getResources().getString(R.string.pause))) {
            locationManager.removeUpdates(locationListener);
            button.setText(R.string.resume);
        }
        else {
            locationManager.requestLocationUpdates(
                    LocationManager.GPS_PROVIDER, 2 * 60 * 1000, 10, locationListener);
            button.setText(R.string.pause);
        }
    }

This snippet is our implementation of the LocationListener interface. When we receive a new location update, the onLocationChanged() method is called, with the new Location information as the method arguments. On extracting the latitude and longitude values, we execute the AsyncTask that updates the thingspeak API.

    private final LocationListener locationListener = new LocationListener() {
        public void onLocationChanged(final Location location) {
            longitude = location.getLongitude();
            latitude = location.getLatitude();
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    longitudeUpdate.setText(longitude + "");
                    latitudeUpdate.setText(latitude + "");
                }
            });

            new UpdateThingspeakTask().execute();
        }
    };

Android prevents developers from performing potentially long running tasks in the UI thread (the thread that controls the responsiveness of your application’s widgets). As such, we must perform network tasks in another thread, and the AsyncTask is a great class that handles all the thread complexity behind the scenes. Instructions in both onPreExecute() and onPostExecute() are run on the UI thread before and after the long running task respectively, while the long running task is placed in the doInBackground() method.

    class UpdateThingspeakTask extends AsyncTask<Void, Void, String> {

        private Exception exception;

        protected void onPreExecute() {
        }

        protected String doInBackground(Void... urls) {
            try {
                URL url = new URL(THINGSPEAK_UPDATE_URL + THINGSPEAK_API_KEY_STRING + "=" +
                        THINGSPEAK_API_KEY + "&" + THINGSPEAK_FIELD1 + "=" + latitude +
                        "&" + THINGSPEAK_FIELD2 + "=" + longitude);
                HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
                try {
                    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
                    StringBuilder stringBuilder = new StringBuilder();
                    String line;
                    while ((line = bufferedReader.readLine()) != null) {
                        stringBuilder.append(line).append("\n");
                    }
                    bufferedReader.close();
                    return stringBuilder.toString();
                }
                finally{
                    urlConnection.disconnect();
                }
            }
            catch(Exception e) {
                Log.e("ERROR", e.getMessage(), e);
                return null;
            }
        }

        protected void onPostExecute(String response) {
            // We completely ignore the response
            // Ideally we should confirm that our update was successful
        }
    }

Fetching channel data

There are many different ways data can be read from a ThingSpeak channel. This includes

  • The entire channel feed
  • Individual fields
  • A specific update
  • Updates within a given time frame and more

Consult the documentation to learn more.

We, however, are interested in retrieving the last update only. This is implemented using an AsyncTask.

In the onPreExecute() method, we fetch the latitude/longitude values, disable further editing of the fields, and display the ProgressBar.

In the onPostExecute() method, we parse the received to a JSONObject, fetch the returned latitude/longitude values, and finally compute the distance between both locations.

    class FetchThingspeakTask extends AsyncTask<Void, Void, String> {

        Location target;

        protected void onPreExecute() {
            double latitude = Double.parseDouble(latitudeEdit.getText().toString());
            double longitude = Double.parseDouble(longitudeEdit.getText().toString());
            target = new Location("");
            target.setLatitude(latitude);
            target.setLongitude(longitude);

            latitudeEdit.setEnabled(false);
            longitudeEdit.setEnabled(false);
            distanceText.setText("");
            distanceText.setVisibility(View.GONE);
            progressBar.setVisibility(View.VISIBLE);
        }

        protected String doInBackground(Void... urls) {
            try {
                URL url = new URL(THINGSPEAK_CHANNEL_URL + THINGSPEAK_CHANNEL_ID +
                        THINGSPEAK_FEEDS_LAST + THINGSPEAK_API_KEY_STRING + "=" +
                        THINGSPEAK_API_KEY + "");
                HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
                try {
                    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
                    StringBuilder stringBuilder = new StringBuilder();
                    String line;
                    while ((line = bufferedReader.readLine()) != null) {
                        stringBuilder.append(line).append("\n");
                    }
                    bufferedReader.close();
                    return stringBuilder.toString();
                }
                finally{
                    urlConnection.disconnect();
                }
            }
            catch(Exception e) {
                Log.e("ERROR", e.getMessage(), e);
                return null;
            }
        }

        protected void onPostExecute(String response) {
            if(response == null) {
                Toast.makeText(MainActivity.this, "There was an error", Toast.LENGTH_SHORT).show();
                return;
            }
            latitudeEdit.setEnabled(true);
            longitudeEdit.setEnabled(true);

            distanceText.setVisibility(View.VISIBLE);
            progressBar.setVisibility(View.GONE);

            try {
                JSONObject channel = (JSONObject) new JSONTokener(response).nextValue();
                double latitude = channel.getDouble(THINGSPEAK_FIELD1);
                double longitude = channel.getDouble(THINGSPEAK_FIELD2);
                Location location = new Location("");
                location.setLatitude(latitude);
                location.setLongitude(longitude);
                float distance = location.distanceTo(target);
                distanceText.setText("The distance between both Locations is \n" +
                        distance + " meters");
                Log.e(TAG, "distance == " + distance);
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }

aa_thingspeak_newyork

Round up

The complete source is available on Github, for use as you see fit. If building from scratch, you would need to request for both the INTERNET and LOCATION permissions by adding the following to your AndroidManifest

    <uses-permission
        android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.INTERNET" />

Using the GPS_PROVIDER is a battery hog, so if your app is going to run in the background, consider using the PASSIVE_PROVIDER to reduce battery usage.

aa_thingspeak_high_battery

The ThingSpeak API allows channel updates every 15 seconds, and fields can contain either numeric data or alphanumeric strings. There are tons of interesting public channels, including a hamster on Twitter. Have you used ThingSpeak or a similar service? What was your experience? What was/is your use case? Share in the comments below.


Android Developer Newsletter

Do you want to know more? Subscribe to our Android Developer Newsletter. Just type in your email address below to get all the top developer news, tips & links once a week in your inbox:


PS. No spam, ever. Your email address will only ever be used for Android Dev Weekly.


Google acquires Pixate – mobile app prototyping platform now free

Posted by wicked July - 22 - 2015 - Wednesday Comments Off
pixate-main

Google’s never-ending shopping spree continues as the company tries to expand its reach anywhere possible. Their latest acquisition has just been announced and developers will be especially fond of it. The Search Giant is now welcoming the Pixate crew and integrating them right into their design team.

The acquisition’s cash amount is yet to be disclosed, but that is not what people are really worrying about. It doesn’t matter how much Pixate costed Google; what matters is how much it will cost you. The good news is Pixate Studio has gone completely free, which is a stunning discount for software that costed hundreds of dollars. We’ll talk more about pricing in a bit, though. For now let’s focus on what’s going on with Google and Pixate.

pixate-1

What is Pixate?

To put it shortly, Pixate Studio is a software that allows developers and designers to see their ideas for mobile apps come to life. It can generate native prototypes for iOS and Android, allowing app makers to experience their interfaces as if they were real.

In addition, the platform makes it a breeze for developers to upload their own layers, as well as adding interaction commands and animations. These projects can then easily be shared with the team so that they may test the design and further improve upon it.

pixate-2

What will happen to Pixate?

Both Google and Pixate assure the design tool will not be dying and is to continue running independently. That is not to say there won’t be changes – there definitely will be. Don’t worry, though. These are all going to benefit the user.

Pricing

Pixate Studio and Cloud were not cheap, but you can always count on Google to make services much more accessible. After all, the Search Giant is all about getting more developers on board, so it only sensible to make it as affordable as possible… and that they did. Pixate Studio is now completely free!

Furthermore, Pixate Cloud has been heavily discounted to $5 a month or $50 a year, per user. For this reason, Pixate will no longer continue to offer cloud services for free. Instead, users have been given a 60-day trial and pricing will be as already stated, once this testing period is over.

In addition, those who have already purchased Pixate Studio will get a $150 credit to be used toward Pixate Cloud. Alternatively, those who purchased it within the last 14 days can get a full refund, if they so choose to.

pixate-hello-google

What will the Pixate team do at Google?

While they are not expressing too much about future plans, Google does state the acquisition adds to their “ongoing effort to develop new design and prototyping tools, including Form 1.3″. Pixate CEO Paul Colton also mentions very little about their role at Mountain View, only mentioning they are “joining the design team”.

Wrapping up

Google continues building bridges so that developers may create the best apps they can. This acquisition is only part of it, but it will prove to be a great tool for app designers. Especially now that it costs nothing! Do we have any developers around here? Go download it now and see how it can improve your work.

Get Pixate for free!

 

How to get and use location data in your Android app

Posted by wicked July - 15 - 2015 - Wednesday Comments Off

location_marker_gps_shutterstock Shutterstock

Using Location in your app has incredible potential in making your app seem intelligent to end users. With location data, your app can predict a user’s potential actions, recommend actions, or perform actions in the background without user interaction.

For this article, we shall discuss integrating location updates into an Android app, with a focus on fetching the latitude and longitude of a given Location only. It is worth pointing out that Location can (and does) contain much more than just latitude and longitude values. It can also have values for the bearing, altitude and velocity of the device.

Preparation

Before your app can receive any location data, you must request location permissions. There are two location permissions, ACCESS_FINE_LOCATION and ACCESS_COARSE_LOCATION. We use ACCESS_FINE_LOCATION to indicate that we want to receive as precise a location as possible. To request this permission, add the following to your app manifest:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.sample.foo.simplelocationapp" >
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
</maniifest>

We also need to select which of the location providers we want to use to get the location data. There are currently three providers:

  • GPS_PROVIDER: The most accurate method, which uses the built-in GPS receiver of the device. GPS is a system of satellites in orbit, that provides location information from almost anywhere on earth. It can sometimes take a while to get a GPS location fix (generally faster when the device is outdoors).
  • NETWORK_PROVIDER: This method determines a device’s location using data collected from the surrounding cell towers and WiFi access points. While it is not as accurate as the GPS method, it provides a quite adequate representation of the device’s location.
  • PASSIVE_PROVIDER: This provider is special, in that it indicates that your app doesn’t want to actually initiate a location fix, but uses the location updates received by other applications/services. In other words, the passive provider will use location data provided by either the GPS or NETWORK providers. You can find out what provider your passive provider actually used with the returned Location’s getProvider() method. This provides the greatest battery savings.

Layout

aa_location_layout

For our app, we are going to fetch location data using the GPS provider, the NETWORK provider, and also by asking the device to decide which is the best available provider that meets a given set of criteria. Our layout has three identical segments, each of which contains:

  • A title for the section, such as GPS LOCATION
  • A Button to resume and pause location updates for the section/provider
  • Longitude Value
  • Latitude Value

The code snippet for the GPS section, from our layout/activity_main.xml file is shown below

        <TextView
            android:id="@+id/titleTextGPS"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:text="GPS LOCATION"
            android:textSize="20sp"/>

        <Button
            android:id="@+id/locationControllerGPS"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_below="@id/titleTextGPS"
            android:text="@string/resume"
            android:onClick="toggleGPSUpdates"/>

        <TextView
            android:id="@+id/longitudeTextGPS"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/locationControllerGPS"
            android:text="longitude"
            android:textSize="20sp"/>

        <TextView
            android:id="@+id/longitudeValueGPS"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/locationControllerGPS"
            android:layout_toRightOf="@id/longitudeTextGPS"
            android:paddingLeft="@dimen/activity_horizontal_margin"
            android:text="0.0000"
            android:textSize="20sp"/>

        <TextView
            android:id="@+id/latitudeTextGPS"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/longitudeTextGPS"
            android:text="latitude"
            android:textSize="20sp"/>

        <TextView
            android:id="@+id/latitudeValueGPS"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/longitudeValueGPS"
            android:layout_toRightOf="@id/longitudeTextGPS"
            android:paddingLeft="@dimen/activity_horizontal_margin"
            android:text="0.0000"
            android:textSize="20sp"/>

MainActivity

It is possible that the user has their device Location settings turned off. Before requesting location information, we should check that Location services are enabled. Polling for location data with the settings turned off will return null. To check if Location is enabled, we implement a method, called isLocationEnabled(), shown below:

private boolean isLocationEnabled() {
        return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) ||
                locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);

We simply ask the LocationManager if either the GPS_PROVIDER or the NETWORK_PROVIDER is available. In the case where the user has Location turned off, we want to help them get to the Location screen as easily and quickly as possible to turn it on and get back into our app. To do this, we implement the showAlert() method.

private void showAlert() {
    final AlertDialog.Builder dialog = new AlertDialog.Builder(this);
    dialog.setTitle("Enable Location")
            .setMessage("Your Locations Settings is set to 'Off'.\nPlease Enable Location to " +
            "use this app")
            .setPositiveButton("Location Settings", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface paramDialogInterface, int paramInt) {
                    Intent myIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                    startActivity(myIntent);
                }
            })
            .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface paramDialogInterface, int paramInt) {
                }
            });
    dialog.show();
}

The most interesting line in the snippet above is within the setPositiveButton() method. We start an activity using the Settings.ACTION_LOCATION_SOURCE_SETTINGS intent, so that when the user clicks on the button, they are taken to the Location Settings screen.

aa_location_settings

Getting location updates

To get GPS and Network location updates, we use one of the LocationManager’s requestLocationUpdates() methods. Our preferred is requestLocationUpdates(String provider, int updateTime, int updateDistance, LocationListener listener). updateTime refers to the frequency with which we require updates, while updateDistance refers to the distance covered before we require an update. Note that updateTime simply specifies the minimum time period before we require a new update. This means that the actual time between two updates can be more than updateTime, but won’t be less.
A very important point to consider is that Location polling uses more battery power. If your app doesn’t require location updates when in the background, consider stopping updates using one of the removeUpdates() methods. In the code snippet below, we stop/start location updates in response to clicking on the relevant Button.

public void toggleGPSUpdates(View view) {
    if(!checkLocation())
        return;
    Button button = (Button) view;
    if(button.getText().equals(getResources().getString(R.string.pause))) {
        locationManager.removeUpdates(locationListenerGPS);
        button.setText(R.string.resume);
    }
    else {
        locationManager.requestLocationUpdates(
                LocationManager.GPS_PROVIDER, 2 * 60 * 1000, 10, locationListenerGPS);
        button.setText(R.string.pause);
    }
}

aa_location_gps

For both NETWORK_PROVIDER and PASSIVE_PROVIDER, simply replace GPS_PROVIDER above with your desired provider.

In the case where you just want to pick the best available provider, there is a LocationManager method, getBestProvider() that allows you do exactly that. You specify some Criteria to be used in selecting which provider is best, and the LocationManager provides you with whichever it determines is the best fit. Here is a sample code, and it’s what we use to select a provider:

Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setAltitudeRequired(false);
criteria.setBearingRequired(false);
criteria.setCostAllowed(true);
criteria.setPowerRequirement(Criteria.POWER_LOW);
String provider = locationManager.getBestProvider(criteria, true);
if(provider != null) {
    locationManager.requestLocationUpdates(provider, 2 * 60 * 1000, 10, locationListenerBest);
    button.setText(R.string.pause);
    Toast.makeText(this, "Best Provider is " + provider, Toast.LENGTH_LONG).show();
}

Using the above code and Criteria, the best provider will be GPS_PROVIDER, where both GPS and NETWORK are available. However if the GPS is turned off, the NETWORK_PROVIDER will be chosen and returned as the best provider.

aa_location_best_provider

LocationListener

The LocationListener is an interface for receiving Location updates from the LocationManager. It has four methods

  • onLocationChanged() – called whenever there is an update from the LocationManager.
  • onStatusChanged() – called when the provider status changes, for example it becomes available after a period of inactivity
  • onProviderDisabled() – called when the user disables the provider. You might want to alert the user in this case that your app functionality will be reduced
  • onProviderEnabled() – called when the user enables the provider

We implement only the onLocationChanged() method for this sample, but in a production app, you will most likely want to perform an appropriate action for each situation.

private final LocationListener locationListenerNetwork = new LocationListener() {
    public void onLocationChanged(Location location) {
        longitudeNetwork = location.getLongitude();
        latitudeNetwork = location.getLatitude();
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                longitudeValueNetwork.setText(longitudeNetwork + "");
                latitudeValueNetwork.setText(latitudeNetwork + "");
                Toast.makeText(MainActivity.this, "Network Provider update", Toast.LENGTH_SHORT).show();
            }
        });
    }
    @Override
    public void onStatusChanged(String s, int i, Bundle bundle) {
    }
    @Override
    public void onProviderEnabled(String s) {
    }
    @Override
    public void onProviderDisabled(String s) {
    }
};

Android Developer Newsletter

Do you want to know more? Subscribe to our Android Developer Newsletter. Just type in your email address below to get all the top developer news, tips & links once a week in your inbox:


PS. No spam, ever. Your email address will only ever be used for Android Dev Weekly.

Conclusion

The complete source code is available on github, for use (or misuse) as you see fit. Just be mindful of the following:

  • Integrating location tracking in your apps drains the battery.
  • Google recommends apps request updates every 5 minutes (5 * 60 * 1000 milliseconds). You might need faster updates if your app is in the foreground (fitness/distance tracker).
  • Users can have location turned off. You should have a plan for when location settings is turned off.

Have fun building Android apps, and watch out for our upcoming tutorial where we make use of Android device location data and web APIs to build something even more fun and challenging.

Writing your first Android game using the Corona SDK

Posted by wicked July - 13 - 2015 - Monday Comments Off

The most popular category on the Google Play Store has always been Games. Although we all probably use key productivity apps like a web browser, an email client, and an instant messaging app, gaming still remains an important part of the mobile experience. So it is no surprise that many people who want to learn to develop for Android want to start by making a game. Also, let’s be honest, writing a game is a whole load more fun than developing a productivity app!

The official language of Android is Java and the official development environment is Android Studio. If you want to look into Java then I suggest our Java basics tutorial, and if you want to learn how to write an app using Android Studio then I suggest you check out our tutorial on writing your first Android app. However Java and Android studio aren’t the only ways to develop for Android. You can find an overview of the available languages and SDKs in our guide: I want to develop Android Apps – What languages should I learn?

corona-sim

One of the SDKs mentioned in the programming languages guide is Corona, a third party SDK designed primarily for writing games. Instead of Java, Corona uses Lua, a fast scripting language that is easy to learn yet powerful. However, Corona isn’t the only mobile gaming SDK that uses Lua, other well known examples include Cocos2d-XMarmalade, and Gideros.

Download and install

To get started with Corona you are going to need to download and install the SDK. Go to the Corona website and hit the download button. You will need to create an account (which is free) before you can download the kit. If you want to build an actual .apk file rather than just running your program in the emulator, you will need to install Java 7, however you won’t need to install the Android SDK. To install the Java 7 Development Kit go to Oracle’s website, look for the section called “Java SE Development Kit 7u79″ and download the version for your PC.

Once you have installed Corona you need to activate it. This is a one-time process, which is free. Start the Corona Simulator and agree to the license. Enter in the email address and password which you used for the download, and click Login.

Starting the project

From within the Corona Simulator click on “New Project.” Enter a name for your app in the “Application Name:” field and leave the rest of the settings at their defaults. Click “OK.”

corona-sim-new-project2

Three windows will now appear. The first two are the Corona Simulator and the Corona Simular Output. Corona will also open a file explorer window showing the files for your project.

The majority of the files (some 23 of them) in the project directory are for the application icon! The most important file for us right now is main.lua, as this is where we will write the code for our app.

Introduction to Lua

Before we get into writing the code, we need to make a whistle-stop tour of Lua. The Lua interpreter  (remember this is a scripting language, not a compiled language) is available for Windows, OS X, and Linux. However it is built-in to Corona, so at this time you don’t need to install anything extra. The easiest way to play with Lua is to use the online live demo.

You can find lots of good tutorials about Lua online and you should take a look at the Lua Reference ManualProgramming in LuaThe.Lua.Tutorial, and The Tutorials Point Lua Tutorial.

Here is a small Lua program which will show you some of the key features of Lua:

local function doubleIt(x)
    return x * 2
end

for i=1,10,1 do
    x = doubleIt(i)
    if(x == 10) then
        print("ten")
    else
        print(doubleIt(i))
    end
end

The code above shows three important Lua constructs: functions, loops, and if statements. The function doubleIt() is very simple, it just doubles the passed in parameter x.

The main code is a for loop from 1 to 10. It calls doubleIt() for each iteration. If the return value is 10 (i.e. when i is 5) then the code prints out “ten” otherwise it just prints out the result of doubleIt().

lua-online-live-demo-zoomed-16-9

If you have any coding experience then the example code should be easy enough to follow. If you are looking to learn some basic programming then I suggest you use some of the resources linked above to hone you skills.

Writing the game

Writing basic programs in Corona is simple. You only need concern yourself with one file, main.lua, and let Corona do all the heavy lifting. The game we are going to write is a simple “tap” game. A balloon or a bomb will fail down the screen. If the player taps on the balloon they score a point, they tap on a bomb then the score will divided by 2, as a penalty. To write the code you need to edit main.lua. You can do this in any text editor.

The Corona SDK has a built-in 2D physics engine, which makes building games very easy. The first step in writing the game is to initialize the physics engine:

local physics = require( "physics" )
physics.start()

The code is fairly self-explanatory. The module physics is loaded and initialized, it is assigned to the variable physics. To enable the engine physics.start() is called.

Next we create some helpful variables which will be useful not only for this simple game, but also for more complex games. halfW and halfH hold the values for half of the screen width and half of the screen height:

halfW = display.contentWidth*0.5
halfH = display.contentHeight*0.5

The display object is a pre-defined object which Corona makes globally available.

Now comes the first step that actually makes something happen on screen:

local bkg = display.newImage( "night_sky.png", halfW, halfH )

As well as properties like contentHeight and contentWidth, the display object also has lots of useful functions. The newImage() function reads an image file (in this case a .png) and displays it on the screen. Display objects are rendered in layers, so since this is the first image we are putting on the screen then it will always be the background (unless the code explicitly does something to change that). The parameters halfW and halfH tell Corona to place the image in the middle.

At this point you can run the code in the emulator and see the background image.  If you save the file then the emulator will notice that the file has changed and offer to relaunch. If that doesn’t happen then use File->Relaunch.

Since the user will score points for tapping on balloons, we need to initialize a score variable and display the score on the screen:

score = 0
scoreText = display.newText(score, halfW, 10)

The score will be kept in the imaginatively named variable score, and scoreText is the object which displays the score. Like newImage(), newText() put something on the screen, in this case text. Since scoreText is a global variable then we can change the text at any point. But we will get to that soon.

You can relaunch the emulator and see the score of 0 display towards the top of the screen.

Left: Just the background. Right: Background and score.

Left: Just the background. Right: Background and score.

Now comes something a bit more tricky, but don’t worry I will explain it line by line:

local function balloonTouched(event)
    if ( event.phase == "began" ) then
Runtime:removeEventListener( "enterFrame", event.self )
        event.target:removeSelf()
score = score + 1
scoreText.text = score
    end
end

The code above defines a function called balloonTouched() which will be called every time a balloon is tapped. We haven’t yet told Corona to call this function every time the balloon is tapped, that will come later, but when we do this is the function that gets called.

Tap or touch events have several stages, many to support dragging. The user puts their finger on an object, this is the “began” phase. If they slide their finger in any direction, that is the “moved” phase. When the user lifts their finger from the screen, that is the “ended” phase.

The first line of balloonTouched() checks we are in the “began” phase. We want to remove the balloon and increment the score as soon as posible. If the function is called again for other phases like “ended” then the function does nothing.

Inside the if statement are four lines of code. Let’s deal with the last two first, as they are simpler. score = score + 1 just increments the score by one and scoreText.text = score changes the score text on the screen to reflect the new score. Remember how I said that scoreText was global and could be accessed anywhere, well that is what we do here.

Now for the first two lines. Once a balloon or bomb falls of the bottom of the screen it still exists in the app’s memory, it is just that you can’t see it. As the game progresses the number of these off-screen objects will steadily increase. Therefore we need to have a mechanism which deletes objects once they are out of sight. We do that in a function called offscreen, which we haven’t written yet. That function will be called once per frame during the game. Once a balloon has been tapped then we need to delete it and remove the call that checks if the balloon has gone offscreen.

The line event.target:removeSelf() deletes the balloon. When a touch event occurs one of the parameters of the listener function is the event parameter. It tells the function about the event and what type of event it is, e.g. event.phase. It also tells us which balloon was tapped, event.target. The removeSelf() function does what it says it does, it deletes the object (in this case a balloon).

The line before that removes the “enterframe” listener, which is the function that is called every frame to see if the balloon has fallen off the bottom of the screen. We will look at that in more detail when we come to write the offscreen listener function.

So, to recap. balloonTouched() checks that this is the beginning of the touch sequence. It then removes the “enterframe” listener, which is the function that is called every frame to see if the balloon has fallen off the bottom of the screen. It then deletes the balloon, increments the score and displays the new score.

That was for balloons, now we need something similar for bombs:

local function bombTouched(event)
    if ( event.phase == "began" ) then
        Runtime:removeEventListener( "enterFrame", event.self )
        event.target:removeSelf()
        score = math.floor(score * 0.5)
        scoreText.text = score
    end
end

As you can see the code is very similar with the exception that rather than incrementing the score, the score is multiplied by 0.5 (i.e. divided by 2). The math.floor() function rounds down the score to the nearest integer. So if the player had a score of 3 and tapped a bomb then the new score would be 1, and not 1.5.

I mentioned the offscreen() function earlier. This function will be called every frame to check if an object has gone off screen. Here is the code:

local function offscreen(self, event)
if(self.y == nil) then
return
end
if(self.y > display.contentHeight + 50) then
Runtime:removeEventListener( "enterFrame", self )
self:removeSelf()
end
end

In computing there is a situation known as a race condition. This is where two things are going to happen but one might happen first, or sometimes the other might happen first. It is a race. Some race conditions are unseen because one thing always seems to happen first, but they can cause interesting bugs in that one day, under the right conditions, the other thing happens first and then the system breaks!

There is a race condition in this simple game because two things can happen very close to each other: a balloon being tapped and the offscreen() function being called to see if the balloon has gone off the screen. The result is that the code to delete the balloon can be called and then the offscreen() function is called (which happens like 30 times per second). To get around this odd sequence of events the offscreen() function needs to check if the y value of the object is nil (null) or not. If it is nil then it means that the object has been deleted already, so move along, these aren’t the droids we are looking for.

If the object is still in play, then check its position, if it has gone 50 pixels off the screen then delete it and remove the listener so that the offscreen() function won’t be called again for this object. The code to make sure that offscreen() is called every frame is part of the next section of code.

The whole premise of this game is that new balloons or bombs will continue to drop down the screen. Therefore we need a function which will create either a new balloon or a new bomb:

local function addNewBalloonOrBomb()
local startX = math.random(display.contentWidth*0.1,display.contentWidth*0.9)
if(math.random(1,5)==1) then
-- BOMB!
local bomb = display.newImage( "bomb.png", startX, -300)
physics.addBody( bomb )
bomb.enterFrame = offscreen
Runtime:addEventListener( "enterFrame", bomb )
bomb:addEventListener( "touch", bombTouched )
else
-- Balloon
local balloon = display.newImage( "red_balloon.png", startX, -300)
physics.addBody( balloon )
balloon.enterFrame = offscreen
Runtime:addEventListener( "enterFrame", balloon )
balloon:addEventListener( "touch", balloonTouched )
end
end

The first line of the function decides where the balloon will drop from on the x plane.  If the balloon or bomb always dropped in the middle, that won’t be very interesting! So startX is a random number between 10 percent and 90 percent of the screen width.

Next a random number is picked between 1 and 5. If the number is 1 then a bomb will be dropped. If it 2, 3, 4 or 5 then a balloon will be dropped. This means that bombs will be dropped around 20 percent of the time.

The bomb and balloon code are quite similar. First the image (either a bomb or a balloon) is displayed using newImage(). Its x position is that of startX while its y position is set to -300, i.e. off the top of the screen. The reason for that is that we want the object to fall from outside the screen area into the visible area and then off the bottom. Since we are using the 2D physics engine it is good to give the object a bit of an initial distance to fall, so it can gain some speed.

The call to physics.addBody() takes the image loaded by newImage() and turns it into an object in the physics engine. This is very powerful. Any image file can be made into a body which responds to gravity and collisions just by calling physics.addBody().

The last three lines of the bomb or balloon code set up the listeners. Setting the enterFrame property tells Corona which function to call every frame and the call to Runtime:addEventListener() sets it up. Lastly the call to balloon:addEventListener() tells Corona which function to call if the bomb or balloon is touched.

And now the game is almost complete. We just need two more lines of code:

addNewBalloonOrBomb()
timer.performWithDelay( 500, addNewBalloonOrBomb, 0 )

The first line makes the very first bomb or balloon fall by explicitly calling addNewBalloonOrBomb(). The second line sets up a timer which will call addNewBalloonOrBomb() every half a second (500 milliseconds). This means that a new balloon or bomb will fall every half a second.

corona-sim-balloon-or-bomb-2-shots

You can now run the game in the emulator.

Here is the complete listing for main.lua, the full project source code for this game can be found here on GitHub.

-----------------------------------------------------------------------------------------
--
-- Falling balloon and bomb game
-- Written by Gary Sims for Android Authority
--
-----------------------------------------------------------------------------------------

-- Start the physics engine
local physics = require( "physics" )
physics.start()

-- Calculate half the screen width and height
halfW = display.contentWidth*0.5
halfH = display.contentHeight*0.5

-- Set the background
local bkg = display.newImage( "night_sky.png", halfW, halfH )

-- Score
score = 0
scoreText = display.newText(score, halfW, 10)

-- Called when the balloon is tapped by the player
-- Increase score by 1
local function balloonTouched(event)
    if ( event.phase == "began" ) then
        Runtime:removeEventListener( "enterFrame", event.self )
        event.target:removeSelf()
        score = score + 1
        scoreText.text = score
    end
end

-- Called when the bomb is tapped by the player
-- Half the score as a penalty
local function bombTouched(event)
    if ( event.phase == "began" ) then
        Runtime:removeEventListener( "enterFrame", event.self )
        event.target:removeSelf()
        score = math.floor(score * 0.5)
        scoreText.text = score
    end
end

-- Delete objects which has fallen off the bottom of the screen
local function offscreen(self, event)
    if(self.y == nil) then
        return
    end
    if(self.y > display.contentHeight + 50) then
        Runtime:removeEventListener( "enterFrame", self )
        self:removeSelf()
    end
end

-- Add a new falling balloon or bomb
local function addNewBalloonOrBomb()
    -- You can find red_ballon.png and bomb.png in the GitHub repo
    local startX = math.random(display.contentWidth*0.1,display.contentWidth*0.9)
    if(math.random(1,5)==1) then
        -- BOMB!
        local bomb = display.newImage( "bomb.png", startX, -300)
        physics.addBody( bomb )
        bomb.enterFrame = offscreen
        Runtime:addEventListener( "enterFrame", bomb )
        bomb:addEventListener( "touch", bombTouched )
    else
        -- Balloon
        local balloon = display.newImage( "red_balloon.png", startX, -300)
        physics.addBody( balloon )
        balloon.enterFrame = offscreen
        Runtime:addEventListener( "enterFrame", balloon )
        balloon:addEventListener( "touch", balloonTouched )
    end
end

-- Add a new balloon or bomb now
addNewBalloonOrBomb()

-- Keep adding a new balloon or bomb every 0.5 seconds
timer.performWithDelay( 500, addNewBalloonOrBomb, 0 )

Next steps

The next step is to play the game on a real Android device. To build an .apk file click on File->Build for Android… and fill out the fields. The result will be a .apk file which you can copy onto your device and then install. You will need to ensure that you have configured your device to allow installation of app from unknown sources. Amazon has some good documentation on this as you also need to set this to install the Amazon Appstore. Corona also has a guide on how to sign, build, and test your app on Android devices.

balloon-or-bomb-in-hand

With the game successfully installed on your device the next thing to do is improve the game. For example, why not try adding a “pop” or “bang” sound everything a balloon or bomb is tapped. Corona has an API for that: media.playEventSound().

Or why not trying adding a third type of object, say a super boost which doubles the current score, or how about some background music?

Wrap-up

Writing games with Corona is quite straight forward because the SDK handles things like OpenGL and it includes a built-in 2D physics engine. Also Lua is easy to learn and shouldn’t be hard for anyone with even the minimum of programming experience. The Coronalabs website has lots of documentation including lots of guides and tutorials.

In less than 100 lines of code we have a working game. OK, it isn’t going to win any prizes, however it shows the power and flexibility of the Corona SDK.

Deal: Learn to build apps with the Infinite Skills Android Developer Course for 80% off

Posted by wicked July - 10 - 2015 - Friday Comments Off

b73432ba7403033f4283be25a046a556eff7594d_main_hero_image

Building Android applications can be one of the most rewarding and fun ways to make money, but how do you get started? If you’d like to start your career as a developer and want to build apps for millions of users, we’d suggest trying out the Infinite Skills Android Developer Course, which is currently 80% off in the AA Deals Store.

With over 105 lectures and 9.5 hours of content, this developer course requires no programming knowledge whatsoever. You’ll learn about media playback, device camera access, device sensors and much more, which many development courses often don’t explain to new learners. With this course, you can also work alongside and interact with the instructor to maximize your learnings, making it easy to ask questions and get feedback on the work you’re doing.

It really couldn’t be any easier to jumpstart your career! If you’re interested, the Infinite Skills Android Developer Course is being offered for only $19 in the Android Authority Deals Store. That’s a massive 80% off the suggested retail price. Interested? Be sure to head to the link below for more information.

Get this deal now

How to use the Android Keystore to store passwords and other sensitive information

Posted by wicked July - 10 - 2015 - Friday Comments Off

DataEncryptionLockedA few months ago, Godfrey Nolan wrote an excellent article discussing how an Android app developer can store user passwords and sensitive/personal information. The Android keystore provides a secure system level credential storage. With the keystore, an app can create a new Private/Public key pair, and use this to encrypt application secrets before saving it in the private storage folders. In this article, we are going to show how to use the Android Keystore to create and delete keys, and how to use these keys to encrypt and decrypt user supplied text.

Preparation

Before we begin coding, it is helpful to understand a bit about the Android Keystore, and it’s capabilities. The Keystore is not used directly for storing application secrets such as password, however, it provides a secure container, which can be used by apps to store their private keys, in a way that’s pretty difficult for malicious (unauthorised) users and apps to retrieve.

As its name suggests, an app can store multiple keys in the Keystore, but an app can only view, and query, its own keys. Ideally, with the keystore, an app would generate/or receive a private/public key pair, which would be stored in the keystore. The public key can then be used to encrypt application secrets, before being stored in the app specific folders, with the private key used to decrypt the same information when needed.

Although the Android Keystore provider was introduced in API level 18 (Android 4.3), the Keystore itself has been available since API 1, restricted to use by VPN and WiFi systems.

The Keystore itself is encrypted using the user’s own lockscreen pin/password, hence, when the device screen is locked the Keystore is unavailable. Keep this in mind if you have a background service that could need to access your application secrets.

Layout

The main layout for our sample app is a ListView, with items made up of a list of all the keys (actually the key aliases/names) created by the app. This is saved as layout/activity_main.xml.

<ListView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/listView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true"
    tools:context="com.sample.foo.simplekeystoreapp.MainActivity">

</ListView>

Each item on the list contains a TextView representing the key alias, a button to delete the key, and buttons each to encrypt and decrypt text. This layout/list_item.xml in our project.
aa_keystore_list_item

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/cardBackground"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    card_view:cardCornerRadius="4dp"
    android:layout_margin="5dp">

    <TextView
        android:id="@+id/keyAlias"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_vertical"
        android:textSize="30dp"/>

    <Button
        android:id="@+id/deleteButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/keyAlias"
        android:layout_alignParentLeft="true"
        android:layout_centerHorizontal="true"
        android:text="@string/delete"
        style="@style/Base.Widget.AppCompat.Button.Borderless" />

    <Button
        android:id="@+id/encryptButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/keyAlias"
        android:layout_alignRight="@+id/keyAlias"
        android:text="@string/encrypt"
        style="@style/Base.Widget.AppCompat.Button.Borderless"/>

    <Button
        android:id="@+id/decryptButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/keyAlias"
        android:layout_toLeftOf="@+id/encryptButton"
        android:text="@string/decrypt"
        style="@style/Base.Widget.AppCompat.Button.Borderless"/>

</RelativeLayout>

List Header

The List header is added to the ListView using the method

View listHeader = View.inflate(this, R.layout.activity_main_header, null);
listView.addHeaderView(listHeader);

aa_keystore_layout
In the image above, the ListView is currently empty, so only the List header is visible. The List Header is pretty straightforward, with an EditText at the top, which expects a string to be used as an alias when creating a key. A button to generate new keys lies immediately below this. The button is followed by three EditTexts, one expecting a string input to be encrypted, another displays the result of the encryption, and the third shows the decrypted string (for a successful decryption). This file is saved in layout/activity_main_header.xml.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center_horizontal"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin">

    <EditText
        android:id="@+id/aliasText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:hint="@string/key_alias"/>

    <Button
        android:id="@+id/generateKeyPair"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/aliasText"
        android:layout_centerHorizontal="true"
        android:layout_alignParentRight="true"
        android:text="@string/generate"
        android:onClick="createNewKeys" />

    <EditText
        android:id="@+id/startText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/generateKeyPair"
        android:layout_centerHorizontal="true"
        android:hint="@string/initial_text"/>

    <EditText
        android:id="@+id/encryptedText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/startText"
        android:layout_centerHorizontal="true"
        android:editable="false"
        android:textIsSelectable="true"
        android:hint="@string/final_text"/>

    <EditText
        android:id="@+id/decryptedText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/encryptedText"
        android:layout_centerHorizontal="true"
        android:editable="false"
        android:textIsSelectable="true"
        android:hint="@string/decrypt_result"/>
</RelativeLayout>

MainActivity

As with any Activity, we begin with the onCreate() method. The first thing we do is get a reference to the AndroidKeyStore, and then initialize it, using:

Keystore.getInstance("AndroidKeyStore");
keystore.load(null)

We then call our refreshKeys() method (discussed next) to list all the keys our app has stored in the Keystore. This ensures that any keys in the Keystore will be shown immediately when the ListView is initialized.

List all keys in the Keystore

aa_keystore_keys
To fetch an Enumeration of all keys available to an app in the keystore, simply call the aliases() method. In our refreshKeys() method below, we fetch the keystore aliases, and put the returned Strings into an ArrayList (used by our ListView’s Adapter).

    private void refreshKeys() {
        keyAliases = new ArrayList<>();
        try {
            Enumeration<String> aliases = keyStore.aliases();
            while (aliases.hasMoreElements()) {
                keyAliases.add(aliases.nextElement());
            }
        }
        catch(Exception e) {}

        if(listAdapter != null)
            listAdapter.notifyDataSetChanged();
    }

Add a new key to the Keystore

aa_keystore_new_key
Each key created by an app must have a unique alias, which can be any String. We use a KeyPairGeneratorSpec object to build the specifications of our required key. You can set the validity period of the key (setStartDate() and setEndDate()), set the alias and the subject (for self signed keys) among others. The subject must be an X500Principal object that resolves to a String of the form “CN=Common Name, O=Organization, C=Country”.

To generate a Public/Private keypair, we need a KeyPairGenerator object. We get an instance of KeyPairGenerator set to use the RSA algorithm with the “AndroidKeyStore”. Calling generateKeyPair() creates the new pair of keys (Private and corresponding Public key), and adds it to the Keystore.

    public void createNewKeys(View view) {
        String alias = aliasText.getText().toString();
        try {
            // Create new key if needed
            if (!keyStore.containsAlias(alias)) {
                Calendar start = Calendar.getInstance();
                Calendar end = Calendar.getInstance();
                end.add(Calendar.YEAR, 1);
                KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(this)
                        .setAlias(alias)
                        .setSubject(new X500Principal("CN=Sample Name, O=Android Authority"))
                        .setSerialNumber(BigInteger.ONE)
                        .setStartDate(start.getTime())
                        .setEndDate(end.getTime())
                        .build();
                KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore");
                generator.initialize(spec);

                KeyPair keyPair = generator.generateKeyPair();
            }
        } catch (Exception e) {
            Toast.makeText(this, "Exception " + e.getMessage() + " occured", Toast.LENGTH_LONG).show();
            Log.e(TAG, Log.getStackTraceString(e));
        }
        refreshKeys();
    }

Delete key from the Keystore

aa_keystore_delete
Deleting a key from the keystore is pretty straightforward. Armed with the key alias, call keystore.deleteEntry(keyAlias). There is no way to restore a deleted key, so you may want to be certain before using this.

    public void deleteKey(final String alias) {
        AlertDialog alertDialog =new AlertDialog.Builder(this)
                .setTitle("Delete Key")
                .setMessage("Do you want to delete the key \"" + alias + "\" from the keystore?")
                .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        try {
                            keyStore.deleteEntry(alias);
                            refreshKeys();
                        } catch (KeyStoreException e) {
                            Toast.makeText(MainActivity.this,
                                    "Exception " + e.getMessage() + " occured",
                                    Toast.LENGTH_LONG).show();
                            Log.e(TAG, Log.getStackTraceString(e));
                        }
                        dialog.dismiss();
                    }
                })
                .setNegativeButton("No", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                })
                .create();
        alertDialog.show();
    }

Encrypt block of text

aa_keystore_encrypt
Encrypting a block of text is performed with the Public key of the Key Pair. We retrieve the Public Key, request for a Cipher using our preferred encryption/decryption transformation (“RSA/ECB/PKCS1Padding”), then initialize the cipher to perform encryption (Cipher.ENCRYPT_MODE) using the retrieved Public Key. Cipher operates on (and returns) a byte []. We wrap the Cipher in a CipherOutputStream, along with a ByteArrayOutputStream to handle the encryption complexities. The result of the encryption process is then converted to a Base64 string for display.

    public void encryptString(String alias) {
        try {
            KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry)keyStore.getEntry(alias, null);
            RSAPublicKey publicKey = (RSAPublicKey) privateKeyEntry.getCertificate().getPublicKey();

            // Encrypt the text
            String initialText = startText.getText().toString();
            if(initialText.isEmpty()) {
                Toast.makeText(this, "Enter text in the 'Initial Text' widget", Toast.LENGTH_LONG).show();
                return;
            }

            Cipher input = Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidOpenSSL");
            input.init(Cipher.ENCRYPT_MODE, publicKey);

            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            CipherOutputStream cipherOutputStream = new CipherOutputStream(
                    outputStream, input);
            cipherOutputStream.write(initialText.getBytes("UTF-8"));
            cipherOutputStream.close();

            byte [] vals = outputStream.toByteArray();
            encryptedText.setText(Base64.encodeToString(vals, Base64.DEFAULT));
        } catch (Exception e) {
            Toast.makeText(this, "Exception " + e.getMessage() + " occured", Toast.LENGTH_LONG).show();
            Log.e(TAG, Log.getStackTraceString(e));
        }
    }

Decryption

Decryption is basically the Encryption process in reverse. Decryption is done using the Private Key of the key pair. We then initialize a Cipher with the same transformation algorithm used for encryption, but set to Cipher.DECRYPT_MODE. The Base64 string is decoded to a byte[], which is then placed in a ByteArrayInputStream. We then use a CipherInputStream to decrypt the data into a byte[]. This is then displayed as a String.

    public void decryptString(String alias) {
        try {
            KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry)keyStore.getEntry(alias, null);
            RSAPrivateKey privateKey = (RSAPrivateKey) privateKeyEntry.getPrivateKey();

            Cipher output = Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidOpenSSL");
            output.init(Cipher.DECRYPT_MODE, privateKey);

            String cipherText = encryptedText.getText().toString();
            CipherInputStream cipherInputStream = new CipherInputStream(
                    new ByteArrayInputStream(Base64.decode(cipherText, Base64.DEFAULT)), output);
            ArrayList<Byte> values = new ArrayList<>();
            int nextByte;
            while ((nextByte = cipherInputStream.read()) != -1) {
                values.add((byte)nextByte);
            }

            byte[] bytes = new byte[values.size()];
            for(int i = 0; i < bytes.length; i++) {
                bytes[i] = values.get(i).byteValue();
            }

            String finalText = new String(bytes, 0, bytes.length, "UTF-8");
            decryptedText.setText(finalText);

        } catch (Exception e) {
            Toast.makeText(this, "Exception " + e.getMessage() + " occured", Toast.LENGTH_LONG).show();
            Log.e(TAG, Log.getStackTraceString(e));
        }
    }

Android Developer Newsletter

Do you want to know more? Subscribe to our Android Developer Newsletter. Just type in your email address below to get all the top developer news, tips & links once a week in your inbox:


PS. No spam, ever. Your email address will only ever be used for Android Dev Weekly.

Round up

The Android Keystore makes creating and managing app keys a breeze, and provides a safe and relatively secure vault for applications to store encryption keys. Of course the Public key can also be sent to your server, and the server public key sent to your apps, to ensure secure communications between your application and your server. As usual, the complete source code is available on github for use as you please. For additions, corrections and/or discussions, leave a comment below, we are eager to hear from you.

Developer preview of Android M gets its first update

Posted by wicked July - 9 - 2015 - Thursday Comments Off

android M

We are getting closer and closer to Android M reaching the market with every update and today is the first update for the developer preview. The update includes the latest platform code, and near-final API’s for you to validate your app. They have also refined the Nexus system images and emulator system images with the Android platform updates. Plus it has Google Play services 7.6.

If you would like to try the update Google outlines how below. Also for a more detailed list of changes please see the Android Developer Blog.

How to Get the Update

If you are already running the M developer preview launched at Google I/O (Build #MPZ44Q) on a supported Nexus device (e.g. Nexus 5, Nexus 6, Nexus 9, or Nexus Player), the update can be delivered to your device via an over-the-air update. We expect all devices currently on the developer preview to receive the update over the next few days. We also posted a new version of the preview system image on the developer preview website. (To view the preview website in a language other than English, select the appropriate language from the language selector at the bottom of the page).

For those developers using the emulator, you can update your M preview system images via the SDK Manager in Android Studio.

Source: Android Developers

Come comment on this article: Developer preview of Android M gets its first update

ePad 7 Android 4.0 ICS
$162 $100 FREE SHIPPING 

10" Android 4.2 1.2GHz Tablet PC

7