Monday, September 26, 2016

Working with 3D - OpenGl ES

Hi .... Dear All ....  Today I am uploading a superb example of OpenGL ES.
In this example i am drawing a Triangle using OpenGL ES.
What is OpenGL ES???
•       Android provides many tools for creating handy and great looking user interface for the applications.
•       The OpenGL ES APIs, which comes as part of Android, has many helper classes and methods that assist in displaying high-end and animated graphics.
•       Most of the android phones come with a dedicated Graphical Processing Unit (GPU); hence the compositing and rendering can be accelerated using this additional hardware. 

Let us now see how to use OpenGL ES APIs to define and draw shapes.
Steps to use the APIs:
  1. Define shapes that will be rendered on screen – Eg: Triangle, Rectangle.
  2. Create our renderer android.opengl.GLSurfaceView.Renderer to render the shape on Surface View.
  3. Extend the android.opengl.GLSurfaceView to create our own surface on which the shapes will be composed.
  4. Finally create an Activity that will show these Graphic shapes by using above View. 
Lets start with step 1 
     package com.exam.ravi.graphicsex2;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import android.opengl.GLES20;

/** * A two-dimensional triangle for use as a drawn object in OpenGL ES 2.0. */

public class Triangle {

    private final String shaderCode =
            "uniform mat4 uMVPMatrix;" +
                    "attribute vec4 vPosition;" +
                    "void main() {" +
                    "  gl_Position = uMVPMatrix * vPosition;" +
                    "}";

    private final String fragShaderCode =
            "precision mediump float;" +
                    "uniform vec4 vColor;" +
                    "void main() {" +
                    "  gl_FragColor = vColor;" +
                    "}";

    private final FloatBuffer vertexBuffer;
    private final int anInt;
    private int mpositionhandle;
    private int mcolorhandle;
    private int mmvpmatrixhandle;

    static final int COORDS_PER_VERTEX = 3;
    static float triangleCoords[] = {
            0.0f,  0.622008459f, 0.0f,   // top    
                -0.5f, -0.311004243f, 0.0f,   // bottom left 
                0.5f, -0.311004243f, 0.0f    // bottom right    };
         private final int vertexcount = triangleCoords.length / COORDS_PER_VERTEX;
    private final int vertexstride = COORDS_PER_VERTEX * 4;  // 4 bytes per vertex
    float color[] = { 0.63671875f, 0.76953125f, 0.22265625f, 0.0f };
    public Triangle() {
        ByteBuffer byteBuffer = ByteBuffer.allocateDirect(
                triangleCoords.length * 4);
        byteBuffer.order(ByteOrder.nativeOrder());

        vertexBuffer = byteBuffer.asFloatBuffer();
        vertexBuffer.put(triangleCoords);
        vertexBuffer.position(0);

        int vertexShader = MyRenderer.loadShader(
                GLES20.GL_VERTEX_SHADER, shaderCode);
        int fragmentShader = MyRenderer.loadShader(
                GLES20.GL_FRAGMENT_SHADER, fragShaderCode);

        anInt = GLES20.glCreateProgram();          
        GLES20.glAttachShader(anInt, vertexShader);   
        GLES20.glAttachShader(anInt, fragmentShader); 
        GLES20.glLinkProgram(anInt);                  

    }

    /**     * Encapsulates the OpenGL ES instructions for drawing this shape.     *   
               * @param mvpMatrix - The Model View Project matrix in which to draw   
                 * this shape.     */    public void draw(float[] mvpMatrix) {
     
        GLES20.glUseProgram(anInt);
        mpositionhandle = GLES20.glGetAttribLocation(anInt, "vPosition");
        GLES20.glEnableVertexAttribArray(mpositionhandle);
        GLES20.glVertexAttribPointer(
                mpositionhandle, COORDS_PER_VERTEX,
                GLES20.GL_FLOAT, false,
                vertexstride, vertexBuffer);

        mcolorhandle = GLES20.glGetUniformLocation(anInt, "vColor");

        GLES20.glUniform4fv(mcolorhandle, 1, color, 0);

        mmvpmatrixhandle = GLES20.glGetUniformLocation(anInt, "uMVPMatrix");
        MyRenderer.checkGlError("glGetUniformLocation");
        GLES20.glUniformMatrix4fv(mmvpmatrixhandle, 1, false, mvpMatrix, 0);
        MyRenderer.checkGlError("glUniformMatrix4fv");

        GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexcount);

        GLES20.glDisableVertexAttribArray(mpositionhandle);
    }

}

