Thursday, March 31, 2016

Xamarin for Absolute Beginners || Installing Xamarin

See how to install Xamarin, and get started with app development.

just announced at //build - "Xamarin for Everyone"

As of today, Visual Studio now includes Xamarin.

Xamarin will be in every edition of Visual Studio, including the widely-available Visual Studio Community Edition, which is free for individual developers, open source projects, academic research, education, and small professional teams. Develop and publish native apps for iOS and Android with C# or F# from directly within Visual Studio with no limits on app size.

For developers on the Mac, Xamarin Studio is now available as a benefit of your Visual Studio Professional or Enterprise subscription. Developers can use the newly-created Xamarin Studio Community Edition for free.

To begin developing iOS and Android apps with the full power of Xamarin and C#, download Xamarin Studio or Xamarin for Visual Studio today.

~ announcement

Wednesday, March 30, 2016

Load something from Internet using URLConnection and ReadableByteChannel, in Thread

Last example show "Load something from Internet using URLConnection and BufferedReader, in Thread". Here is another example using java.nio.channels.ReadableByteChannel.

Read operations are synchronous on a ReadableByteChannel, that is, if a read is already in progress on the channel then subsequent reads will block until the first read completes. It is undefined whether non-read operations will block.


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

import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;
import android.widget.Toast;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;

public class MainActivity extends AppCompatActivity {

    TextView textResult;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textResult = (TextView)findViewById(R.id.tresult);

        MyThread myThread = new MyThread("http://android-er.blogspot.com", textResult);
        myThread.start();
    }

    class MyThread extends Thread{
        String target;
        TextView textviewResult;

        private Handler handler = new Handler();

        public MyThread(String target, TextView textviewResult) {
            super();
            this.target = target;
            this.textviewResult = textviewResult;
        }

        @Override
        public void run() {
            String result = "";

            URL url = null;
            try {
                url = new URL(target);
                URLConnection urlConnection = url.openConnection();
                InputStream inputStream = urlConnection.getInputStream();

                ReadableByteChannel readableByteChannel = Channels.newChannel(inputStream);
                ByteBuffer buffer = ByteBuffer.allocate(1024);

                while (readableByteChannel.read(buffer) > 0)
                {
                    result += new String(buffer.array());
                    buffer.clear();
                }

            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

            final String finalResult = result;
            handler.post(new Runnable() {
                @Override
                public void run() {
                    textviewResult.setText(finalResult);
                    Toast.makeText(MainActivity.this,
                            "finished", Toast.LENGTH_LONG).show();
                }
            });
        }
    }
}


For layout and AndroidManifest.xml, refer to the previous post "Load something from Internet using URLConnection and BufferedReader, in AsyncTask".


Tuesday, March 29, 2016

Load something from Internet using URLConnection and BufferedReader, in Thread

Previous post show how to Load something from Internet using URLConnection and BufferedReader, in AsyncTask. This post show how to do it in Thread, and update UI using Handler.



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

import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;
import android.widget.Toast;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

public class MainActivity extends AppCompatActivity {

    TextView textResult;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textResult = (TextView)findViewById(R.id.tresult);

        MyThread myThread = new MyThread("http://android-er.blogspot.com", textResult);
        myThread.start();
    }

    class MyThread extends Thread{
        String target;
        TextView textviewResult;

        private Handler handler = new Handler();

        public MyThread(String target, TextView textviewResult) {
            super();
            this.target = target;
            this.textviewResult = textviewResult;
        }

        @Override
        public void run() {
            String result = "";

            try {
                URL url = new URL(target);
                URLConnection urlConnection = url.openConnection();
                InputStream inputStream = urlConnection.getInputStream();
                InputStreamReader inputStreamReader =
                        new InputStreamReader(inputStream);
                BufferedReader buffReader = new BufferedReader(inputStreamReader);

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

            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

            final String finalResult = result;
            handler.post(new Runnable() {
                @Override
                public void run() {
                    textviewResult.setText(finalResult);
                    Toast.makeText(MainActivity.this,
                            "finished", Toast.LENGTH_LONG).show();
                }
            });
        }
    }
}


For layout and AndroidManifest.xml, refer to the previous post "Load something from Internet using URLConnection and BufferedReader, in AsyncTask".

Related:
Load something from Internet using URLConnection and ReadableByteChannel, in Thread

NFC For Dummies

NFC For Dummies

Your no-nonsense guide to Near Field Communication
Are you a newcomer to Near Field Communication and baffled by the scant documentation and online support available for this powerful new technology? You've come to the right place! Written in a friendly and easily accessible manner, NFC For Dummies takes the intimidation out of working with the features of NFC-enabled devices and tells you exactly what it is and what it does—and doesn't do.

NFC is revolutionizing the way people interact on a daily basis. It enables big data and cloud-based computing through mobile devices and can be used by anyone with a smartphone or tablet every day! Soon to be as commonplace as using Wi-Fi or the camera on your smartphone, NFC is going to forever change the way we interact with people and the things around us. It simplifies the sending and receiving of information, makes monetary transactions simple and secure—Apple Pay already uses NFC—and is a low-cost product to manufacture and use. As more developers create apps with NFC, you're going to see it used regularly—everywhere from cash registers to your social media accounts to electronic identity systems. Don't get left behind; get up to speed on NFC today!

  • Provides a plain-English overview of NFC
  • Covers the history and technology behind NFC
  • Helps you make sense of IoT and powered chips
  • Explains proximity technologies and non-payment applications

Whether you're a developer, investor, or a mobile phone user who is excited about the capabilities of this rapidly growing technology, NFC For Dummies is the reference you'll want to keep close at hand!

Load something from Internet using URLConnection and BufferedReader, in AsyncTask

Here is example to load something from Internet using URLConnection and BufferedReader, in AsyncTask.

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

import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;

import org.w3c.dom.Text;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

public class MainActivity extends AppCompatActivity {

    TextView textResult;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textResult = (TextView)findViewById(R.id.tresult);

