Pages

Showing posts with label using. Show all posts
Showing posts with label using. Show all posts

Friday, May 13, 2016

Android Developers Backstage Episode 9 Design

Tor and Chet make a startling break with ancient tradition and talk to a real, live designer in this episode: Christian Robertson from the Android User Experience team. Tune in to hear about the Roboto font that Christian created and about font design in general, plus design tips for layout, visual rhythm, and other Android designities.

Design: Its the new Develop.

Relevant links:
Android Design: https://developer.android.com/design/index.html
Android Style Guide: http://developer.android.com/design/style/index.html
Android Asset Studio: http://romannurik.github.io/AndroidAssetStudio/
Roboto: http://www.google.com/fonts/specimen/Roboto

Christian: https://plus.google.com/110879635926653430880/posts
Tor: google.com/+TorNorbye
Chet: google.com/+ChetHaase

Subscribe to the podcast in your favorite player or at http://feeds.feedburner.com/blogspot/AndroidDevelopersBackstage
Or just download the mp3 directly: http://storage.googleapis.com/androiddevelopers/android_developers_backstage/Android%20Developers%20Backstage%20Ep9%20Design.mp3
Read More..

Monday, May 9, 2016

New in Android Samples Authenticating to remote servers using the Fingerprint API

Posted by Takeshi Hagikura, Yuichi Araki, Developer Programs Engineer

Originally posted on Google Android Developer blog

As we announced in the previous blog post, Android 6.0 Marshmallow is now publicly available to users. Along the way, we’ve been updating our samples collection to highlight exciting new features available to developers.

This week, we’re releasing AsymmetricFingerprintDialog, a new sample demonstrating how to securely integrate with compatible fingerprint readers (like Nexus Imprint) in a client/server environment.

Let’s take a closer look at how this sample works, and talk about how it complements the FingerprintDialog sample we released earlier during the public preview.

Symmetric vs Asymmetric Keys

The Android Fingerprint API protects user privacy by keeping users’ fingerprint features carefully contained within secure hardware on the device. This guards against malicious actors, ensuring that users can safely use their fingerprint, even in untrusted applications.

Android also provides protection for application developers, providing assurances that a user’s fingerprint has been positively identified before providing access to secure data or resources. This protects against tampered applications, providing cryptographic-level security for both offline data and online interactions.

When a user activates their fingerprint reader, they’re unlocking a hardware-backed cryptographic vault. As a developer, you can choose what type of key material is stored in that vault, depending on the needs of your application:

  • Symmetric keys: Similar to a password, symmetric keys allow encrypting local data. This is a good choice securing access to databases or offline files.
  • Asymmetric keys: Provides a key pair, comprised of a public key and a private key. The public key can be safely sent across the internet and stored on a remote server. The private key can later be used to sign data, such that the signature can be verified using the public key. Signed data cannot be tampered with, and positively identifies the original author of that data. In this way, asymmetric keys can be used for network login and authenticating online transactions. Similarly, the public key can be used to encrypt data, such that the data can only be decrypted with the private key.

This sample demonstrates how to use an asymmetric key, in the context of authenticating an online purchase. If you’re curious about using symmetric keys instead, take a look at the FingerprintDialog sample that was published earlier.

Here is a visual explanation of how the Android app, the user, and the backend fit together using the asymmetric key flow:

1. Setting Up: Creating an asymmetric keypair

First you need to create an asymmetric key pair as follows:

KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_EC, "AndroidKeyStore");
keyPairGenerator.initialize(
new KeyGenParameterSpec.Builder(KEY_NAME,
KeyProperties.PURPOSE_SIGN)
.setDigests(KeyProperties.DIGEST_SHA256)
.setAlgorithmParameterSpec(new ECGenParameterSpec("secp256r1"))
.setUserAuthenticationRequired(true)
.build());
keyPairGenerator.generateKeyPair();

Note that .setUserAuthenticationRequired(true) requires that the user authenticate with a registered fingerprint to authorize every use of the private key.

Then you can retrieve the created private and public keys with as follows:


KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
PublicKey publicKey =
keyStore.getCertificate(MainActivity.KEY_NAME).getPublicKey();

KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
PrivateKey key = (PrivateKey) keyStore.getKey(KEY_NAME, null);

2. Registering: Enrolling the public key with your server

Second, you need to transmit the public key to your backend so that in the future the backend can verify that transactions were authorized by the user (i.e. signed by the private key corresponding to this public key). This sample uses the fake backend implementation for reference, so it mimics the transmission of the public key, but in real life you need to transmit the public key over the network.

boolean enroll(String userId, String password, PublicKey publicKey);

3. Let’s Go: Signing transactions with a fingerprint

To allow the user to authenticate the transaction, e.g. to purchase an item, prompt the user to touch the fingerprint sensor.

Then start listening for a fingerprint as follows:

Signature.getInstance("SHA256withECDSA");
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
PrivateKey key = (PrivateKey) keyStore.getKey(KEY_NAME, null);
signature.initSign(key);
CryptoObject cryptObject = new FingerprintManager.CryptoObject(signature);

CancellationSignal cancellationSignal = new CancellationSignal();
FingerprintManager fingerprintManager =
context.getSystemService(FingerprintManager.class);
fingerprintManager.authenticate(cryptoObject, cancellationSignal, 0, this, null);

4. Finishing Up: Sending the data to your backend and verifying

After successful authentication, send the signed piece of data (in this sample, the contents of a purchase transaction) to the backend, like so:

Signature signature = cryptoObject.getSignature();
// Include a client nonce in the transaction so that the nonce is also signed
// by the private key and the backend can verify that the same nonce cant be used
// to prevent replay attacks.
Transaction transaction = new Transaction("user", 1, new SecureRandom().nextLong());
try {
signature.update(transaction.toByteArray());
byte[] sigBytes = signature.sign();
// Send the transaction and signedTransaction to the dummy backend
if (mStoreBackend.verify(transaction, sigBytes)) {
mActivity.onPurchased(sigBytes);
dismiss();
} else {
mActivity.onPurchaseFailed();
dismiss();
}
} catch (SignatureException e) {
throw new RuntimeException(e);
}

Last, verify the signed data in the backend using the public key enrolled in step 2:

@Override
public boolean verify(Transaction transaction, byte[] transactionSignature) {
try {
if (mReceivedTransactions.contains(transaction)) {
// It verifies the equality of the transaction including the client nonce
// So attackers cant do replay attacks.
return false;
}
mReceivedTransactions.add(transaction);
PublicKey publicKey = mPublicKeys.get(transaction.getUserId());
Signature verificationFunction = Signature.getInstance("SHA256withECDSA");
verificationFunction.initVerify(publicKey);
verificationFunction.update(transaction.toByteArray());
if (verificationFunction.verify(transactionSignature)) {
// Transaction is verified with the public key associated with the user
// Do some post purchase processing in the server
return true;
}
} catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException e) {
// In a real world, better to send some error message to the user
}
return false;
}

At this point, you can assume that the user is correctly authenticated with their fingerprints because as noted in step 1, user authentication is required before every use of the private key. Let’s do the post processing in the backend and tell the user that the transaction is successful!

Other updated samples