Step II 
     package com.exam.ravi.graphicsex2;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.opengl.Matrix;
import android.util.Log;

public class MyRenderer implements GLSurfaceView.Renderer {

    private static final String TAG = "MyRenderer";
    private Triangle mTriangle;
    private final float[] mMVPMatrix = new float[16];
    private final float[] mProjectionMatrix = new float[16];
    private final float[] mViewMatrix = new float[16];
    private final float[] mRotationMatrix = new float[16];

    private float mAngle;

    @Override   
           public void onSurfaceCreated(GL10 unused, EGLConfig config) {

        GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

        mTriangle = new Triangle();
    }

    @Override   
             public void onDrawFrame(GL10 unused) {
        float[] scratch = new float[16];
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);

        Matrix.setLookAtM(mViewMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);

        Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0);


        Matrix.setRotateM(mRotationMatrix, 0, mAngle, 0, 0, 1.0f);

        Matrix.multiplyMM(scratch, 0, mMVPMatrix, 0, mRotationMatrix, 0);

        mTriangle.draw(scratch);
    }

    @Override    public void onSurfaceChanged(GL10 unused, int width, int height) {
        GLES20.glViewport(0, 0, width, height);

        float ratio = (float) width / height;

        Matrix.frustumM(mProjectionMatrix, 0, -ratio, ratio, -1, 1, 3, 7);

    }

    /**     * Utility method for compiling a OpenGL shader.    
          *     * <p><strong>Note:</strong> When developing shaders, use the checkGlError()  
                * method to debug shader coding errors.</p>
     *     * @param type - Vertex or fragment shader type.    
                 * @param shaderCode - String containing the shader code.   
               * @return - Returns an id for the shader.     */   
           public static int loadShader(int type, String shaderCode){

        int shader = GLES20.glCreateShader(type);

        GLES20.glShaderSource(shader, shaderCode);
        GLES20.glCompileShader(shader);

        return shader;
    }

    /**     * Utility method for debugging OpenGL calls. Provide the name of the call 
                 * just after making it:     *     * <pre>
     
            * mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");   
                 * MyRenderer.checkGlError("glGetUniformLocation");</pre>
 
       *       * If the operation is not successful, the check throws an error.     *   
                * @param glOperation - Name of the OpenGL call to check.     */    
         public static void checkGlError(String glOperation) {
        int error;
        while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
            Log.e(TAG, glOperation + ": glError " + error);
            throw new RuntimeException(glOperation + ": glError " + error);
        }
    }

    /**     * Returns the rotation angle of the triangle shape (mTriangle).     *    
                 * @return - A float representing the rotation angle.     */   
        public float getAngle() {
        return mAngle;
    }

    public void setAngle(float angle) {
        mAngle = angle;
    }
}

Step III
     package com.exam.ravi.graphicsex2;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.opengl.GLSurfaceView;

public class MainActivity extends AppCompatActivity {

    private GLSurfaceView glSurfaceView;

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

        glSurfaceView = new MySurfaceView(this);
        setContentView(glSurfaceView);
    }

    @Override    protected void onPause() {
        super.onPause();
        glSurfaceView.onPause();
    }

    @Override    protected void onResume() {
        super.onResume();
        glSurfaceView.onResume();
    }
}

Step IV

     package com.exam.ravi.graphicsex2;
import android.content.Context;
import android.opengl.GLSurfaceView;
import android.view.MotionEvent;

public class MySurfaceView extends GLSurfaceView {

    private final MyRenderer mRenderer;

    public MySurfaceView(Context context) {
        super(context);
        setEGLContextClientVersion(2);

        mRenderer = new MyRenderer();
        setRenderer(mRenderer);

        setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
    }
}

Output will be like 



Friday, September 23, 2016

Inter Process Communication - Android Interface Definition Language

Hi .... Dear All ....  Today I am uploading a superb example of Inter Process Communication in Android.
In this example i am using a popular concept of AIDL.
What is Interprocess Communication??? 


In IPC a method is called by an activity or other application component, but executed remotely (in another process), with any result returned back to the caller.
This entails decomposing a method call and its data to a level the operating system can understand, transmitting it from the local process and address space to the remote process and address space, then reassembling and reenacting the call there.
 Return values are then transmitted back to caller.
 Android provides all the code to perform these IPC transactions, so you can focus on defining and implementing the RPC programming interface.
To implement  IPC, your application must bind to a service, using bindService().