        MyAsyncTask myAsyncTask = new MyAsyncTask(textResult);
        myAsyncTask.execute("http://android-er.blogspot.com");
    }

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

        TextView textviewResult;

        public MyAsyncTask(TextView textviewResult) {
            super();
            this.textviewResult = textviewResult;
        }

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

            try {
                URL url = new URL(params[0]);
                URLConnection urlConnection = url.openConnection();
                InputStream inputStream = urlConnection.getInputStream();
                InputStreamReader inputStreamReader =
                        new InputStreamReader(inputStream);
                BufferedReader buffReader = new BufferedReader(inputStreamReader);

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

            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

            return result;
        }

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

            Toast.makeText(MainActivity.this,
                    "DONE", Toast.LENGTH_LONG).show();
            super.onPostExecute(s);
        }
    }
}


activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp"
    tools:context="com.blogspot.android_er.androidinternet.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" />

    <ScrollView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
    <TextView
        android:id="@+id/tresult"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    </ScrollView>
</LinearLayout>


uses-permission of "android.permission.INTERNET" is needed in src/main/AndroidManifest.xml.


Add uses-permission of "android.permission.INTERNET" to AndroidManifest.xml

To access Internet in your app, you have to add uses-permission of "android.permission.INTERNET" to AndroidManifest.xml. Shown in this video:


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.blogspot.android_er.androidinternet">

    <uses-permission android:name="android.permission.INTERNET"/>
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

</manifest>

Related:
Load something from Internet using URLConnection and BufferedReader, in Thread

Thursday, March 24, 2016

HandlerThread example


Last post show examples of AsyncTask and Thread + Handler, here is another version using HandlerThread.

This video show how it run on Android Emulator running Android N, in Multi-Window. The left windows running example of HandlerThread in this post, the right window running Thread + Handler in last post.


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

import android.os.Handler;
import android.os.HandlerThread;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    private Handler handler = new Handler();
    private MyHandlerThread myHandlerThread;

    Button btnStart;
    ProgressBar progressBar;
    TextView textMsg;

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

        progressBar = (ProgressBar)findViewById(R.id.progress);
        textMsg = (TextView)findViewById(R.id.msg);
        btnStart = (Button)findViewById(R.id.start);

        myHandlerThread = new MyHandlerThread("myHandlerThread");
        final Runnable myRunnable = new Runnable() {

            @Override
            public void run() {
                for (int i = 0; i <= 10; i++) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    //is accessed from within inner class, needs to be declared final
                    final int finalI = i;
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            progressBar.setProgress(finalI);
                        }
                    });
                }

                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        textMsg.setText("finished");
                    }
                });
            }
        };

        myHandlerThread.start();
        myHandlerThread.prepareHandler();

        btnStart.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                myHandlerThread.postTask(myRunnable);
            }
        });
    }

    @Override
    protected void onDestroy() {
        myHandlerThread.quit();
        super.onDestroy();
    }

    public class MyHandlerThread extends HandlerThread {

        private Handler handler;

        public MyHandlerThread(String name) {
            super(name);
        }

        public void postTask(Runnable task){
            handler.post(task);
        }

        public void prepareHandler(){
            handler = new Handler(getLooper());
        }
    }
}


layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    android:orientation="vertical"
    tools:context="com.blogspot.android_er.androidhandlerthread.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" />

    <Button
        android:id="@+id/start"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Start"/>

    <ProgressBar
        android:id="@+id/progress"
        style="?android:attr/progressBarStyleHorizontal"
        android:indeterminate="false"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:max="10"
        android:progress="0"/>
    <TextView
        android:id="@+id/msg"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
</LinearLayout>




reference: Get a HandlerThread on your App

AsyncTask vs Thread + Handler


This post show how to implement using AsyncTask and Thread/Handler to perform the same function: doing something in background and update UI elements (ProgressBar and TextView).

This video show how it run on Android Emulator running Android N, in Multi-Window.


AsyncTask

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

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

public class MainActivity extends AppCompatActivity {

    Button btnStart;
    ProgressBar progressBar;
    TextView textMsg;

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

        progressBar = (ProgressBar)findViewById(R.id.progress);
        textMsg = (TextView)findViewById(R.id.msg);

        btnStart = (Button)findViewById(R.id.start);
        btnStart.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                MyAsyncTask myAsyncTask = new MyAsyncTask(progressBar, textMsg);
                myAsyncTask.execute();
            }
        });
    }

    class MyAsyncTask extends AsyncTask<Void, Integer, Void>{

        ProgressBar pBar;
        TextView tMsg;

        public MyAsyncTask(ProgressBar pBar, TextView tMsg) {
            super();
            this.pBar = pBar;
            this.tMsg = tMsg;
        }

        @Override
        protected Void doInBackground(Void... params) {
            for(int i=0; i<=10; i++){
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                publishProgress(i);
            }
            return null;
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            pBar.setProgress(values[0]);
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            tMsg.setText("finished");
        }
    }
}


layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    android:orientation="vertical"
    tools:context="com.blogspot.android_er.androidasynctask.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" />

    <Button
        android:id="@+id/start"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Start"/>

    <ProgressBar
        android:id="@+id/progress"
        style="?android:attr/progressBarStyleHorizontal"
        android:indeterminate="false"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:max="10"
        android:progress="0"/>
    <TextView
        android:id="@+id/msg"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
</LinearLayout>



Thread + Handler

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

import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;

import org.w3c.dom.Text;

public class MainActivity extends AppCompatActivity {

    Button btnStart;
    ProgressBar progressBar;
    TextView textMsg;

    private Handler handler = new Handler();

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

        progressBar = (ProgressBar)findViewById(R.id.progress);
        textMsg = (TextView)findViewById(R.id.msg);

        btnStart = (Button)findViewById(R.id.start);
        btnStart.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                MyThread myThread = new MyThread(progressBar, textMsg);
                myThread.start();
            }
        });
    }

    class MyThread extends Thread{

        ProgressBar pBar;
        TextView tMsg;

        public MyThread(ProgressBar pBar, TextView tMsg) {
            super();
            this.pBar = pBar;
            this.tMsg = tMsg;
        }

        @Override
        public void run() {

            for (int i = 0; i <= 10; i++) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                //is accessed from within inner class, needs to be declared final
                final int finalI = i;
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        pBar.setProgress(finalI);
                    }
                });
            }

            handler.post(new Runnable() {
                @Override
                public void run() {
                    tMsg.setText("finished");
                }
            });
        }
    }
}


layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    android:orientation="vertical"
    tools:context="com.blogspot.android_er.androidthreadhandler.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" />

    <Button
        android:id="@+id/start"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Start"/>

    <ProgressBar
        android:id="@+id/progress"
        style="?android:attr/progressBarStyleHorizontal"
        android:indeterminate="false"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:max="10"
        android:progress="0"/>
    <TextView
        android:id="@+id/msg"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
</LinearLayout>



next:
- HandlerThread example

related:
Load something from Internet using URLConnection and BufferedReader, in AsyncTask
Load something from Internet using URLConnection and BufferedReader, in Thread


Tuesday, March 22, 2016

An Introduction to Brillo, the OS for IoT


The vision with Brillo is to bring the simplicity and speed of software development to hardware by joining together three things. First, an OS based on Android. Second, core services that enable a great getting started experience and allow you to operate at scale. Third, a developer kit with tools to build, test, and debug your solution. Watch this video for a quick overview of these major components and how they work together to quickly move from prototype to production, and manage at scale with over the air (OTA) updates, metrics, and crash reporting

Learn more about Brillo - http://developers.google.com/brillo

An Introduction to Weave, the communications platform for IoT


Weave helps you focus on adding intelligence into your IoT user experience in two ways. First, by giving you all the building blocks you need for communicating with your devices directly or through the cloud. Second, by providing a common language for your app or service to use across all of a user’s devices. Watch this video to get an overview of the Weave components and how they fit together to help make it the easiest way to connect all the things

Learn More about Weave - http://developers.google.com/weave


Set Text size base on TypedValue

setTextSize (int unit, float size) set the default text size to a given unit and value. See TypedValue for the possible dimension units.

Example to set text size of TextView base on TypedValue:


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

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.TypedValue;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    TextView text1, text2, text3, text4, text5, text6;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        text1 = (TextView)findViewById(R.id.text1);
        text2 = (TextView)findViewById(R.id.text2);
        text3 = (TextView)findViewById(R.id.text3);
        text4 = (TextView)findViewById(R.id.text4);
        text5 = (TextView)findViewById(R.id.text5);
        text6 = (TextView)findViewById(R.id.text6);

        text1.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20);
        text1.setText("20 DIP (Device Independent Pixels)");

        text2.setTextSize(TypedValue.COMPLEX_UNIT_IN, 0.5f);
        text2.setText("0.5 inch");

        text3.setTextSize(TypedValue.COMPLEX_UNIT_MM, 10);
        text3.setText("10 millimeter");

        text4.setTextSize(TypedValue.COMPLEX_UNIT_PT, 30);
        text4.setText("30 points");

        text5.setTextSize(TypedValue.COMPLEX_UNIT_PX, 30);
        text5.setText("30 raw pixels");

        text6.setTextSize(TypedValue.COMPLEX_UNIT_SP, 30);
        text6.setText("30 scaled pixels");
    }
}


layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    android:orientation="vertical"
    tools:context="com.blogspot.android_er.androidfonts.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" />
    <TextView
        android:id="@+id/text1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <TextView
        android:id="@+id/text2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <TextView
        android:id="@+id/text3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <TextView
        android:id="@+id/text4"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <TextView
        android:id="@+id/text5"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <TextView
        android:id="@+id/text6"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</LinearLayout>


Sunday, March 20, 2016

Detect phone type and network type

Android example to detect phone (CDMA, GSM, SIP or NONE) type and network type (CDMA, EDGE, GPRS, LTE...etc).

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

import android.content.Context;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.telephony.TelephonyManager;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

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

        TextView textPhoneType = (TextView)findViewById(R.id.textphonetype);
        TextView textNetworkType = (TextView)findViewById(R.id.textnetworktype);

        TelephonyManager telephonyManager =
                (TelephonyManager) getApplicationContext()
                        .getSystemService(Context.TELEPHONY_SERVICE);

        if(telephonyManager == null){
            textPhoneType.setText("not supported TELEPHONY_SERVICE");
        }else{
            int phoneType = telephonyManager.getPhoneType();
            int networkType = telephonyManager.getNetworkType();

            textPhoneType.setText(
                    "Phone Type: " + phoneType + " " + decPhoneType(phoneType));
            textNetworkType.setText(
                    "Network Type: " + networkType + " " + decNetworkType(networkType));
        }
    }

    private String decPhoneType(int type){
        String result = "";

        switch(type){
            case TelephonyManager.PHONE_TYPE_CDMA:
                result = "CDMA";
                break;
            case TelephonyManager.PHONE_TYPE_GSM:
                result = "GSM";
                break;
            case TelephonyManager.PHONE_TYPE_NONE:
                result = "NONE";
                break;
            case TelephonyManager.PHONE_TYPE_SIP:
                result = "SLIP";
                break;
            default:
                result = "unknown type";
        }
        return result;
    }

    private String decNetworkType(int type){
        String result = "";

        switch(type){
            case TelephonyManager.NETWORK_TYPE_1xRTT:
                result = "1xRTT";
                break;
            case TelephonyManager.NETWORK_TYPE_CDMA:
                result = "CDMA";
                break;
            case TelephonyManager.NETWORK_TYPE_EDGE:
                result = "EDGE";
                break;
            case TelephonyManager.NETWORK_TYPE_EHRPD:
                result = "EHRPD";
                break;
            case TelephonyManager.NETWORK_TYPE_EVDO_0:
                result = "EVDO_0";
                break;
            case TelephonyManager.NETWORK_TYPE_EVDO_A:
                result = "EVDO_A";
                break;
            case TelephonyManager.NETWORK_TYPE_EVDO_B:
                result = "EVDO_B";
                break;
            case TelephonyManager.NETWORK_TYPE_GPRS:
                result = "GPRS";
                break;
            case TelephonyManager.NETWORK_TYPE_HSDPA:
                result = "HSDPA";
                break;
            case TelephonyManager.NETWORK_TYPE_HSPA:
                result = "HSPA";
                break;
            case TelephonyManager.NETWORK_TYPE_HSPAP:
                result = "HSPAP";
                break;
            case TelephonyManager.NETWORK_TYPE_HSUPA:
                result = "HSUPA";
                break;
            case TelephonyManager.NETWORK_TYPE_IDEN:
                result = "IDEN";
                break;
            case TelephonyManager.NETWORK_TYPE_LTE:
                result = "LTE";
                break;
            case TelephonyManager.NETWORK_TYPE_UMTS:
                result = "UMTS";
                break;
            case TelephonyManager.NETWORK_TYPE_UNKNOWN:
                result = "UNKNOWN";
                break;
            default:
                result = "unknown type";
        }
        return result;
    }
}


layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    android:orientation="vertical"
    tools:context="com.blogspot.android_er.androidphone.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" />

    <TextView
        android:id="@+id/textphonetype"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <TextView
        android:id="@+id/textnetworktype"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</LinearLayout>



Get current setting of font scale


Android example to get current user preference for the scaling factor for fonts, relative to the base density scaling, by reading getResources().getConfiguration().fontScale.

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

import android.provider.Settings;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

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

        TextView prompt = (TextView)findViewById(R.id.prompt);

        float fontScale = getResources().getConfiguration().fontScale;
        prompt.setText("fontScale:: " + fontScale);

    }
}


layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    android:orientation="vertical"
    tools:context="com.blogspot.android_er.androidfontscale.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" />

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


Saturday, March 19, 2016

Free from O'reilly Media: Evaluating And Choosing An Iot Platform

O'reilly Media: Evaluating And Choosing An Iot Platform

With the push for IoT-enabled solutions comes the need for reliable IoT platforms, especially for companies that require industrial-grade IoT capabilities. This O’Reilly report examines various features that heavy-equipment B2B industries should expect in an IoT platform, as well as the key attributes you should be looking for when choosing a platform vendor.

Up to this point, much of the effort in developing an IoT solution has gone into platform building. But if you are to gain a competitive advantage in the marketplace, you can’t afford to build technology stacks from scratch to accommodate hardware, firmware, software, edge computing, analytics, business systems integration, and many other components.

In this report, author Matthew Perry explains what an industrial-grade IoT platform ideally should include, from bidirectional connectivity and distributed computing to availability, scalability, and reliability. You’ll also learn how to assess your IoT strategy and find a vendor that can fulfill your specific needs.

Matthew J. Perry is a writer and editor with a particular interest in how the Internet of Things can make cities smarter. He has written for Cisco Systems and collaborated on ten published books. He lives in New York City.

link: http://www.thingworx.com/white-papers/oreilly-media-evaluating-and-choosing-an-iot-platform

FREE Ebook from O'Reilly - Functional Programming in Python

Functional Programming in Python
By David Mertz
Publisher: O'Reilly
Released: June 2015

Python is not a functional programming language, but it is a multi-paradigm language that makes functional programming easy to perform, and easy to mix with other programming styles. In this paper, David Mertz, a director of Python Software Foundation, examines the functional aspects of the language and points out which options work well and which ones you should generally decline.

Mertz describes ways to avoid Python’s imperative-style flow control, the nuances of callable functions, how to work lazily with iterators, and the use of higher-order functions. He also lists several third-party Python libraries useful for functional programming.

Topics include:

  • Using encapsulation and other means to describe "what" a data collection consists of, rather than "how" to construct a data collection
  • Creating callables with named functions, lambdas, closures, methods of classes, and multiple dispatch
  • Using Python’s iterator protocol to accomplish the same effect as a lazy data structure
  • Creating higher-order functions that take functions as arguments and/or produce a function as a result

David Mertz is a director of the Python Software Foundation, and chair of its Trademarks and Outreach & Education Committees. He wrote the columns Charming Python and XML Matters for IBM developerWorks and the Addison-Wesley book Text Processing in Python. David has spoken at multiple OSCON and PyCon events.

link: http://www.oreilly.com/programming/free/functional-programming-python.csp

FREE Ebook from O'Reilly - Modern Java EE Design Patterns

Modern Java EE Design Patterns
Building Scalable Architecture for Sustainable Enterprise Development
Publisher: O'Reilly

With the ascent of DevOps, microservices, containers, and cloud-based development platforms, the gap between state-of-the-art solutions and the technology that enterprises typically support has greatly increased. But as Markus Eisele explains in this O’Reilly report, some enterprises are now looking to bridge that gap by building microservice-based architectures on top of Java EE.

Can it be done? Is it even a good idea? Eisele thoroughly explores the possibility and provides savvy advice for enterprises that want to move ahead. The issue is complex: Java EE wasn’t built with the distributed application approach in mind, but rather as one monolithic server runtime or cluster hosting many different applications. If you’re part of an enterprise development team investigating the use of microservices with Java EE, this book will help you:

  • Understand the challenges of starting a greenfield development vs tearing apart an existing brownfield application into services
    Examine your business domain to see if microservices would be a good fit
  • Explore best practices for automation, high availability, data separation, and performance
  • Align your development teams around business capabilities and responsibilities
  • Inspect design patterns such as aggregator, proxy, pipeline, or shared resources to model service interactions

Markus Eisele is a Developer Advocate at Red Hat and focuses on JBoss Middleware. He has been working with Java EE servers from different vendors for more than 14 years, and has worked with different customers on all kinds of Java EE related applications and solutions. He is a prolific blogger, writer, and tech editor for Java EE content. Markus is also a Java Champion and former ACE Director.

link: http://www.oreilly.com/programming/free/modern-java-ee-design-patterns.csp

Tuesday, March 15, 2016

Set wallpaper using resource inside APK


This example modify from the post "Restore default build-in wallpaper", to add function to set wallpaper using resource inside APK.


Create /res/raw/ folder in your Android Studio project. Refer: Android Studio error: Expected resource of type raw

Modify layout/activity_main.xml to add button to "Load Wallpaper from from Resources".
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    android:orientation="vertical"
    tools:context="com.blogspot.android_er.androidwallpaper.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" />
    <Button
        android:id="@+id/displaywp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Display Wallpaper"/>
    <Button
        android:id="@+id/loadwp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Load Wallpaper from Gallery"/>
    <Button
        android:id="@+id/loadwpres"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Load Wallpaper from from Resources"/>
    <Button
        android:id="@+id/restorewp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Restore default Wallpaper"/>
    <ImageView
        android:id="@+id/image"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>


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