We also have a couple of Marshmallow-related updates to the Android For Work APIs this month for you to peruse:

  • AppRestrictionEnforcer and AppRestrictionSchemaThese samples were originally released when the App Restriction feature was introduced as a part of Android for Work API in Android 5.0 Lollipop. AppRestrictionEnforcer demonstrates how to set restriction to other apps as a profile owner. AppRestrictionSchema defines some restrictions that can be controlled by AppRestrictionEnforcer. This update shows how to use 2 additional restriction types introduced in Android 6.0.
  • We hope you enjoy the updated samples. If you have any questions regarding the samples, please visit us on our GitHub page and file issues or send us pull requests.

    Read More..

    Friday, May 6, 2016

    Install Android Studio on Ubuntu 15 10 using ubuntu developer tools center


    remark:
    ubuntu-developer-tools-center is now named Ubuntu Make officially.
    Please check the updated "Install Android Studio on 64-bit Ubuntu-GNOME 15.10 with Ubuntu Make".



    To install Android Studio on Ubuntu 15.10 using ubuntu-developer-tools-center
    - install java (refer "Install Oracle java8 on Ubuntu 15.10 via PPA")
    - Enter the command in Terminal:
    $ sudo apt-get install ubuntu-developer-tools-center
    $ udtc android

    This video show installing Android Studio on 64-bit Ubuntu 15.10 (run in VirtualBox) using ubuntu-developer-tools-center.

    Read More..

    Thursday, May 5, 2016

    Android example to create grouped sub OptionsMenu


    Create menu/activity_main.xml
    <?xml version="1.0" encoding="utf-8"?>
    <menu
    >
    <item
    android_id="@+id/option1"
    android_orderInCategory="100"
    app_showAsAction="ifRoom"
    android_title="Option 1"/>
    <item
    android_id="@+id/option2"
    android_orderInCategory="100"
    app_showAsAction="never"
    android_title="Option 2"/>
    <item
    android_id="@+id/option3"
    android_orderInCategory="100"
    app_showAsAction="never"
    android_title="Option 3...">
    <menu >
    <group android_id="@+id/group3"
    android_checkableBehavior="single">
    <item android_id="@+id/submenu3a"
    android_title="SubMenu 3A" />
    <item android_id="@+id/submenu3b"
    android_title="SubMenu 3B" />
    </group>
    </menu>

    </item>
    </menu>

    MainActivity.java
    package com.blogspot.android_er.androidoptionsmenu;

    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.widget.Toast;

    public class MainActivity extends AppCompatActivity {

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

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.activity_main, menu);
    return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
    switch(item.getItemId()){
    case R.id.option1:
    Toast.makeText(MainActivity.this, "Option 1", Toast.LENGTH_LONG).show();
    return true;
    case R.id.option2:
    Toast.makeText(MainActivity.this, "Option 2", Toast.LENGTH_LONG).show();
    return true;
    case R.id.submenu3a:
    Toast.makeText(MainActivity.this, "Option 3 A", Toast.LENGTH_LONG).show();
    return true;
    case R.id.submenu3b:
    Toast.makeText(MainActivity.this, "Option 3 B", Toast.LENGTH_LONG).show();
    return true;
    }
    return super.onOptionsItemSelected(item);
    }
    }



    Read More..

    Tuesday, May 3, 2016

    Android Studio Cookbook

    Design, test, and debug your apps using Android Studio

    Android Studio Cookbook

    About This Book
    • See what Material design is about and how to apply it your apps
    • Explore the possibilities to develop apps that works on any type of device
    • A step-by-step practical guide that will help you build improved applications, change their look, and debug them
    Who This Book Is For
    This book is for developers that are already familiar with programming concepts and have already started creating apps for the Android platform, for example, by using the Eclipse IDE. It is for developers who intend to use Android Studio as their primary IDE or want to use Android Studio more efficiently.

    What You Will Learn
    • Develop Android Studio applications using Genymotion
    • Apply the concepts of Material design to your applications
    • Use memory monitoring tools to tweak performance
    • Build applications for Android Wearable
    • Capture images, video, or audio within your Android app
    • Use content providers to display data
    • Build apps with a cloud-based backend
    • Create media-related apps that will run on phones, phablets, tablets, and TVs
    In Detail
    This book starts with an introduction of Android Studio and why you should use this IDE rather than Eclipse. Moving ahead, it teaches you to build a simple app that requires no backend setup but uses Google Cloud or Parse instead. After that, you will learn how to create an Android app that can send and receive text and images using Google Cloud or Parse as a backend. It explains the concepts of Material design and how to apply them to an Android app. Also, it shows you how to build an app that runs on an Android wear device.

    Later, it explains how to build an app that takes advantage of the latest Android SDK while still supporting older Android versions. It also demonstrates how the performance of an app can be improved and how memory management tools that come with the Android Studio IDE can help you achieve this.

    By the end of the book, you will be able to develop high quality apps with a minimum amount of effort using the Android Studio IDE.

    Style and approach
    This is a practical guide full of challenges and many real-world examples that demonstrate interesting development concepts. Besides smartphones and tablets, it also covers Android wearable devices and Android TV. Although strongly recommended, it is not necessary to own any Android device yourself.

    Read More..

    Friday, April 29, 2016

    Android popup messages using Toast

    In Android you can display pop up messages that lasts for a certain duration and then disappears-using the Toast class.

    Toast is a transient message that appears and disappears without any interaction from the user and with no notification to the program that it disappeared.

    the Toast can display a simple text message or a complex view.

    Displaying simple text:

    to display a simple toast that displays a text message we use the following code:
    Toast toast=Toast.makeText(this, "Hello toast", 2000);
    toast.setGravity(Gravity.TOP, -30, 50);
    toast.show();

    we create the toast using the static Toast.makeText(Context con,String message, int duration) method to create a toast in the current context to display a text message for a duration specified in milli seconds or we can use the constant values Toast.LENGTH_SHORT to display for a short duration or Toast.LENGTH_LONG for longer duration.
    The toast by default appears in the center of the screen, you can change the default position by specifying the Gravity and the X and Y offsets.
    finally we call the Show() method to display the toast.

    the previous toast will be like this:

    Displaying complex views:


    Toasts can also display complex views. this is done like this:

    First: create a layout xml file in res/layout directory. the file must be named toast_layout.xml.
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
    android_orientation="vertical"
    android_layout_width="fill_parent"
    android_layout_height="fill_parent"
    android_id="@+id/toastView"
    >
    <TextView
    android_layout_width="fill_parent"
    android_layout_height="wrap_content"
    android_text="Hello toast"
    android_textColor="#000"
    />
    <TextView
    android_layout_width="fill_parent"
    android_layout_height="wrap_content"
    android_id="@+id/txtDate"
    android_textColor="#000"
    />


    </LinearLayout>

    then from the code
    Toast toast=new Toast(this);
    LayoutInflater inflater=this.getLayoutInflater();
    View toastView=inflater.inflate(R.layout.toast_layout, (ViewGroup)findViewById(R.id.toastView));
    TextView txtDate=(TextView)toastView.findViewById(R.id.txtDate);
    txtDate.setText("toast appeared at "+Calendar.getInstance().getTime().toLocaleString());
    toast.setGravity(Gravity.CENTER, 0, 0);
    toast.setView(toastView);
    toast.show();

    the toast will be like this:
    Notes:
    • In the toast_layout.xml width, if you put any buttons or any control that has a callback, it would appear disabled and the user cannot interact with it.
    • The toast can be created in two ways: by calling Toast.makeText method or by specifyinga view via setView method. when you want to display a simple text use the first one otherwise use the second. if you try to interchange or combie between the two methods an exception will be thrown.
    Read More..

    Wednesday, April 27, 2016

    Android query current weather using OpenWeatherMaps Weather API


    OpenWeatherMaps weather API is simple, clear and free. This Android example show how access current weather data using OpenWeatherMaps weather API; for any location on Earth including over 200,000 cities! Current weather is frequently updated based on global models and data from more than 40,000 weather stations. Data is available in JSON, XML, or HTML format. This example use JSON.


    To access the API you need to sign up for an API key, this example use the demo API Key (appid in the query)

    MainActivity.java
    package com.blogspot.android_er.androidopenweathermap;

    import android.os.AsyncTask;
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.view.View;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.TextView;

    import org.json.JSONArray;
    import org.json.JSONException;
    import org.json.JSONObject;

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.UnsupportedEncodingException;
    import java.net.HttpURLConnection;
    import java.net.URL;
    import java.net.URLEncoder;

    public class MainActivity extends AppCompatActivity {

    EditText editTextCityName;
    Button btnByCityName;
    TextView textViewResult, textViewInfo;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    editTextCityName = (EditText)findViewById(R.id.cityname);
    btnByCityName = (Button)findViewById(R.id.bycityname);
    textViewResult = (TextView)findViewById(R.id.result);
    textViewInfo = (TextView)findViewById(R.id.info);

    btnByCityName.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
    new OpenWeatherMapTask(
    editTextCityName.getText().toString(),
    textViewResult).execute();
    }
    });
    }

    private class OpenWeatherMapTask extends AsyncTask<Void, Void, String> {

    String cityName;
    TextView tvResult;

    String dummyAppid = "bd82977b86bf27fb59a04b61b657fb6f";
    String queryWeather = "http://api.openweathermap.org/data/2.5/weather?q=";
    String queryDummyKey = "&appid=" + dummyAppid;

    OpenWeatherMapTask(String cityName, TextView tvResult){
    this.cityName = cityName;
    this.tvResult = tvResult;
    }

    @Override
    protected String doInBackground(Void... params) {
    String result = "";
    String queryReturn;

    String query = null;
    try {
    query = queryWeather + URLEncoder.encode(cityName, "UTF-8") + queryDummyKey;
    queryReturn = sendQuery(query);
    result += ParseJSON(queryReturn);
    } catch (UnsupportedEncodingException e) {
    e.printStackTrace();
    queryReturn = e.getMessage();
    } catch (IOException e) {
    e.printStackTrace();
    queryReturn = e.getMessage();
    }


    final String finalQueryReturn = query + " " + queryReturn;
    runOnUiThread(new Runnable() {
    @Override
    public void run() {
    textViewInfo.setText(finalQueryReturn);
    }
    });


    return result;
    }

    @Override
    protected void onPostExecute(String s) {
    tvResult.setText(s);
    }

    private String sendQuery(String query) throws IOException {
    String result = "";

    URL searchURL = new URL(query);

    HttpURLConnection httpURLConnection = (HttpURLConnection)searchURL.openConnection();
    if(httpURLConnection.getResponseCode() == HttpURLConnection.HTTP_OK){
    InputStreamReader inputStreamReader = new InputStreamReader(httpURLConnection.getInputStream());
    BufferedReader bufferedReader = new BufferedReader(
    inputStreamReader,
    8192);

    String line = null;
    while((line = bufferedReader.readLine()) != null){
    result += line;
    }

    bufferedReader.close();
    }

    return result;
    }

    private String ParseJSON(String json){
    String jsonResult = "";

    try {
    JSONObject JsonObject = new JSONObject(json);
    String cod = jsonHelperGetString(JsonObject, "cod");

    if(cod != null){
    if(cod.equals("200")){

    jsonResult += jsonHelperGetString(JsonObject, "name") + " ";
    JSONObject sys = jsonHelperGetJSONObject(JsonObject, "sys");
    if(sys != null){
    jsonResult += jsonHelperGetString(sys, "country") + " ";
    }
    jsonResult += " ";

    JSONObject coord = jsonHelperGetJSONObject(JsonObject, "coord");
    if(coord != null){
    String lon = jsonHelperGetString(coord, "lon");
    String lat = jsonHelperGetString(coord, "lat");
    jsonResult += "lon: " + lon + " ";
    jsonResult += "lat: " + lat + " ";
    }
    jsonResult += " ";

    JSONArray weather = jsonHelperGetJSONArray(JsonObject, "weather");
    if(weather != null){
    for(int i=0; i<weather.length(); i++){
    JSONObject thisWeather = weather.getJSONObject(i);
    jsonResult += "weather " + i + ": ";
    jsonResult += "id: " + jsonHelperGetString(thisWeather, "id") + " ";
    jsonResult += jsonHelperGetString(thisWeather, "main") + " ";
    jsonResult += jsonHelperGetString(thisWeather, "description") + " ";
    jsonResult += " ";
    }
    }

    JSONObject main = jsonHelperGetJSONObject(JsonObject, "main");
    if(main != null){
    jsonResult += "temp: " + jsonHelperGetString(main, "temp") + " ";
    jsonResult += "pressure: " + jsonHelperGetString(main, "pressure") + " ";
    jsonResult += "humidity: " + jsonHelperGetString(main, "humidity") + " ";
    jsonResult += "temp_min: " + jsonHelperGetString(main, "temp_min") + " ";
    jsonResult += "temp_max: " + jsonHelperGetString(main, "temp_max") + " ";
    jsonResult += "sea_level: " + jsonHelperGetString(main, "sea_level") + " ";
    jsonResult += "grnd_level: " + jsonHelperGetString(main, "grnd_level") + " ";
    jsonResult += " ";
    }

    jsonResult += "visibility: " + jsonHelperGetString(JsonObject, "visibility") + " ";
    jsonResult += " ";

    JSONObject wind = jsonHelperGetJSONObject(JsonObject, "wind");
    if(wind != null){
    jsonResult += "wind: ";
    jsonResult += "speed: " + jsonHelperGetString(wind, "speed") + " ";
    jsonResult += "deg: " + jsonHelperGetString(wind, "deg") + " ";
    jsonResult += " ";
    }

    //...incompleted

    }else if(cod.equals("404")){
    String message = jsonHelperGetString(JsonObject, "message");
    jsonResult += "cod 404: " + message;
    }
    }else{
    jsonResult += "cod == null ";
    }

    } catch (JSONException e) {
    e.printStackTrace();
    jsonResult += e.getMessage();
    }

    return jsonResult;
    }

    private String jsonHelperGetString(JSONObject obj, String k){
    String v = null;
    try {
    v = obj.getString(k);
    } catch (JSONException e) {
    e.printStackTrace();
    }

    return v;
    }

    private JSONObject jsonHelperGetJSONObject(JSONObject obj, String k){
    JSONObject o = null;

    try {
    o = obj.getJSONObject(k);
    } catch (JSONException e) {
    e.printStackTrace();
    }

    return o;
    }

    private JSONArray jsonHelperGetJSONArray(JSONObject obj, String k){
    JSONArray a = null;

    try {
    a = obj.getJSONArray(k);
    } catch (JSONException e) {
    e.printStackTrace();
    }

    return a;
    }
    }
    }


    layout/activity_main.xml
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout


    android_layout_width="match_parent"
    android_layout_height="match_parent"
    android_padding="16dp"
    android_orientation="vertical"
    tools_context=".MainActivity">

    <TextView
    android_layout_width="wrap_content"
    android_layout_height="wrap_content"
    android_layout_gravity="center_horizontal"
    android_autoLink="web"
    android_text="http://android-er.blogspot.com/"
    android_textStyle="bold" />

    <EditText
    android_id="@+id/cityname"
    android_layout_width="match_parent"
    android_layout_height="wrap_content"
    android_hint="City name"/>
    <Button
    android_id="@+id/bycityname"
    android_layout_width="match_parent"
    android_layout_height="wrap_content"
    android_text="Call current weather by city name"/>
    <LinearLayout
    android_layout_width="match_parent"
    android_layout_height="match_parent"
    android_orientation="horizontal">
    <ScrollView
    android_layout_width="0dp"
    android_layout_height="match_parent"
    android_layout_weight="1">
    <TextView
    android_id="@+id/result"
    android_layout_width="match_parent"
    android_layout_height="wrap_content"
    android_textSize="20dp"
    android_textStyle="bold"/>
    </ScrollView>
    <ScrollView
    android_layout_width="0dp"
    android_layout_height="match_parent"
    android_layout_weight="1">
    <TextView
    android_id="@+id/info"
    android_layout_width="match_parent"
    android_layout_height="wrap_content"
    android_textSize="18dp"
    android_textStyle="italic"/>
    </ScrollView>
    </LinearLayout>

    </LinearLayout>


    Permission of "android.permission.INTERNET" is needed in AndroidManifest.xml.
     <uses-permission android_name="android.permission.INTERNET"/>


    download filesDownload the files (Android Studio Format) .
    Read More..

    Tuesday, April 26, 2016

    Using Android SlidingDrawer

    Remeber Androids old versions (prior to 2.2) launcher screen where we had a sliding pane at the bottom that when dragged upwards displays the applications menu of the phone, that is called the SlidingDrawer control.


    consider this layout:
    <?xml version="1.0" encoding="utf-8"?>
    <FrameLayout

    android_layout_width="wrap_content"
    android_layout_height="wrap_content">
    <SlidingDrawer
    android_layout_width="fill_parent"
    android_layout_height="fill_parent"
    android_id="@+id/drawer"
    android_handle="@+id/handle"
    android_content="@+id/content"
    >
    <ImageView
    android_layout_width="wrap_content"
    android_layout_height="wrap_content"
    android_id="@+id/handle"
    android_src="@drawable/tray_handle_normal"
    />
    <LinearLayout
    android_layout_width="fill_parent"
    android_layout_height="fill_parent"
    android_orientation="vertical"
    android_id="@+id/content"
    >
    <TextView
    android_layout_width="wrap_content"
    android_layout_height="wrap_content"
    android_text="This is some text"
    android_id="@+id/txt"
    />
    <Button
    android_layout_width="wrap_content"
    android_layout_height="wrap_content"
    android_text="Click Me"
    android_id="@+id/btn"
    android_onClick="ClickHandler"
    />
    </LinearLayout>

    </SlidingDrawer>
    </FrameLayout>



    when the SlidingDrawer is pressed it looks like this:

    the SlidingDrawer is a container that when dragged or pressed shows/hides its contents.

    As the SlidingDrawer displays one content at a time, it must be declared within FrameLayout

    the SlidingDrawer has two key properties:
    android:handle: specifies the id of the control that acts as the handle.
    android:content: specifies the id of the view that acts as content of the SlidingDrawer, most times will be a container.

    you can open/close the drawer from the code like this:
    if(drawer.isOpened())
    {
    drawer.close();
    btnToggle.setText("Open");
    }
    else
    {
    drawer.open();
    btnToggle.setText("Close");
    }

    you can open/close the drawer with animation using these methods instead
    drawer.animateClose();
    drawer.animateOpen();

    or you can handle the open/close operations automatically using toggle method:
    drawer.toggle();
    drawer.animateToggle();

    you can lock/unlock the SlidingDrawer to enable/disable dragging or clicking of the drawer using these methods:
    drawer.lock();
    drawer.unlock();

    Responding to SlidingDrawer Events:

    SlidingDrawer has three key callbacks:
    1. when the drawer is open, handled by implementing OnDrawerOpenListener.
    2. when the drawer is close, handled by implementing OnDrawerCloseListener.
    3. when the drawer is close, handled by implementing OnDrawerScroll
      Listener.


    drawer.setOnDrawerOpenListener(new OnDrawerOpenListener() {

    @Override
    public void onDrawerOpened() {
    // TODO Auto-generated method stub
    TextView txtStatus=(TextView)findViewById(R.id.txtStatus);
    txtStatus.setText("Opened");
    ImageView view=(ImageView)drawer.getHandle();
    view.setImageResource(R.drawable.tray_handle_selected);

    }
    });



    drawer.setOnDrawerCloseListener(new OnDrawerCloseListener() {

    @Override
    public void onDrawerClosed() {
    // TODO Auto-generated method stub
    TextView txtStatus=(TextView)findViewById(R.id.txtStatus);
    txtStatus.setText("Closed");
    ImageView view=(ImageView)drawer.getHandle();
    view.setImageResource(R.drawable.tray_handle_normal);
    }
    });

    drawer.setOnDrawerScrollListener(new OnDrawerScrollListener() {

    @Override
    public void onScrollStarted() {
    // TODO Auto-generated method stub
    TextView txtStatus=(TextView)findViewById(R.id.txtStatus);
    txtStatus.setText("Scroll start");

    }

    @Override
    public void onScrollEnded() {
    // TODO Auto-generated method stub
    TextView txtStatus=(TextView)findViewById(R.id.txtStatus);
    txtStatus.setText("Scroll end");
    }
    });

    Notes:
    • you can make the drawer appear horizontally from right to left by setting the android:orientation property to horizontal in the xml file.
    • you can find images used as a source for the handler from this site: http://www.netmite.com/android/mydroid/1.0/packages/apps/Phone/res/drawable-finger/  I used tray_handle_normal.9.png and tray_handle_selected.9.png
    Read More..

    Thursday, April 21, 2016

    Using SQLite Database with Android

    Android default Database engine is Lite. SQLite is a lightweight transactional database engine that occupies small amout of disk storage and memory, so its a perfect choice for creating databases on many mobile operating systems such as Android, iOS.

    Things to consider when dealing with SQLite:
    1. Data type integrity is not maintained in SQLite, you can put a value of a certain data type in a column of another dataype (put string in an integer and vice versa).
    2. Referential integrity is not maintained in SQLite, there is no FOREIGN KEY constraints or JOIN statements.
    3. SQLite Full Unicode support is optional and not installed by default.

    In this tutorial we will create a simple database application to store employees data.

    the DB has:
    Tables:
    1. Employees
    2. Dept.
    Views:
    1. ViewEmps: to display employees and their relative departments.


    Creating SQLite Database

    By default SQLite on Android does not have a management interface or an application to create and manage data bases from, so were going to create the database ourselves by code.

    First we will create a class that handles all the operations required to deal with the database such as creating the database, creating tables, inserting and deleting records and so on.

    The first step is to create a class that inherits from SQLiteOpenHelper class. this class provides two methods to override to deal with the database:
    1. onCreate(SQLiteDatabase db): invoked when the database is created, this is where we can create tables and columns to them, create views or triggers.
    2. onUpgrade(SQLiteDatabse db, int oldVersion, int newVersion): invoked when we make a modification to the database such as altering, dropping , creating new tables.


    our class will have the following members
    public class DatabaseHelper extends SQLiteOpenHelper {

    static final String dbName="demoDB";
    static final String employeeTable="Employees";
    static final String colID="EmployeeID";
    static final String colName="EmployeeName";
    static final String colAge="Age";
    static final String colDept="Dept";

    static final String deptTable="Dept";
    static final String colDeptID="DeptID";
    static final String colDeptName="DeptName";

    static final String viewEmps="ViewEmps";

    The Constructor:
    public DatabaseHelper(Context context) {
    super(context, dbName, null,33);
    }

    The constructor of the super class has the following parameters:

    Context con: the context attached to the database.
    dataBaseName: the name of the database.
    CursorFactory: some times we may use a class that extends the Cursor class to implement some extra validations or operations on the queries run on the database. In this case we pass an instance of CusrsorFactory to return a reference to our derived class to be used instead of the default cursor,
    In this example we are going to use the standard Cursor Interface to retrieve results, so the CursorFactory parameter is going to be null.

    Version: the version of the schema of the database.

    The constructor creates a new blank database with the specified name and version.

    Creating the database:

    The first superclass method to override is onCreate(SQLiteDatabase db):
    public void onCreate(SQLiteDatabase db) {
    // TODO Auto-generated method stub

    db.execSQL("CREATE TABLE "+deptTable+" ("+colDeptID+ " INTEGER PRIMARY KEY , "+
    colDeptName+ " TEXT)");

    db.execSQL("CREATE TABLE "+employeeTable+" ("+colID+" INTEGER PRIMARY KEY AUTOINCREMENT, "+
    colName+" TEXT, "+colAge+" Integer, "+colDept+" INTEGER NOT NULL ,FOREIGN KEY ("+colDept+") REFERENCES "+deptTable+" ("+colDeptID+"));");


    db.execSQL("CREATE TRIGGER fk_empdept_deptid " +
    " BEFORE INSERT "+
    " ON "+employeeTable+

    " FOR EACH ROW BEGIN"+
    " SELECT CASE WHEN ((SELECT "+colDeptID+" FROM "+deptTable+" WHERE "+colDeptID+"=new."+colDept+" ) IS NULL)"+
    " THEN RAISE (ABORT,Foreign Key Violation) END;"+
    " END;");

    db.execSQL("CREATE VIEW "+viewEmps+
    " AS SELECT "+employeeTable+"."+colID+" AS _id,"+
    " "+employeeTable+"."+colName+","+
    " "+employeeTable+"."+colAge+","+
    " "+deptTable+"."+colDeptName+""+
    " FROM "+employeeTable+" JOIN "+deptTable+
    " ON "+employeeTable+"."+colDept+" ="+deptTable+"."+colDeptID
    );
    //Inserts pre-defined departments
    InsertDepts(db);

    }


    the method creates tables with columns,a view and a trigger.

    The method is invoked when the database is created. So we create our table and specify the columns.

    This method is invoked when the database does not exist on the disk, it’s executed only once on the same device at the first time the application is run on the device.

    Upgrading the database:

    some times we want to upgrade the database by changing the schema, add new tables or change column data types.
    this is done by overriding onUpdate(SQLiteDatabase db,int old Version,int newVerison) method:

    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    // TODO Auto-generated method stub

    db.execSQL("DROP TABLE IF EXISTS "+employeeTable);
    db.execSQL("DROP TABLE IF EXISTS "+deptTable);

    db.execSQL("DROP TRIGGER IF EXISTS dept_id_trigger");
    db.execSQL("DROP TRIGGER IF EXISTS dept_id_trigger22");
    db.execSQL("DROP TRIGGER IF EXISTS fk_empdept_deptid");
    db.execSQL("DROP VIEW IF EXISTS "+viewEmps);
    onCreate(db);
    }


    This method is invoked when the version number specified in the constructor of the class changes.

    when you want to append a change to your database you must change the version number in the constructor of the class:

    so when you pass the constructor a version number of 2:
    public DatabaseHelper(Context context) {
    super(context, dbName, null,2);

    // TODO Auto-generated constructor stub
    }
    instead of 1:
    super(context, dbName, null,2);
    the application understands that you want to upgrade the database and onUpgrade method will be invoked

    A typical implementation of this method is to drop the tables and create them again with the additional modifications.

    Managing Foreign-Key Constraints:

    we mentioned before that SQLite 3 by default does not support foreign key constraint, however we can force such a constraint using TRIGGERS:

    we will create a trigger that ensures that when a new Employee is inserted his/her Dept value is present in the original Dept table.

    the sql statement to create such a trigger would be like this:
    CREATE TRIGGER fk_empdept_deptid Before INSERT ON Employees 
    FOR EACH ROW BEGIN
    SELECT CASE WHEN ((SELECT DeptID FROM Dept WHERE DeptID =new.Dept ) IS NULL)
    THEN RAISE (ABORT,Foreign Key Violation) END;
    END

    in onCreate method we created this trigger like this:
    db.execSQL("CREATE TRIGGER fk_empdept_deptid " +
    " BEFORE INSERT "+
    " ON "+employeeTable+

    " FOR EACH ROW BEGIN"+
    " SELECT CASE WHEN ((SELECT "+colDeptID+" FROM "+deptTable+" WHERE "+colDeptID+"=new."+colDept+" ) IS NULL)"+
    " THEN RAISE (ABORT,Foreign Key Violation) END;"+
    " END;");


    Executing SQL statements:

    now lets begin executing basic sql statements. you can execute any sql statement that is not a query whether it is insert, delete, update or anything using db.execSQL(String statement) method like when we did when creating the database tables:
    db.execSQL("CREATE TABLE "+deptTable+" ("+colDeptID+ " INTEGER PRIMARY KEY , "+
    colDeptName+ " TEXT)");

    Inserting records:

    we insert records to the databse using the following code for example to insert records in the Dept table:
    SQLiteDatabase db=this.getWritableDatabase();
    ContentValues cv=new ContentValues();
    cv.put(colDeptID, 1);
    cv.put(colDeptName, "Sales");
    db.insert(deptTable, colDeptID, cv);

    cv.put(colDeptID, 2);
    cv.put(colDeptName, "IT");
    db.insert(deptTable, colDeptID, cv);
    db.close();

    notice that we need to call this.getWritableDatabase() to open the connection with the database for reading/writing.
    the ContentValues.put has two parameters: Column Name and the value to be inserted.

    also it is a good practice to close the database after executing statements.

    Updating values:

    to execute an update statement we have two ways

    1. to execute db.execSQL
    2. to execute db.update method:
    public int UpdateEmp(Employee emp)
    {
    SQLiteDatabase db=this.getWritableDatabase();
    ContentValues cv=new ContentValues();
    cv.put(colName, emp.getName());
    cv.put(colAge, emp.getAge());
    cv.put(colDept, emp.getDept());
    return db.update(employeeTable, cv, colID+"=?", new String []{String.valueOf(emp.getID())});

    }

    the update method has the following parameters:

    1. String Table: the table to update a value in
    2. ContentValues cv: the content values object that has the new values
    3. String where clause: the WHERE clause to specify which record to update.
    4. String[] args: the arguments of the WHERE clause.
    Deleteing rows:

    as in update to execute a delete statement we have two ways

    1. to execute db.execSQL
    2. to execute db.delete method:
    public void DeleteEmp(Employee emp)
    {
    SQLiteDatabase db=this.getWritableDatabase();
    db.delete(employeeTable,colID+"=?", new String [] {String.valueOf(emp.getID())});
    db.close();
    }

    the delete method has the same parameters as the update method.

    Executing queries:

    to execute queries there are two methods:

    1. Execute db.rawQuery method.
    2. Execute db.query method.

    to execute a raw query to retreive all departments
    Cursor getAllDepts()
    {
    SQLiteDatabase db=this.getReadableDatabase();
    Cursor cur=db.rawQuery("SELECT "+colDeptID+" as _id, "+colDeptName+" from "+deptTable,new String [] {});

    return cur;
    }

    the rawQuery method has two parameters:

    1. String query: the select statement.
    2. String[] selection args: the arguments if a WHERE clause is included in the select statement.

    Notes:
    1. The result of a query is returned in Cursor object.
    2. In a select statement if the primary key column (the id column) of the table has a name other than _id then you have to use an alias in the form SELECT [Column Name] as _id
    3. cause the Cursor object always expects that the primary key column has the name _id or it will throw an exception .


    another way to perform a query is to use a db.query method.

    a query to select all employees in a certain department from a view would be like this:
    public Cursor getEmpByDept(String Dept)
    {
    SQLiteDatabase db=this.getReadableDatabase();
    String [] columns=new String[]{"_id",colName,colAge,colDeptName};
    Cursor c=db.query(viewEmps, columns, colDeptName+"=?", new String[]{Dept}, null, null, null);
    return c;
    }

    the db.query has the folowing parameters:
    1. String Table Name: the name of the table to run the query against.
    2. String [ ] columns: the projection of the query i.e the columns to retrieve.
    3. String WHERE clause: where clause, if none pass null.
    4. String [ ] selection args: the parameters of the WHERE clause.
    5. String Group by: a string specifying group by clause.
    6. String Having: a string specifying HAVING clause.
    7. String Order By by: a string Order By by clause.
    Managing Cursors:

    Result sets of queries are returned in Cursor objects.
    there are some common methdos that you will use with cursors:
    1. boolean moveToNext(): moves the cursor by one record in the result set, returns false if moved past the last row in the result set.
    2. boolean moveToFirst(): moves the cursor to the first row in the result set, returns false if the result set is empty.
    3. boolean moveToPosition(int position): moves the cursor to a certain row index within the boolean result set, returns false if the position is un-reachable
    4. boolean moveToPrevious():moves the cursor to the preevious row in the result set, returns false if the cursor is past the first row.
    5. boolean moveToLast():moves the cursor to the lase row in the result set, returns false if the result set is empty.

    there are also some useful methods to check the position of a cursor:
    boolean isAfterLast(), isBeforeFirst, isFirst,isLast and isNull(columnIndex).


    also if you have a result set of only one row and you need to retreive values of certain columns, you can do it like this:
    public int GetDeptID(String Dept)
    {
    SQLiteDatabase db=this.getReadableDatabase();
    Cursor c=db.query(deptTable, new String[]{colDeptID+" as _id",colDeptName},colDeptName+"=?", new String[]{Dept}, null, null, null);
    //Cursor c=db.rawQuery("SELECT "+colDeptID+" as _id FROM "+deptTable+" WHERE "+colDeptName+"=?", new String []{Dept});
    c.moveToFirst();
    return c.getInt(c.getColumnIndex("_id"));

    }

    we have Cursor.getColumnIndex(String ColumnName) to get the index of a column.

    then to get the value of a certain column we have Cursor.getInt(int ColumnIndex) method.
    also there are getShort,getString,getDouble, getBlob to return the value as a byte array.

    its a good practice to close() the cursor after using it.

    Download a sample application on using database in Android from here
    Read More..

    Wednesday, April 20, 2016

    Android 6 Essentials

    Design, build, and create your own applications using the full range of features available in Android 6

    Android 6 Essentials

    About This Book
    • Learn how to utilize the robust features of Android 6 to design, develop, and publish better Android applications
    • Get useful guidance on creating new apps or migrating existing apps to support features such as app permissions, app links, fingerprint authentication, etc
    • A fast paced guide, packed with hands-on examples that ties all the features such as API, audio, video, camera, tab customization together under a single cover
    Who This Book Is For
    This book is for Android developers who are looking to move their applications into the next Android version with ease.

    What You Will Learn
    • Familiarize yourself with the features of Android 6
    • Code with the new Android permissions model
    • Use apps auto backup and restore lost data automatically
    • Increase user engagement with apps through an assistant using triggers and providing contextual assistance
    • Assess and handle proper usage of the API
    • Work with Audio, Video,Camera in Android 6
    • Utilize the new features in Android for professional purposes
    • Understand and code Chromes custom tabs
    In Detail
    Android 6 is the latest and greatest version of the Android operating system, and comes packed with cutting edge new features for you to harness for the benefit of building better applications.

    This step-by-step guide will take you through the basics of the Android Marshmallow permissions model and beyond into other crucial areas such as the Audio,Video,Camera API and Androids at work features. Learn how to create, deploy, and manage Android applications with Marshmallows API and the latest functionalities.

    The combination of instructions and real-world examples will make your application deployment and testing a breeze.

    Style and approach
    This easy-to-follow, step-by-step tutorial provides explanations and examples to add the new Android 6 features to your skill set. Each chapter provides sequential steps and detailed information about the API, as well as best practices and testing options.

    Read More..

    Using View Flipper in Android

    Suppose you want to display a news bar in your activity. this news bar displays a single news item at a time then flips and shows next item and so on, then your choice would be Androids ViewFlipper.

    ViewFlipper inherits from frame layout, so it displays a single view at a time.

    consider this layout:
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
    android_orientation="vertical"
    android_layout_width="fill_parent"
    android_layout_height="fill_parent"
    >
    <TextView
    android_layout_width="fill_parent"
    android_layout_height="wrap_content"
    android_text="@string/hello"
    />
    <Button
    android_layout_width="wrap_content"
    android_layout_height="wrap_content"
    android_text="Flip"
    android_id="@+id/btn"
    android_onClick="ClickHandler"
    />
    <ViewFlipper
    android_layout_width="fill_parent"
    android_layout_height="fill_parent"
    android_id="@+id/flip"
    >
    <TextView
    android_layout_width="fill_parent"
    android_layout_height="wrap_content"
    android_text="Item1"
    />
    <TextView
    android_layout_width="fill_parent"
    android_layout_height="wrap_content"
    android_text="Item2"
    />
    <TextView
    android_layout_width="fill_parent"
    android_layout_height="wrap_content"
    android_text="Item3"
    />
    </ViewFlipper>
    </LinearLayout>


    just a ViewFlipper container that contains three text views

    now we want to flip the views when the button is clicked
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    btn=(Button)findViewById(R.id.btn);
    flip=(ViewFlipper)findViewById(R.id.flip);

    }

    public void ClickHandler(View v)
    {

    flip.showNext();

    }

    if we want to flip in reverese direction we could use
    flip.showPrevious() instead

    we can add animations to the child views when they appear or disappear:
    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    btn=(Button)findViewById(R.id.btn);
    flip=(ViewFlipper)findViewById(R.id.flip);
    //when a view is displayed
    flip.setInAnimation(this,android.R.anim.fade_in);
    //when a view disappears
    flip.setOutAnimation(this, android.R.anim.fade_out);
    }

    we can also set the ViewFlipper to flip views automatically when the button is clicked:
    public void ClickHandler(View v)
    {


    //specify flipping interval
    flip.setFlipInterval(1000);
    flip.startFlipping();
    }

    we can stop the flipping by calling flip.stopFlipping(); method.

    or we can set the flipper to flip autommatically when the activity starts
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    btn=(Button)findViewById(R.id.btn);
    flip=(ViewFlipper)findViewById(R.id.flip);
    flip.setInAnimation(this,android.R.anim.fade_in);
    flip.setOutAnimation(this, android.R.anim.fade_out);
    flip.setFlipInterval(1000);
    flip.setAutoStart(true);

    }
    Read More..

    Sunday, April 17, 2016

    Create AVD using new Android Emulator in Android Studio 2 0 Preview


    New Android Emulator Preview is available now, you can create AVD using new Emulator in Android Studio 2.0 Preview.

    When I try it, dialog pop up with error message:
    emulator: ERROR: Couldnt find crash service executable
    C:UsersuserAppDataLocalAndroidsdk oolsemulator64-crash-service.exe
    ...
    I check my system, I have emulator-crash-service.exe, not emulator64-crash-service.exe! I dont know is it a bug, or anything wrong in my setting.

    updated@2015-12-13:
    Seem its a bug of the new emulator in Windows. Somebody reported this issue: https://code.google.com/p/android/issues/detail?id=196629


    Anyway, the emulator still can run and deploy my Hello World. This video show steps to create AVD using new Android Emulator in Android Studio 2.0 Preview; run on Windows 10 with CPU of Intel i5.


    Reference:
    - Android Developers Blog: Android Studio 2.0 Preview: Android Emulator
    - Android Tools Project Site: Android Emulator Preview (with system requirement and update SDK)


    Read More..

    Saturday, April 16, 2016

    Android Developers Backstage Episode 8 Volley



    In this episode, the second in a bizarrely and completely unplanned series on Play Store technology, Tor Norbye and Chet Haase are joined by Ficus Kirkpatrick from the Play Store team (and from many other Android projects from the early days). Listen in to hear what Volley is for and how you can use it to simplify your network requests and bitmap download/caching code.

    Relevant links:
    Volley: https://android.googlesource.com/platform/frameworks/volley/
    Volley email list: https://groups.google.com/forum/#!forum/volley-users
    Gson adapter for Volley: https://gist.github.com/ficusk/5474673

    Subscribe to the podcast at http://feeds.feedburner.com/blogspot/AndroidDevelopersBackstage?.
    Or download directly at http://storage.googleapis.com/androiddevelopers/android_developers_backstage/Android%20Developers%20Backstage%20Ep%208%20Volley.mp3
    Read More..

    Wednesday, April 6, 2016

    Android communicate with Arduino HC 06 Bluetooth Module part II

    Its my old post "Android example to communicate with Bluetooth device, HC-06 Bluetooth Module", to make a Android phone communicate with Arduino + HC-06 Bluetooth Module. In the example, the first byte always lost.

    After more test, I found that the first byte not lost. Because the byte stream sent from Arduino not in sync with Android side, and the bytes may be separated in different slot received in Android ThreadConnected, and the old slot covered by the new slot.

    To show it, I modify it not to clear the TextView.


    MainActivity.java
    /*
    Android Example to connect to and communicate with Bluetooth
    In this exercise, the target is a Arduino Due + HC-06 (Bluetooth Module)

    Ref:
    - Make BlueTooth connection between Android devices
    http://android-er.blogspot.com/2014/12/make-bluetooth-connection-between.html
    - Bluetooth communication between Android devices
    http://android-er.blogspot.com/2014/12/bluetooth-communication-between-android.html
    */
    package com.example.androidbtcontrol;

    import android.app.Activity;
    import android.bluetooth.BluetoothAdapter;
    import android.bluetooth.BluetoothDevice;
    import android.bluetooth.BluetoothSocket;
    import android.content.Intent;
    import android.content.pm.PackageManager;
    import android.os.Bundle;
    import android.support.v7.app.ActionBarActivity;
    import android.view.View;
    import android.widget.AdapterView;
    import android.widget.ArrayAdapter;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.LinearLayout;
    import android.widget.ListView;
    import android.widget.TextView;
    import android.widget.Toast;

    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.util.ArrayList;
    import java.util.Set;
    import java.util.UUID;

    public class MainActivity extends ActionBarActivity {

    private static final int REQUEST_ENABLE_BT = 1;

    BluetoothAdapter bluetoothAdapter;

    ArrayList<BluetoothDevice> pairedDeviceArrayList;

    TextView textInfo, textStatus, textByteCnt;
    ListView listViewPairedDevice;
    LinearLayout inputPane;
    EditText inputField;
    Button btnSend, btnClear;

    ArrayAdapter<BluetoothDevice> pairedDeviceAdapter;
    private UUID myUUID;
    private final String UUID_STRING_WELL_KNOWN_SPP =
    "00001101-0000-1000-8000-00805F9B34FB";

    ThreadConnectBTdevice myThreadConnectBTdevice;
    ThreadConnected myThreadConnected;

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

    textInfo = (TextView)findViewById(R.id.info);
    textStatus = (TextView)findViewById(R.id.status);
    textByteCnt = (TextView)findViewById(R.id.textbyteCnt);
    listViewPairedDevice = (ListView)findViewById(R.id.pairedlist);

    inputPane = (LinearLayout)findViewById(R.id.inputpane);
    inputField = (EditText)findViewById(R.id.input);
    btnSend = (Button)findViewById(R.id.send);
    btnSend.setOnClickListener(new View.OnClickListener(){

    @Override
    public void onClick(View v) {
    if(myThreadConnected!=null){
    byte[] bytesToSend = inputField.getText().toString().getBytes();
    myThreadConnected.write(bytesToSend);
    byte[] NewLine = " ".getBytes();
    myThreadConnected.write(NewLine);
    }
    }});

    btnClear = (Button)findViewById(R.id.clear);
    btnClear.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
    textStatus.setText("");
    textByteCnt.setText("");
    }
    });

    if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)){
    Toast.makeText(this,
    "FEATURE_BLUETOOTH NOT support",
    Toast.LENGTH_LONG).show();
    finish();
    return;
    }

    //using the well-known SPP UUID
    myUUID = UUID.fromString(UUID_STRING_WELL_KNOWN_SPP);

    bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    if (bluetoothAdapter == null) {
    Toast.makeText(this,
    "Bluetooth is not supported on this hardware platform",
    Toast.LENGTH_LONG).show();
    finish();
    return;
    }

    String stInfo = bluetoothAdapter.getName() + " " +
    bluetoothAdapter.getAddress();
    textInfo.setText(stInfo);
    }

    @Override
    protected void onStart() {
    super.onStart();

    //Turn ON BlueTooth if it is OFF
    if (!bluetoothAdapter.isEnabled()) {
    Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
    startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
    }

    setup();
    }

    private void setup() {
    Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices();
    if (pairedDevices.size() > 0) {
    pairedDeviceArrayList = new ArrayList<BluetoothDevice>();

    for (BluetoothDevice device : pairedDevices) {
    pairedDeviceArrayList.add(device);
    }

    pairedDeviceAdapter = new ArrayAdapter<BluetoothDevice>(this,
    android.R.layout.simple_list_item_1, pairedDeviceArrayList);
    listViewPairedDevice.setAdapter(pairedDeviceAdapter);

    listViewPairedDevice.setOnItemClickListener(new AdapterView.OnItemClickListener() {

    @Override
    public void onItemClick(AdapterView<?> parent, View view,
    int position, long id) {
    BluetoothDevice device =
    (BluetoothDevice) parent.getItemAtPosition(position);
    Toast.makeText(MainActivity.this,
    "Name: " + device.getName() + " "
    + "Address: " + device.getAddress() + " "
    + "BondState: " + device.getBondState() + " "
    + "BluetoothClass: " + device.getBluetoothClass() + " "
    + "Class: " + device.getClass(),
    Toast.LENGTH_LONG).show();

    textStatus.setText("start ThreadConnectBTdevice");
    myThreadConnectBTdevice = new ThreadConnectBTdevice(device);
    myThreadConnectBTdevice.start();
    }
    });
    }
    }

    @Override
    protected void onDestroy() {
    super.onDestroy();

    if(myThreadConnectBTdevice!=null){
    myThreadConnectBTdevice.cancel();
    }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if(requestCode==REQUEST_ENABLE_BT){
    if(resultCode == Activity.RESULT_OK){
    setup();
    }else{
    Toast.makeText(this,
    "BlueTooth NOT enabled",
    Toast.LENGTH_SHORT).show();
    finish();
    }
    }
    }

    //Called in ThreadConnectBTdevice once connect successed
    //to start ThreadConnected
    private void startThreadConnected(BluetoothSocket socket){

    myThreadConnected = new ThreadConnected(socket);
    myThreadConnected.start();
    }

    /*
    ThreadConnectBTdevice:
    Background Thread to handle BlueTooth connecting
    */
    private class ThreadConnectBTdevice extends Thread {

    private BluetoothSocket bluetoothSocket = null;
    private final BluetoothDevice bluetoothDevice;


    private ThreadConnectBTdevice(BluetoothDevice device) {
    bluetoothDevice = device;

    try {
    bluetoothSocket = device.createRfcommSocketToServiceRecord(myUUID);
    textStatus.setText("bluetoothSocket: " + bluetoothSocket);
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }

    @Override
    public void run() {
    boolean success = false;
    try {
    bluetoothSocket.connect();
    success = true;
    } catch (IOException e) {
    e.printStackTrace();

    final String eMessage = e.getMessage();
    runOnUiThread(new Runnable() {

    @Override
    public void run() {
    textStatus.setText("something wrong bluetoothSocket.connect(): " + eMessage);
    }
    });

    try {
    bluetoothSocket.close();
    } catch (IOException e1) {
    // TODO Auto-generated catch block
    e1.printStackTrace();
    }
    }

    if(success){
    //connect successful
    final String msgconnected = "connect successful: "
    + "BluetoothSocket: " + bluetoothSocket + " "
    + "BluetoothDevice: " + bluetoothDevice;

    runOnUiThread(new Runnable() {

    @Override
    public void run() {
    textStatus.setText("");
    textByteCnt.setText("");
    Toast.makeText(MainActivity.this, msgconnected, Toast.LENGTH_LONG).show();

    listViewPairedDevice.setVisibility(View.GONE);
    inputPane.setVisibility(View.VISIBLE);
    }
    });

    startThreadConnected(bluetoothSocket);

    }else{
    //fail
    }
    }

    public void cancel() {

    Toast.makeText(getApplicationContext(),
    "close bluetoothSocket",
    Toast.LENGTH_LONG).show();

    try {
    bluetoothSocket.close();
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }

    }

    }

    /*
    ThreadConnected:
    Background Thread to handle Bluetooth data communication
    after connected
    */
    private class ThreadConnected extends Thread {
    private final BluetoothSocket connectedBluetoothSocket;
    private final InputStream connectedInputStream;
    private final OutputStream connectedOutputStream;

    public ThreadConnected(BluetoothSocket socket) {
    connectedBluetoothSocket = socket;
    InputStream in = null;
    OutputStream out = null;

    try {
    in = socket.getInputStream();
    out = socket.getOutputStream();
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }

    connectedInputStream = in;
    connectedOutputStream = out;
    }

    @Override
    public void run() {
    byte[] buffer = new byte[1024];
    int bytes;

    String strRx = "";

    while (true) {
    try {
    bytes = connectedInputStream.read(buffer);
    final String strReceived = new String(buffer, 0, bytes);
    final String strByteCnt = String.valueOf(bytes) + " bytes received. ";

    runOnUiThread(new Runnable(){

    @Override
    public void run() {
    textStatus.append(strReceived);
    textByteCnt.append(strByteCnt);
    }});

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

    final String msgConnectionLost = "Connection lost: "
    + e.getMessage();
    runOnUiThread(new Runnable(){

    @Override
    public void run() {
    textStatus.setText(msgConnectionLost);
    }});
    }
    }
    }

    public void write(byte[] buffer) {
    try {
    connectedOutputStream.write(buffer);
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }

    public void cancel() {
    try {
    connectedBluetoothSocket.close();
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    }

    }


    layout/activity_main.xml
    <LinearLayout 

    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="horizontal"
    tools_context=".MainActivity">

    <LinearLayout
    android_layout_width="0dp"
    android_layout_height="match_parent"
    android_layout_weight="1"
    android_orientation="vertical">
    <TextView
    android_layout_width="wrap_content"
    android_layout_height="wrap_content"
    android_layout_gravity="center_horizontal"
    android_autoLink="web"
    android_text="http://android-er.blogspot.com/"
    android_textStyle="bold" />

    <TextView
    android_id="@+id/textbyteCnt"
    android_layout_width="wrap_content"
    android_layout_height="0dp"
    android_layout_weight="1"/>
    <TextView
    android_id="@+id/status"
    android_layout_width="wrap_content"
    android_layout_height="0dp"
    android_layout_weight="1"/>
    </LinearLayout>

    <LinearLayout
    android_layout_width="0dp"
    android_layout_height="match_parent"
    android_layout_weight="1"
    android_orientation="vertical">

    <TextView
    android_id="@+id/info"
    android_textStyle="bold|italic"
    android_layout_width="wrap_content"
    android_layout_height="wrap_content"/>
    <ListView
    android_id="@+id/pairedlist"
    android_layout_width="match_parent"
    android_layout_height="match_parent"/>

    <LinearLayout
    android_id="@+id/inputpane"
    android_layout_width="match_parent"
    android_layout_height="wrap_content"
    android_orientation="vertical"
    android_visibility="gone">

    <EditText
    android_id="@+id/input"
    android_layout_width="match_parent"
    android_layout_height="wrap_content"/>
    <Button
    android_id="@+id/send"
    android_layout_width="match_parent"
    android_layout_height="wrap_content"
    android_text="Sent"/>
    <Button
    android_id="@+id/clear"
    android_layout_width="match_parent"
    android_layout_height="wrap_content"
    android_text="Clear"/>

    </LinearLayout>

    </LinearLayout>

    </LinearLayout>


    Have to modify AndroidManifest.xml to uses-permission of "android.permission.BLUETOOTH". Refer the exmple "Android example to communicate with Bluetooth device, HC-06 Bluetooth Module".

    download filesDownload the files (Android Studio Format) .

    download filesDownload and try APK.


    For the Arduino side, refer to : Arduino-er - Connect Arduino Due with HC-06 (Bluetooth Module).


    This Android App can be used to talk with PC, with FTDI USB-to-Serial adapter connected to HC-06. Refer to the next post "Android Bluetooth connect PC (running Windows10) via HC-06 BT Module and FTDI US-to-Serial adapter".

    more:
    - Android Bluetooth Terminal to login Raspberry Pi + HC-06

    Read More..

    Friday, April 1, 2016

    Android Developers Backstage Episode 5 RenderScript

    Chet Haase and Tor Norbye are joined by Tim Murray from the RenderScript team.

    In this episode, we dive into RenderScript and talk about compute, parallel processing, GPUs, and architecture-independent, high-performance pixel processing. Its intrinsically interesting.

    To download the podcast click here.
    Read More..

    Wednesday, March 30, 2016

    Android Developers Backstage Episode 10 ART pART 1

    Tor and Chet may not know ART, but they know what they like. In this episode, the first in a two-pART series, they talk with Anwar Ghuloum from the ART, or Android Runtime team. ART is the new runtime for Android, which came online in the KitKat release as an alternative to Dalvik. Now ART is not only enabled by default: it’s the only runtime. We’ll talk about what it is, how it works, why it’s better, and the future and very meaning of ART in modern society.

    Subscribe to the podcast feed or download the audio file directly.

    ARTicles:
    Introducing ART: http://source.android.com/devices/tech/dalvik/art.html
    Verifying App Behavior: http://developer.android.com/guide/practices/verifying-apps-art.html

    Google I/O 2014 Session:
    The ART Runtime: https://www.youtube.com/watch?v=EBlTzQsUoOw

    Other Resources:
    Systrace: http://developer.android.com/tools/help/systrace.html

    Tor: google.com/+TorNorbye
    Chet: google.com/+ChetHaase
    Read More..

    Monday, March 28, 2016

    Using Android Preferences

    We saw before that we can persist an applications data using SQLite database. Android offers another way to store users data through using preferences.

    Android preferences is a key/value entries that store data that can be specific to a certain activity or shared among all activities within the application.
    the data are stored in a xml file.

    Saving Preferences

    We can save preferences in three ways:

    1. Preferences can be retrieved only by a single activity.
    2. Preferences can be shared and retrieved among all activities within the application.
    3. Preferences can be shared and retrieved through all applications on the device.
    Saving Activity-level preferences:
    to save preferences that are accessed only from a single activity, we do it like this:
    SharedPreferences prefs=getPreferences(Context.MODE_PRIVATE);
    SharedPreferences.Editor editor=prefs.edit();
    editor.putString("pref 1", "some text");

    editor.commit();

    we get a SharedPreferences object by calling getPreferences(int mode) method which takes an integer value as a parameter, the mode value can be one of the following:

    1. Context.MODE_PRIVATE (0): a file creating mode that makes the created file only accessible by applications with the same user ID (access the file from the same application context, will desctribe later).
    2. Context.MODE_WORLD_READABLE (1): file mode makes the file readable from other applications.
    3. Context.MODE_WORLD_WRITEABLE (2): file mode allows other applications to write to the file.
    then we get an instance of SharedPreferences.Editor and write the preference value with editor.putString(String key, String value) method.
    shared preferences allows you to insert preferences using the following methods:
    1. editor.putBoolean(String key, boolean value).
    2. editor.putFloat(String key,float value).
    3. editor.putInt(String key, int value).
    4. editor.putLong(String key, long value)
    5. editor.putString(String key, String value)
    then we call edit.commit() to save the preferences to the file. commit returns a boolean indicating the result of saving, true if successful and false if failed.

    Reading preferences values:
    To read preferences values:
    SharedPreferences prefs=getPreferences(Context.MODE_PRIVATE);
    String val=prefs.getString("pref 1", "some text");
    we use sharedpreferences.getString(String key, String defaultValue) (or get boolean/float/int) to return the value stored with a specific key or defaultValue if not found.

    Saving Application-level preferences:
    to save preferences that can be retrieved from all activities in the application we do it like this:
    SharedPreferences prefs= getSharedPreferences("demopref", Context.MODE_WORLD_READABLE);
    SharedPreferences.Editor editor=prefs.edit();
    editor.putString("demostring", "hello");
    editor.commit();

    same as the code above, but the difference is that we give our preferences file a name (demopref in this case) so that other activities can reference that preferences file.
    Sharing preferences across applications:


    We can store preferences in one application and read them in another application, this is done reading the preferences file by loading them through the first applications context.

    lets assume we have two applications:

    1. Application 1 with package name "com.mina.prefdemo".
    2. Application2 with package name "com.mina.demoapp".
    If application1 creates a preferences file with the name "demopref" and inserts a String preference with the key/value "demostring/hello".

    now we access this file and value from application 2 like this:
    Context con;
    try {
    con = createPackageContext("com.minasamy.prefdemo", 0);
    SharedPreferences pref=con.getSharedPreferences("demopref", Context.MODE_PRIVATE);
    String x=pref.getString("demostring", "not found");
    txt.setText(x);
    } catch (NameNotFoundException e) {
    Log.e(Tag, e.toString());
    }

    Creating Preferences Activities:
    android provides another nice way of presenting and saving preferences. you can create Activities that extend PreferenceActivity.
    PreferenceActivity is an activity that displays a set of built-in preferences related widgets that are defined in xml file.

    the preference activity can be divided to several PreferenceCategory each containing a set of related preferences.
    The preferences widgets that Android provide are:

    1. CheckBoxPreference: displays a check box widget.
    2. EditTextPreference: displays an EditText widget to save user prefs.
    3. RingtonePreference: displays a list with the  ringtones on the device.
    4. ListPreference: displays a list of key/value items.
    each one of these preferences widgets is associated with a preference key. its value is persisted instantly as the widget selection changes.

    we can construct our preferences screen xml (saved in res/xml directory) layout like this:
    <?xml version="1.0" encoding="utf-8"?>
    <PreferenceScreen
    >
    <PreferenceCategory
    android_title="Catogory one"
    android_summary="sample summary">
    <CheckBoxPreference
    android_title="Enable"
    android_key="pref_enable"
    android_summary="enables a preference"/>
    <EditTextPreference
    android_summary="Edit text prefrence"
    android_title="Edit"
    android_key="pref_edit"/>


    </PreferenceCategory>
    <PreferenceCategory
    android_title="Category2"
    android_summary="sample summary">
    <RingtonePreference
    android_key="pref_ring"
    android_title="Ringtones preference"/>

    <ListPreference
    android_key="pref_list"
    android_title="List Preference"
    android_dialogTitle="List Pref Dialog"
    android_entries="@array/pref_items"
    android_entryValues="@array/pref_items_values"/>
    </PreferenceCategory>


    then from our activity:
    public class PrefActivity extends PreferenceActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    addPreferencesFromResource(R.xml.prefs);

    }
    }

    and the activity will look like this:





    the ListPreference can be associated with String array resources as its key/value entries
    <string-array name="pref_items">
    <item>Item1</item>
    <item>Item2</item>
    <item>Item3</item>
    <item>Item4</item>
    <item>Item5</item>
    </string-array>

    <string-array name="pref_items_values">
    <item>1</item>
    <item>2</item>
    <item>3</item>
    <item>4</item>
    <item>5</item>
    </string-array>


    to reference the preference widgets programmatically:
    EditTextPreference pref_edit=(EditTextPreference)findPreference("pref_edit");
    Read More..

    Thursday, March 24, 2016

    Android Developers Backstage Ep 3 Security

    Chet Haase, Tor Norbye, are joined by Adrian Ludwig on the third episode of Android Developers Backstage.

    Adrian is stalwart member of the Android team focusing on all aspects of security. Learn about the various ways that Adrian and his team help to make Android better for users.

    Click here to download the podcast
    Read More..

    Friday, March 18, 2016

    Ski Safari v1 4 0 Full

    ? ? ? ? ? "Great! - Love everything about this game. The graphics are excellent, the controls easy to use, and best of all, its endlessly fun!"
    ? ? ? ? ? "How can you go wrong ! - This game is smooth as a sheet of ice !! Love it"
    Welcome to Ski Safari!
    Ski Safari is where Animals, Avalanches and Action come together to create a new casual gameplay experience.

    Our deep sleeping hero has to stay ahead of a relentless avalanche that threatens the local mountainsides. Sven, as we like to call him, can use animals to aid his escape from an icey end. Each of the hillside animals have different attributes to make a speedier escape. Penguins glide further, Yetis are tougher, Eagles soar to great heights, each of these can provide useful advantage for Sven. Sometimes on the slopes Sven can find fast Snowmobiles which can ferry multiple animals a maintain a very high top speed.
    Staying ahead of the avalanche has its advantages and perks. Completing objectives can level up Sven and increase his score multiplier. Riding animals, performing backflips add to the score and with an increased score multiplier Sven will rocketing up the highscore table with ease.

    Whats New
    Welcome to the North Pole!
    Its that time of year where reindeer and snowballs collide... well... at least in Ski Safari they do.
    Weve crammed loads of things in this update, including:
    • new boosters!
    • new costumes and scarves!
    • new snowmobiles!
    • new challenges and ranks!
    • tweaks and fixes
    Once you are out in wilds of the North Pole be on the look out for the elusive Rudolph reindeer, its the one with the shiny red nose... some would even say it glows.
    Happy holidays and have fun!

    Read Here: How to Install APK

    Requirements: Android 2.0.1+
    File Size: 37 MB
    Download Link: Mediafire.com
    Read More..