Android Interface Definition Language (AIDL)

It allows you to define the programming interface that both the client and service agree upon in order to communicate with each other using interprocess communication.

On Android, one process cannot normally access the memory of another process. 

So to talk, they need to decompose their objects into primitives that the operating system can understand, and marshall the objects across that boundary for you. 

The code to do that marshalling is tedious to write, so Android handles it for you with AIDL.

See my example .....

A. How to define AIDL .... steps 
-> first create a aidl folder in res folder.
-> In this folder create a aidl file.
-> This file is actually interface so declare all methods here.
-> After done all these steps please Rebuild project once.
see my aidl file named as   IRemSer.aidl

// IRemSer.aidlpackage aidl;

// Declare any non-default types here with import statements
interface IRemSer {
            String sayHello(String msg);
            int add_num(int a,int b);
}  

B. Create a service to implement this aidl interface 
Register service in manifest file 
In  my example i had created service named as DemoService.java as
package com.example.ravigodara.ipcaidl;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.annotation.Nullable;

import aidl.IRemSer;


public class DemoService extends Service   {
    @Nullable    @Override

    public IBinder onBind(Intent intent) {
        return mBinder;
    }
 private final IRemSer.Stub mBinder = new IRemSer.Stub() {
     @Override     public String sayHello(String msg) throws RemoteException {
         return "Hello"+ msg;
     }

     @Override

     public int add_num(int a, int b) throws RemoteException {
         return (a+b);
     }

 };
}

C. Create you MainActivity and call the service 
In my example i had created MainActivity.java as 
package com.example.ravigodara.ipcaidl;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

import aidl.IRemSer;

public class DemoSerAct extends AppCompatActivity {

    IRemSer mIRemSer;
    Intent intent;
    EditText first,second,res;
    int fnum,snum,result;
    ServiceConnection scon = new ServiceConnection() {
        @Override

        public void onServiceConnected(ComponentName name, IBinder service) {
            mIRemSer = IRemSer.Stub.asInterface(service);
            startService(intent);
        }

        @Override

        public void onServiceDisconnected(ComponentName name) {
            mIRemSer=null;
        }
    };
    @Override

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        first  = (EditText) findViewById(R.id.editText);
        second  = (EditText) findViewById(R.id.editText2);
        res  = (EditText) findViewById(R.id.editText3);



    }
    public void startServ(View view)
    {
        fnum = Integer.parseInt(first.getText().toString());
        snum = Integer.parseInt(second.getText().toString());
        intent=new Intent(this,DemoService.class);
        bindService(intent, scon, Context.BIND_AUTO_CREATE);
    }
    public void stopServ(View view)
    {
        unbindService(scon);
    }
    public void callSer(View view)
    {
        String retmsg = null;
        try {
            retmsg = mIRemSer.sayHello("Godara");
            result = mIRemSer.add_num(fnum,snum);
            Log.d("ravi",String.valueOf(result));
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        Toast.makeText(this,"Sevice Returned Message "+retmsg,
                                          Toast.LENGTH_LONG).show();
        res.setText(String.valueOf(result));
    }
}

D. The layout file is like activity_main.xml as 

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    tools:context="com.example.ravigodara.ipcaidl.MainActivity">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="StartService"
        android:id="@+id/button1"
        android:onClick="startServ"
        android:layout_alignBaseline="@+id/button"
        android:layout_alignBottom="@+id/button"
        android:layout_alignParentStart="true" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="StopService"
        android:id="@+id/button2"
        android:onClick="stopServ"
        android:layout_alignTop="@+id/button1"
        android:layout_alignParentEnd="true" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="callSer"
        android:text="CallSer"
        android:id="@+id/button"
        android:layout_below="@+id/editText2"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="54dp" />

    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/editText"
        android:layout_alignParentTop="true"
        android:layout_alignParentStart="true"
        android:layout_alignEnd="@+id/button2"
        android:hint="First Number"/>

    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/editText2"
        android:layout_below="@+id/editText"
        android:layout_alignParentStart="true"
        android:layout_alignEnd="@+id/editText"
        android:hint="Second Number"/>

    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/editText3"
        android:layout_below="@+id/button1"
        android:layout_marginTop="75dp"
        android:layout_alignParentStart="true"
        android:layout_alignEnd="@+id/button2"
        android:hint="Result....."/>
</RelativeLayout>   

Output would be like this 
First start service then call service 
A.    



B.   


Sunday, September 18, 2016

AsyncTask in Android @ Better than Thread