import android.app.Activity;
import android.app.WallpaperManager;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

import java.io.FileNotFoundException;
import java.io.IOException;

public class MainActivity extends AppCompatActivity {

    ImageView imageWallpaper;
    Button btnLoadWallpaper, btnDisplayWallpaper, btnRestoreWallpaper;
    Button btnLoadWallpaperRes;

    private static final int RQS_OPEN_IMAGE = 1;

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

        imageWallpaper = (ImageView)findViewById(R.id.image);

        btnDisplayWallpaper = (Button)findViewById(R.id.displaywp);
        btnDisplayWallpaper.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                displayWallpaper();
            }
        });

        btnLoadWallpaper = (Button)findViewById(R.id.loadwp);
        btnLoadWallpaper.setOnClickListener(btnLoadWallpaperOnClickListener);

        btnRestoreWallpaper = (Button)findViewById(R.id.restorewp);
        btnRestoreWallpaper.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                WallpaperManager myWallpaperManager =
                        WallpaperManager.getInstance(getApplicationContext());
                try {
                    myWallpaperManager.clear();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });

        btnLoadWallpaperRes = (Button)findViewById(R.id.loadwpres);
        btnLoadWallpaperRes.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                WallpaperManager myWallpaperManager =
                        WallpaperManager.getInstance(getApplicationContext());
                try {
                    myWallpaperManager.setResource(R.raw.androidstudio);
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        });

        displayWallpaper();

    }

    View.OnClickListener btnLoadWallpaperOnClickListener = new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            Intent intent = new Intent();

            if (Build.VERSION.SDK_INT >=
                    Build.VERSION_CODES.KITKAT) {
                intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
            } else {
                intent.setAction(Intent.ACTION_GET_CONTENT);
            }

            intent.addCategory(Intent.CATEGORY_OPENABLE);

            // set MIME type for image
            intent.setType("image/*");

            startActivityForResult(intent, RQS_OPEN_IMAGE);
        }
    };

    private void displayWallpaper(){
        WallpaperManager myWallpaperManager =
                WallpaperManager.getInstance(getApplicationContext());
        Drawable drawableWallpaper = myWallpaperManager.getDrawable();
        imageWallpaper.setImageDrawable(drawableWallpaper);

        Toast.makeText(this,
                drawableWallpaper.getMinimumWidth() + " x " + drawableWallpaper.getMinimumHeight()
                        + "\n" +
                        drawableWallpaper.getIntrinsicWidth() + " x " + drawableWallpaper.getIntrinsicHeight(),
                Toast.LENGTH_LONG).show();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == Activity.RESULT_OK) {
            if (requestCode == RQS_OPEN_IMAGE) {
                Uri dataUri = data.getData();
                Uri wallpaperUri = dataUri;
                Toast.makeText(this, wallpaperUri.toString(), Toast.LENGTH_LONG).show();

                Bitmap newOriginalBM= loadBitmap(dataUri);
                reloadWallpaper(newOriginalBM);
            }
        }
    }

    private Bitmap loadBitmap(Uri src) {

        Bitmap bm = null;

        try {
            bm = BitmapFactory.decodeStream(
                    getBaseContext().getContentResolver().openInputStream(src));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        return bm;
    }

    private void reloadWallpaper(Bitmap bm){
        if(bm != null){
            WallpaperManager myWallpaperManager =
                    WallpaperManager.getInstance(getApplicationContext());

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if(myWallpaperManager.isWallpaperSupported()){
                    try {
                        myWallpaperManager.setBitmap(bm);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }else{
                    Toast.makeText(MainActivity.this,
                            "isWallpaperSupported() NOT SUPPORTED",
                            Toast.LENGTH_LONG).show();
                }
            }else{
                try {
                    myWallpaperManager.setBitmap(bm);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }else{
            Toast.makeText(MainActivity.this, "bm == null", Toast.LENGTH_LONG).show();
        }
    }
}


uses-permission of "android.permission.SET_WALLPAPER" is needed.

Android Studio error: Expected resource of type raw

In my exercise of setting wallpaper using resource inside APK, I tried to load resource from /res/drawable/ folder. But reported with error of "Expected resource of type raw".


My solution is to create /res/raw/ folder and move the resources to it. And load with R.raw....

This video show how:


Beginning Android 5th Edition

Beginning Android

Get started in creating marketable apps for the burgeoning Android market. Begin your journey by learning the essentials of programming for phones and tables that are built around Google's wildly-successful Android platform. Beginning Android, Fifth Edition is fresh with details on the latest iteration of the Android 5 and earlier versions.

Google’s Android operating-system has taken the industry by storm, going from its humble beginnings as a smartphone operating system to its current status as a platform for apps that run across a gamut of devices from phones to tablets to netbooks to televisions, and the list is sure to grow. Smart developers are not sitting idly by in the stands, but are jumping into the game of creating innovative and salable applications for this fast-growing, mobile- and consumer-device platform. If you’re not in the game yet, now is your chance!

Begin at the beginning by installing the tools and compiling a skeleton app. Move through creating layouts, employing widgets, taking user input, and giving back results. Soon you’ll be creating innovative applications involving multi-touch, multi-tasking, and more! You’ll be drawing data live from the Internet using web services and delighting your customers with life-enhancing apps. Not since the PC era first began has there been this much opportunity for the common developer. What are you waiting for? Grab your copy of Beginning Android and get started!

Monday, March 14, 2016

Create AVD of Android N Preview for Android Emulator, in Android Studio

Android Emulator running Android N Preview
Before create AVD of Android N Preview, update with Android SDK Manager, make sure to include Android N (API 23, N Preview) SDK Platform and System Images.


Create new AVD in Android Studio (version 2.1 Preview 1 in this example), refer to the video below:


Sunday, March 13, 2016

Calculate SHA1 checksum using Certutil in Windows 10


Certutil.exe is a command-line program that is installed as part of Certificate Services. You can use Certutil.exe to dump and display certification authority (CA) configuration information, configure Certificate Services, backup and restore CA components, and verify certificates, key pairs, and certificate chains. ~ details

Example:
CertUtil -hashfile kali-2.1-rpi2.img.xz SHA1

This video show how to:


Wednesday, March 9, 2016

Insert bitmap to MediaStore with title and List images title in MediaStore

It's a following exercise of my old posts "Save Bitmap to storage", "List images in MediaStore.Images.Media" and "Get thumbnails (in MediaStore.Images.Thumbnails) associated with MediaStore.Images.Media", to show how to insert bitmap to MediaStore with title, and list images title in MediaStore.


To insert bitmap to MediaStore, we can call insertImage(ContentResolver cr, String imagePath, String name, String description) or insertImage(ContentResolver cr, Bitmap source, String title, String description) methods of MediaStore.Images.Media. Both of them, we have to provide title (or name) and description. In my understanding, they are some extra info we can pass to MediaStore.

In the insert bitmap side, modify the example in "Save Bitmap to storage" to insert with user editable title. For the second button "Save to MediaStore" only.


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

import android.content.ContentResolver;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

public class MainActivity extends AppCompatActivity {

    ImageView imageView;
    Button btnSaveExternalStorageDirectory;
    Button btnSaveMediaStore;
    Button btnSaveFileAndMediaStore;

    EditText editTextTitle;

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

        editTextTitle = (EditText)findViewById(R.id.title);

        imageView = (ImageView)findViewById(R.id.image);
        btnSaveExternalStorageDirectory = (Button)findViewById(R.id.saveExternalStorageDirectory);
        btnSaveExternalStorageDirectory.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                /*
                * Save bitmap to ExternalStorageDirectory
                */
                // get bitmap from ImageView
                // not always valid, depends on your drawable
                Bitmap bitmap = ((BitmapDrawable)imageView.getDrawable()).getBitmap();

                //always save as
                String fileName = "test.jpg";

                ByteArrayOutputStream bytes = new ByteArrayOutputStream();
                bitmap.compress(Bitmap.CompressFormat.JPEG, 40, bytes);

                File ExternalStorageDirectory = Environment.getExternalStorageDirectory();
                File file = new File(ExternalStorageDirectory + File.separator + fileName);

                FileOutputStream fileOutputStream = null;
                try {
                    file.createNewFile();
                    fileOutputStream = new FileOutputStream(file);
                    fileOutputStream.write(bytes.toByteArray());

                    Toast.makeText(MainActivity.this,
                            file.getAbsolutePath(),
                            Toast.LENGTH_LONG).show();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } finally {
                    if(fileOutputStream != null){
                        try {
                            fileOutputStream.close();
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                }
            }});

        btnSaveMediaStore = (Button)findViewById(R.id.saveMediaStore);
        btnSaveMediaStore.setOnClickListener(new View.OnClickListener(){

            @Override
            public void onClick(View v) {
                /*
                * Save bitmap to MediaStore
                */

                //get bitmap from ImageVIew
                //not always valid, depends on your drawable
                Bitmap bitmap = ((BitmapDrawable)imageView.getDrawable()).getBitmap();

                ContentResolver cr = getContentResolver();
                //Save with user editable title
                String title = editTextTitle.getText().toString();
                String description = "Bitmap saved by Android-er";
                String savedURL = MediaStore.Images.Media
                        .insertImage(cr, bitmap, title, description);

                Toast.makeText(MainActivity.this,
                        savedURL,
                        Toast.LENGTH_LONG).show();

            }});

        btnSaveFileAndMediaStore = (Button)findViewById(R.id.saveExternalStorageDirectoryMediaStore);
        btnSaveFileAndMediaStore.setOnClickListener(new View.OnClickListener(){

            @Override
            public void onClick(View v) {
                /*
                * Save bitmap to ExternalStorageDirectory
                */

                //get bitmap from ImageVIew
                //not always valid, depends on your drawable
                Bitmap bitmap = ((BitmapDrawable)imageView.getDrawable()).getBitmap();

                //always save as
                String fileName = "test.jpg";

                ByteArrayOutputStream bytes = new ByteArrayOutputStream();
                bitmap.compress(Bitmap.CompressFormat.JPEG, 40, bytes);

                File ExternalStorageDirectory = Environment.getExternalStorageDirectory();
                File file = new File(ExternalStorageDirectory + File.separator + fileName);

                FileOutputStream fileOutputStream = null;
                try {
                    file.createNewFile();
                    fileOutputStream = new FileOutputStream(file);
                    fileOutputStream.write(bytes.toByteArray());

                    ContentResolver cr = getContentResolver();
                    String imagePath = file.getAbsolutePath();
                    String name = file.getName();
                    String description = "My bitmap created by Android-er";
                    String savedURL = MediaStore.Images.Media
                            .insertImage(cr, imagePath, name, description);

                    Toast.makeText(MainActivity.this,
                            savedURL,
                            Toast.LENGTH_LONG).show();

                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } finally {
                    if(fileOutputStream != null){
                        try {
                            fileOutputStream.close();
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                }

            }});
    }
}


layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    android:orientation="vertical"
    tools:context="com.blogspot.android_er.androidsavebitmap.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" />

    <ImageView
        android:id="@+id/image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher" />

    <EditText
        android:id="@+id/title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <Button
        android:id="@+id/saveExternalStorageDirectory"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Save to ExternalStorageDirectory" />

    <Button
        android:id="@+id/saveMediaStore"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Save to MediaStore" />

    <Button
        android:id="@+id/saveExternalStorageDirectoryMediaStore"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Save to ExternalStorageDirectory and insert to MediaStore" />
</LinearLayout>


uses-permission of "android.permission.WRITE_EXTERNAL_STORAGE" is needed in AndroidManifest.xml.


download filesDownload the files .


In the List Images in MediaStore:


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

import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.provider.MediaStore;
import android.support.v4.content.CursorLoader;
import android.support.v4.widget.CursorAdapter;
import android.support.v4.widget.SimpleCursorAdapter;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    final Uri thumbUri = MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI;;
    final String thumb_DATA = MediaStore.Images.Thumbnails.DATA;
    final String thumb_IMAGE_ID = MediaStore.Images.Thumbnails.IMAGE_ID;
    final Uri sourceUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;

    ListView myList;
    SimpleCursorAdapter mySimpleCursorAdapter;

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

        myList=(ListView)findViewById(R.id.mylist);

        String[] from = {MediaStore.MediaColumns.TITLE};
        int[] to = {android.R.id.text1};

        CursorLoader cursorLoader = new CursorLoader(
                this,
                sourceUri,
                null,
                null,
                null,
                MediaStore.Images.Media.TITLE);

        Cursor cursor = cursorLoader.loadInBackground();

        mySimpleCursorAdapter = new SimpleCursorAdapter(
                this,
                android.R.layout.simple_list_item_1,
                cursor,
                from,
                to,
                CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
        myList.setAdapter(mySimpleCursorAdapter);
        myList.setOnItemClickListener(myOnItemClickListener);
    }

    AdapterView.OnItemClickListener myOnItemClickListener
            = new AdapterView.OnItemClickListener(){
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            Cursor cursor = mySimpleCursorAdapter.getCursor();
            cursor.moveToPosition(position);

            int int_ID = cursor.getInt(cursor.getColumnIndex(MediaStore.Images.Media._ID));
            getThumbnail(int_ID);
        }
    };

    private Bitmap getThumbnail(int id){

        String[] thumbColumns = {thumb_DATA, thumb_IMAGE_ID};

        CursorLoader thumbCursorLoader = new CursorLoader(
                this,
                thumbUri,
                thumbColumns,
                thumb_IMAGE_ID + "=" + id,
                null,
                null);

        Cursor thumbCursor = thumbCursorLoader.loadInBackground();

        Bitmap thumbBitmap = null;
        if(thumbCursor.moveToFirst()){
            int thCulumnIndex = thumbCursor.getColumnIndex(thumb_DATA);

            String thumbPath = thumbCursor.getString(thCulumnIndex);

            Toast.makeText(getApplicationContext(),
                    thumbPath,
                    Toast.LENGTH_LONG).show();

            thumbBitmap = BitmapFactory.decodeFile(thumbPath);

            //Create a Dialog to display the thumbnail
            AlertDialog.Builder thumbDialog = new AlertDialog.Builder(MainActivity.this);
            ImageView thumbView = new ImageView(MainActivity.this);
            thumbView.setImageBitmap(thumbBitmap);
            LinearLayout layout = new LinearLayout(MainActivity.this);
            layout.setOrientation(LinearLayout.VERTICAL);
            layout.addView(thumbView);
            thumbDialog.setView(layout);
            thumbDialog.show();

        }else{
            Toast.makeText(getApplicationContext(),
                    "NO Thumbnail!",
                    Toast.LENGTH_LONG).show();
        }

        return thumbBitmap;
    }
}


activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    android:orientation="vertical"
    tools:context="com.blogspot.android_er.androidlistimages.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" />

    <ListView
        android:id="@+id/mylist"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</LinearLayout>


uses-permission of "android.permission.READ_EXTERNAL_STORAGE" is needed in AndroidManifest.xml.

download filesDownload the files .

Google announced a Developer Preview of Android N!



Developer Preview of Android N released, support new system behaviors to save power and memory. Extend your apps with multi-window UI, direct reply notifications and more.

source: Android Developers Blog - First Preview of Android N: Developer APIs & Tools

Related:
Create AVD of Android N Preview for Android Emulator, in Android Studio

Monday, March 7, 2016

To know how many devices running various Android version, screen size and Open GL version?

Do you want to know how many devices running various Android version?

Android Developers Dashboards provides information about the relative number of devices that share a certain characteristic, such as Android version, screen size and Open GL Version.

The Google Play Developer Console also provides detailed statistics about your users' devices. Those stats may help you prioritize the device profiles for which you optimize your app.


Friday, March 4, 2016

Too busy in background thread of AsyncTask

It's a following of the post "ProgressDialog and AsyncTask". I make the background process of the AsyncTask too busy by removing the Thread.sleep() inside doInBackground(). In such case, the system is too busy to update UI, even cannot update the ProgressBar animation!