Hi .... Dear All ....  Today I am uploading a superb example of AsyncTask.
In this example i have one Main Thread and a AsyncTask.
 
AsyncTask updates the status on UI thread.
Just see this example first otherwise you can't undersatnd the importance of AsyncTask.

http://androidclue4u.blogspot.in/2016/09/thread-in-android-worker-and-main.html

AsyncTask is an Abstract class belonging to Android’s OS framework.
It allows us to interact with the UI thread efficiently and performs time-consuming jobs in another thread.
It is an ideal choice for operation that can be completed in short time.
  To implement an AsyncTask, we need to know about the three generic type params
  1. Params: This generic is to specify the type of the parameters that you want to send to the task for execution
  2. Progress: This is to define the type of progress parameter.
  3. Result: Return type for background execution. 

A. Output will be same as previous example 
B. Layout files are also same 
C. Java code is as 

package com.exam.ravi.threadasync;

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

public class AsyncActivity extends AppCompatActivity {

    @Override    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_async);
        CountingTask countingTask = new CountingTask();
        countingTask.execute();
    }

    private class CountingTask extends AsyncTask<Void, Integer, Integer> {
        CountingTask() {}
        @Override        protected Integer doInBackground(Void... params) {
            int count = 0;
            while (count < 100) {
                SystemClock.sleep(200);
                count++;
                if (count % 10 == 0) {
                    publishProgress(count);
                }
            }
            return count;
        }

        @Override        protected void onProgressUpdate(Integer... params) {

            TextView textView = (TextView) findViewById(R.id.counter);
            textView.setText(params[0]+"% Complete");
        }

        @Override        protected void onPostExecute(Integer params) {
            TextView textView = (TextView) findViewById(R.id.counter);
            textView.setText(" Task Completed");
        }
    }
}

Thread In Android @ Worker and Main Thread - Communication

Hi .... Dear All ....  Today I am uploading a superb example of Multi-threading. 
In this example i have one Main Thread / UI Thread and worker thread.
Worker thread updates the status on UI thread.
•    Threads are lightweight processes, which allow us to perform jobs in parallel and concurrent manner.
•      Android starts a process with a single thread for execution called the “Main thread” or “UI Thread”.
•       Capable of handling multiple threads
•       Different threads need different priorities
Thread Life Cycle
In Android we can classify threads based on their Access to UI toolkit. Thus we have two types of thread
  1. UI thread
  2. Worker thread
UI thread
We have already seen that the application starts its execution with a single thread called the UI thread.
Since the UI thread is responsible for the user’s interaction with the UI components.
Android UI toolkit is not thread safe. This means that other thread cannot access the UI toolkit.
In order to manipulate the widgets, we must follow these two golden rules.
  • Always access the UI toolkit from the UI thread only.
  • Never block the UI thread
Worker Thread
Worker threads are created to remove long time-consuming jobs off from the UI thread.
These threads are vital for the responsiveness of the application, given that UI thread can’t be blocked.
Basically, all network related operations like fetching data from web services, downloading files, etc., database queries, IO operations like reading or writing to a file, time consuming calculations etc. are performed on these threads.
To overcome this problem, Android has a work around solution allows us to post task to the UI thread from any thread. Following are the method which helps us achieve this.
  • View.post(Runnable)
  • Activity.runOnUiThread(Runnable)
  • View.postDelayed(Runnable,timeInMillis
See an Example 
A. Output will be like 
a.

b.

B. XML files are 
<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    tools:context=".ThreadActivity">

    <TextView        android:id="@+id/counter"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="40dp"
        android:layout_centerVertical="true"
        android:layout_alignParentEnd="true"
        android:textAlignment="center"/>
</RelativeLayout>

C. Java code is as 
package com.exam.ravi.threadex1;

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

public class ThreadActivity extends AppCompatActivity {
     TextView textView;
    @Override    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_thread);
        textView = (TextView) findViewById(R.id.counter);
        new Thread(new Runnable() {
            @Override            public void run() {
           int i=0;
                while(i<100)
                {
                    SystemClock.sleep(200);
                    i++;
                    final int curCount =i;
                    if(curCount%10==0)
                    {
                        textView.post(new Runnable() {
                            @Override                            public void run() {
                                textView.setText(curCount+"% Complete");
                            }
                        });
                    }
                }
                textView.post(new Runnable() {
                    @Override                    public void run() {
                        textView.setText("Count Completed");
                    }
                });
            }
        }).start();
    }
}