The example code refer to the post "ProgressDialog and AsyncTask".

Thursday, March 3, 2016

Restore default build-in wallpaper



Last post "Load photo and set Wallpaper" show how to open photo with Intent of ACTION_OPEN_DOCUMENT/ACTION_GET_CONTENT, then set as Wallpaper with WallpaperManager. This example show how to revert to the system's built-in wallpaper, by calling clear() method of WallpaperManager.


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

import android.app.Activity;
import android.app.WallpaperManager;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

import java.io.FileNotFoundException;
import java.io.IOException;

public class MainActivity extends AppCompatActivity {

    ImageView imageWallpaper;
    Button btnLoadWallpaper, btnDisplayWallpaper, btnRestoreWallpaper;

    private static final int RQS_OPEN_IMAGE = 1;

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

        imageWallpaper = (ImageView)findViewById(R.id.image);

        btnDisplayWallpaper = (Button)findViewById(R.id.displaywp);
        btnDisplayWallpaper.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                displayWallpaper();
            }
        });

        btnLoadWallpaper = (Button)findViewById(R.id.loadwp);
        btnLoadWallpaper.setOnClickListener(btnLoadWallpaperOnClickListener);

        btnRestoreWallpaper = (Button)findViewById(R.id.restorewp);
        btnRestoreWallpaper.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                WallpaperManager myWallpaperManager =
                        WallpaperManager.getInstance(getApplicationContext());
                try {
                    myWallpaperManager.clear();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });

        displayWallpaper();

    }

    View.OnClickListener btnLoadWallpaperOnClickListener = new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            Intent intent = new Intent();

            if (Build.VERSION.SDK_INT >=
                    Build.VERSION_CODES.KITKAT) {
                intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
            } else {
                intent.setAction(Intent.ACTION_GET_CONTENT);
            }

            intent.addCategory(Intent.CATEGORY_OPENABLE);

            // set MIME type for image
            intent.setType("image/*");

            startActivityForResult(intent, RQS_OPEN_IMAGE);
        }
    };

    private void displayWallpaper(){
        WallpaperManager myWallpaperManager =
                WallpaperManager.getInstance(getApplicationContext());
        Drawable drawableWallpaper = myWallpaperManager.getDrawable();
        imageWallpaper.setImageDrawable(drawableWallpaper);

        Toast.makeText(this,
                drawableWallpaper.getMinimumWidth() + " x " + drawableWallpaper.getMinimumHeight()
                        + "\n" +
                        drawableWallpaper.getIntrinsicWidth() + " x " + drawableWallpaper.getIntrinsicHeight(),
                Toast.LENGTH_LONG).show();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == Activity.RESULT_OK) {
            if (requestCode == RQS_OPEN_IMAGE) {
                Uri dataUri = data.getData();
                Uri wallpaperUri = dataUri;
                Toast.makeText(this, wallpaperUri.toString(), Toast.LENGTH_LONG).show();

                Bitmap newOriginalBM= loadBitmap(dataUri);;
                reloadWallpaper(newOriginalBM);
            }
        }
    }

    private Bitmap loadBitmap(Uri src) {

        Bitmap bm = null;

        try {
            bm = BitmapFactory.decodeStream(
                    getBaseContext().getContentResolver().openInputStream(src));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        return bm;
    }

    private void reloadWallpaper(Bitmap bm){
        if(bm != null){
            WallpaperManager myWallpaperManager =
                    WallpaperManager.getInstance(getApplicationContext());

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if(myWallpaperManager.isWallpaperSupported()){
                    try {
                        myWallpaperManager.setBitmap(bm);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }else{
                    Toast.makeText(MainActivity.this,
                            "isWallpaperSupported() NOT SUPPORTED",
                            Toast.LENGTH_LONG).show();
                }
            }else{
                try {
                    myWallpaperManager.setBitmap(bm);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }else{
            Toast.makeText(MainActivity.this, "bm == null", Toast.LENGTH_LONG).show();
        }
    }
}


activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    android:orientation="vertical"
    tools:context="com.blogspot.android_er.androidwallpaper.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" />
    <Button
        android:id="@+id/displaywp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Display Wallpaper"/>
    <Button
        android:id="@+id/loadwp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Load Wallpaper"/>
    <Button
        android:id="@+id/restorewp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Restore default Wallpaper"/>
    <ImageView
        android:id="@+id/image"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>


uses-permission of "android.permission.SET_WALLPAPER" is needed in AndroidManifest.xml.

Next:
Set wallpaper using resource inside APK

Load photo and set Wallpaper


Example to open photo with Intent of ACTION_OPEN_DOCUMENT/ACTION_GET_CONTENT, then set as Wallpaper with WallpaperManager.


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

import android.app.Activity;
import android.app.WallpaperManager;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

import java.io.FileNotFoundException;
import java.io.IOException;

public class MainActivity extends AppCompatActivity {

    ImageView imageWallpaper;
    Button btnLoadWallpaper, btnDisplayWallpaper;

    private static final int RQS_OPEN_IMAGE = 1;

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

        imageWallpaper = (ImageView)findViewById(R.id.image);

        btnDisplayWallpaper = (Button)findViewById(R.id.displaywp);
        btnDisplayWallpaper.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                displayWallpaper();
            }
        });

        btnLoadWallpaper = (Button)findViewById(R.id.loadwp);
        btnLoadWallpaper.setOnClickListener(btnLoadWallpaperOnClickListener);
        displayWallpaper();

    }

    View.OnClickListener btnLoadWallpaperOnClickListener = new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            Intent intent = new Intent();

            if (Build.VERSION.SDK_INT >=
                    Build.VERSION_CODES.KITKAT) {
                intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
            } else {
                intent.setAction(Intent.ACTION_GET_CONTENT);
            }

            intent.addCategory(Intent.CATEGORY_OPENABLE);

            // set MIME type for image
            intent.setType("image/*");

            startActivityForResult(intent, RQS_OPEN_IMAGE);
        }
    };

    private void displayWallpaper(){
        WallpaperManager myWallpaperManager =
                WallpaperManager.getInstance(getApplicationContext());
        Drawable drawableWallpaper = myWallpaperManager.getDrawable();
        imageWallpaper.setImageDrawable(drawableWallpaper);

        Toast.makeText(this,
                drawableWallpaper.getMinimumWidth() + " x " + drawableWallpaper.getMinimumHeight()
                        + "\n" +
                        drawableWallpaper.getIntrinsicWidth() + " x " + drawableWallpaper.getIntrinsicHeight(),
                Toast.LENGTH_LONG).show();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == Activity.RESULT_OK) {
            if (requestCode == RQS_OPEN_IMAGE) {
                Uri dataUri = data.getData();
                Uri wallpaperUri = dataUri;
                Toast.makeText(this, wallpaperUri.toString(), Toast.LENGTH_LONG).show();

                Bitmap newOriginalBM= loadBitmap(dataUri);;
                reloadWallpaper(newOriginalBM);
            }
        }
    }

    private Bitmap loadBitmap(Uri src) {

        Bitmap bm = null;

        try {
            bm = BitmapFactory.decodeStream(
                    getBaseContext().getContentResolver().openInputStream(src));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        return bm;
    }

    private void reloadWallpaper(Bitmap bm){
        if(bm != null){
            WallpaperManager myWallpaperManager =
                    WallpaperManager.getInstance(getApplicationContext());

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if(myWallpaperManager.isWallpaperSupported()){
                    try {
                        myWallpaperManager.setBitmap(bm);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }else{
                    Toast.makeText(MainActivity.this,
                            "isWallpaperSupported() NOT SUPPORTED",
                            Toast.LENGTH_LONG).show();
                }
            }else{
                try {
                    myWallpaperManager.setBitmap(bm);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }else{
            Toast.makeText(MainActivity.this, "bm == null", Toast.LENGTH_LONG).show();
        }
    }
}


activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    android:orientation="vertical"
    tools:context="com.blogspot.android_er.androidwallpaper.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" />
    <Button
        android:id="@+id/displaywp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Display Wallpaper"/>
    <Button
        android:id="@+id/loadwp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Load Wallpaper"/>
    <ImageView
        android:id="@+id/image"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>


uses-permission of "android.permission.SET_WALLPAPER" is needed in AndroidManifest.xml.

download filesDownload the files (Android Studio Format) .

Next:
Restore default build-in wallpaper