Wednesday, May 25, 2016

Optimize power consumption in android app development

Optimize power consumption in android app

For mobile application development it is compulsory that application should not consume more power. In order to provide end users with good battery performance, device manufacturers have a joint responsibility together with all of app developers. Now a day’s mobile operating system provides whole and sole solution for user. User doesn’t need to use their laptops or PCs for small works like e-mail, documents reading etc.

I am sharing few programming things that should be taken care by developer to develop an application with minimum power consumption.

Reducing Network Battery Drain

The network traffic generated by an app can have a significant impact on the battery life of the device where it is running. In order to optimize that traffic, you need to both measure it and identify its source.

 In order to properly optimize your app's use of networking resources, you must understand how frequently your app is using the network and for what reasons.

Analyze how much network traffic use in android application and try to reduce the same for example Wi-Fi network consume less power instead of mobile data therefore if you have some downloading secondary task that can be allow to download in Wi-fi network only.

Use network only when you required do not make unnecessary call in application that request continuously in network with server.

Always optimize background services that should not be continuously running without necessary task.

Network Traffic Tool:

The Network Traffic tool in Android Studio helps you see how your app uses network resources in real time.

To start the Network Traffic tool and visualize the network requests:
1.       Start the Network Traffic tool by launching Android Studio and choosing Tools > Android > Android Device Monitor. When asked, allow incoming network connections.
2.       In the Android Device Monitor window, click the DDMS button along the top and choose the Network Statistics tab. If you don't see this tab, widen the window and then try Window > Reset Perspective.
3.       Select your app to debug from the list of debuggable apps on your device in the Devices tab, then click the Start button in the Network Statistics tab.
  

Optimizing for Doze and App Standby

Doze mode from android 6.0 and higher can affect you application for power reduction therefore at the time of development must test your app with Doze mode and optimize your app.

Doze and App Standby manage the behavior of all apps running on Android 6.0 or higher, regardless whether they are specifically targeting API level 23. To ensure the best experience for users, test your app in Doze and App Standby modes and make any necessary adjustments to your code.

Doze can affect apps differently. You must optimize the way that your app manages network, alarms, jobs, and syncs. Apps should be able to efficiently manage activities during each maintenance window.

Way to test android app with doze mode:

1.       Configure a hardware device or virtual device with an Android 6.0 or higher system image.
2.       Connect the device to your development machine and install your app.
3.       Run your app and leave it active.
4.       Shut off the device screen. (The app remains active.)
5.       Force the system to cycle through Doze modes by running the following commands:

$ adb shell dumpsys battery unplug
$ adb shell dumpsys deviceidle step

You may need to run the second command more than once. Repeat it until the device state changes to idle.

6.       Observe the behavior of your app after you reactivate the device. Make sure the app recovers gracefully when the device exits Doze.

Monitoring the Battery Level and Charging State

The battery-life impact of performing application updates depends on the battery level and charging state of the device. 

In some cases it's also useful to determine the current battery level. You may choose to reduce the rate of your background updates if the battery charge is below a certain level.

Optimize application code for background task or network access according to certain battery limit it make application more smooth and reduce the chance of data lose.

Monitoring the Docking State and Type

Android devices can be docked into car or home, digital and analog docks. Docking state means generally your charging state.

You may choose to increase the update frequency of a sports center app when it's in the desktop dock, or disable your updates completely if the device is car docked. Conversely, you may choose to maximize your updates while car docked if your background service is updating traffic conditions.

Determine docking state:

Register receiver:
IntentFilter ifilter = new IntentFilter(Intent.ACTION_DOCK_EVENT);
Intent dockStatus = context.registerReceiver(null, ifilter);

Extract the current docking status from the EXTRA_DOCK_STATE extra

int dockState = battery.getIntExtra(EXTRA_DOCK_STATE, -1);
boolean isDocked = dockState != Intent.EXTRA_DOCK_STATE_UNDOCKED;

Monitoring the Connectivity Status

 Most of the android application repeating alarms and background services is to schedule regular updates of application data from Internet resources. It might be possible that there is no network or network is very slow to download data in that case network should be monitored and should not run scheduler it is completely meaningless as well as consume power of device.












Wednesday, May 18, 2016

Signature Capture or sign on glass in android

Signature Capture or sign on glass in android:

I am showing implementation of a functionality that is use to capture signature in android. This is generally used in application where user has to do signature like a banking application, logistic delivery, insurance etc.

For capture signature we have to take signature using canvas and save the same in bitmap /.png format to further use.
Here I am explaining only two activities one is main activity and second for capture signature. This two classes can be used in any project. User needs to modify their Layout according to their requirement.  

1)      Create an activity with the signature button and an image view to show signature. From this activity we starts capture activity to click on signature button.

Here the main activity xml code:
activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/sign"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="Signature" />

    <ImageView
        android:id="@+id/signView"
        android:layout_width="300dp"
        android:layout_height="300dp"
        android:layout_gravity="center"
        android:src="@drawable/ic_launcher" />

</LinearLayout>


Here the main activity code:
MainActivity.java

package com.capturesignature;

import com.example.capturesignature.R;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

public class MainActivity extends Activity {
    Button sign;
    ImageView signView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        sign = (Button) findViewById(R.id.sign);
        signView = (ImageView) findViewById(R.id.signView);
        sign.setOnClickListener(onButtonClick);
    }

    Button.OnClickListener onButtonClick = new Button.OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            Intent i = new Intent(MainActivity.this, CaptureSignature.class);
            startActivityForResult(i, 0);
        }
    };

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        // TODO Auto-generated method stub
        if (resultCode == 1) {
            Bitmap b = BitmapFactory.decodeByteArray(
                    data.getByteArrayExtra("byteArray"), 0,
                    data.getByteArrayExtra("byteArray").length);
            signView.setImageBitmap(b);
        }
    }
}



2)      CaptureSignature activity that start from main activity and we can capture signature and save signature on this activity.

Here the signature activity xml code:
capturesignature.xml



<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:orientation="horizontal" >

        <Button
            android:id="@+id/clear"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Clear" />

        <Button
            android:id="@+id/save"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="save" />
    </LinearLayout>

    <LinearLayout
        android:id="@+id/signatureView"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >
    </LinearLayout>

</LinearLayout>



Here the CaptureSignature activity code:
CaptureSignature.java



package com.capturesignature;

import java.io.ByteArrayOutputStream;


import com.example.capturesignature.R;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;

public class CaptureSignature extends Activity {
    signature mSignature;
    Paint paint;
    LinearLayout signatureView;
    Button clear, save;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.capturesignature);

        save = (Button) findViewById(R.id.save);
        save.setEnabled(false);
        clear = (Button) findViewById(R.id.clear);
        signatureView = (LinearLayout) findViewById(R.id.signatureView);

        mSignature = new signature(this, null);
        signatureView.addView(mSignature);

        save.setOnClickListener(onButtonClick);
        clear.setOnClickListener(onButtonClick);
    }

    Button.OnClickListener onButtonClick = new Button.OnClickListener() {
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            if (v == clear) {
                mSignature.clear();
            } else if (v == save) {
                mSignature.save();
            }
        }
    };

    public class signature extends View {
        static final float STROKE_WIDTH = 10f;
        static final float HALF_STROKE_WIDTH = STROKE_WIDTH / 2;
        Paint paint = new Paint();
        Path path = new Path();

        float lastTouchX;
        float lastTouchY;
        final RectF dirtyRect = new RectF();

        public signature(Context context, AttributeSet attrs) {
            super(context, attrs);
            paint.setAntiAlias(true);
            paint.setColor(Color.BLACK);
            paint.setStyle(Paint.Style.STROKE);
            paint.setStrokeJoin(Paint.Join.ROUND);
            paint.setStrokeWidth(STROKE_WIDTH);
        }

        public void clear() {
            path.reset();
            invalidate();
            save.setEnabled(false);
        }

        public void save() {
            Bitmap returnedBitmap = Bitmap.createBitmap(signatureView.getWidth(),
                                signatureView.getHeight(), Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(returnedBitmap);
            Drawable bgDrawable = signatureView.getBackground();
            if (bgDrawable != null)
                bgDrawable.draw(canvas);
            else
                canvas.drawColor(Color.WHITE);
            signatureView.draw(canvas);

            ByteArrayOutputStream bs = new ByteArrayOutputStream();
            returnedBitmap.compress(Bitmap.CompressFormat.PNG, 50, bs);
            Intent intent = new Intent();
            intent.putExtra("byteArray", bs.toByteArray());
            setResult(1, intent);
            finish();
        }

        @Override
        protected void onDraw(Canvas canvas) {
            // TODO Auto-generated method stub
            canvas.drawPath(path, paint);
        }

        @Override
        public boolean onTouchEvent(MotionEvent event) {
            float eventX = event.getX();
            float eventY = event.getY();
            save.setEnabled(true);

            switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                path.moveTo(eventX, eventY);
                lastTouchX = eventX;
                lastTouchY = eventY;
                return true;

            case MotionEvent.ACTION_MOVE:

            case MotionEvent.ACTION_UP:

                resetDirtyRect(eventX, eventY);
                int historySize = event.getHistorySize();
                for (int i = 0; i < historySize; i++) {
                    float historicalX = event.getHistoricalX(i);
                    float historicalY = event.getHistoricalY(i);
                    path.lineTo(historicalX, historicalY);
                }
                path.lineTo(eventX, eventY);
                break;
            }

            invalidate((int) (dirtyRect.left - HALF_STROKE_WIDTH),
                    (int) (dirtyRect.top - HALF_STROKE_WIDTH),
                    (int) (dirtyRect.right + HALF_STROKE_WIDTH),
                    (int) (dirtyRect.bottom + HALF_STROKE_WIDTH));

            lastTouchX = eventX;
            lastTouchY = eventY;

            return true;
        }

        private void resetDirtyRect(float eventX, float eventY) {
            dirtyRect.left = Math.min(lastTouchX, eventX);
            dirtyRect.right = Math.max(lastTouchX, eventX);
            dirtyRect.top = Math.min(lastTouchY, eventY);
            dirtyRect.bottom = Math.max(lastTouchY, eventY);
        }
    }
}

This two activity classes can be copied in any project for use same source .









Tuesday, May 17, 2016

Serialization and Parcelable in android

Serialization and Parcelable in android:

Serialization and parcelable both used for marshaling and unmarshaling of object and send data from one android component to other component.

Parcelable:

When we want to pass objects between two components in Android, these objects have to implements Android Parcelable interface. Parcelable in Android is similar to serialization and deserialization mechanism as we are used in Java.

 In Parcelable, developers write custom code for marshaling and unmarshaling so it creates less garbage objects in comparison to Serialization. The performance of Parcelable over Serialization dramatically improves, because of this custom implementation.

Ex:
public class MyParcelable implements Parcelable {
     private String name;
     private String lastName;


     public int describeContents() {
         return 0;
     }

     public void writeToParcel(Parcel out, int flags) {
         out.writeInt(name);
         out.writeInt(lastName);



     }



     public static final Parcelable.Creator<MyParcelable> CREATOR

             = new Parcelable.Creator<MyParcelable>() {

         public MyParcelable createFromParcel(Parcel in) {

             return new MyParcelable(in);

         }



         public MyParcelable[] newArray(int size) {

             return new MyParcelable[size];

         }

     };

     

     private MyParcelable(Parcel in) {

         name = in.readString();
   lastName = in.readString();



     }

 }


Syntax to send object

Intent i = new Intent();
i.putExtra("name_of_extra", myParcelableObject);


Syntax to receive object

Intent i = getIntent();
MyParcelable myParcelableObject = (MyParcelable) i.getParcelableExtra("name_of_extra");
 
 
 
 
Serialization:

Serialization is the process of converting an object's state (including its references) to a sequence of bytes, as well as the process of rebuilding those bytes into a live object at some future time.
This process is in java therefore we can use the same in android for passing object from one component to other component.

Serialization is a marker interface, which implies the user cannot marshal the data according to their requirements. In Serialization, a marshaling operation is performed on a Java Virtual Machine (JVM) using the Java reflection API. This helps identify the Java objects member and behavior, but also ends up creating a lot of garbage objects. Due to this, the Serialization process is slow in compare to parcelable.

Ex:


import java.io.Serializable;
 
public class Person implements Serializable {
  private String firstName;
  private String lastName;
  
 
  public Person(String firstName, String lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }
 
  public String getFirstName() {
    return firstName;
  }
 
  public void setFirstName(String firstName) {
    this.firstName = firstName;
  }
 
  public String getLastName() {
    return lastName;
  }
 
  public void setLastName(String lastName) {
    this.lastName = lastName;
  }
} 

 
Syntax to send object

Intent i = new Intent();
i.putExtra("name_of_extra", mySerialableObject);

Syntax to receive object

Intent i = getIntent();
Person mySerialableObject = (Person) 
i.getSerializableExtra ("name_of_extra");
 
 

Difference between Serialization and Parcelable:

 Differences between the two are often cited around implementation techniques and performance results
1)      Parcelable is well documented in the Android SDK whereas serialization is available in Java.

2)      Developers needs to write custom code for marshaling and unmarshaling so it creates less garbage objects in compare to Serialization.


3)      In Serialization object marshaling operation is performed on a Java Virtual Machine (JVM) using the Java reflection API and Serializable is a marker interface, which implies the user cannot marshal the data according to their requirements therefore it create lots of garbage object due to that it is slow in compare to parcelable.



Which one is better to use in android:

Parcelable takes little more time in implementation due to custom marshaling but it performs around two times faster to serialization therefore always use parcalable in android instead of serialization for passing object between android components.




Monday, May 16, 2016

Apache HttpClient and HttpUrlConnection for android

APACHE HTTP CLIENT AND HTTP URL CONNECTION FOR ANDROID:

Http client and HttpUrlConnection both are used to make connection over HTTP to communicate through server in android. From android M (6.0) apache http client is officially deprecated from android and from gingerbread (2.3) it is suggested to use HttpUrlConnection instead of HttpClient .

Quote from android official site “Android 6.0 release removes support for the Apache HTTP client. If your app is using this client and targets Android 2.3 (API level 9) or higher, use the HttpUrlConnection class instead. This API is more efficient because it reduces network use through transparent compression and response caching, and minimizes power consumption.”

HTTP CLIENT:

Http client project represents an effort to provide an implementation of Apache HttpClient, which can be deployed on Google Android in parallel to the outdated version shipped with the platform while remaining partially API compatible with Apache HttpClient 4.3.

There is few changes that has to be different from the stock version of apache HttpClient and android version of apache HttpClient.
1.       Compiled against HttpClient 4.0 APIs.
2.       Commons Logging replaced with Android Logging.
3.       Base64 implementation from Commons Codec replaced with Android Base64.
4.       Android default SSLSocketFactory used by for SSL/TLS connections.

There is few things about http client that is good for web browser but it is not as good as for android.
Android operate on small devices there for it require less battery consumption, small API for memory purpose etc.
1.       Large and extensive APIs
2.       Supports cookie handling, authentication and connection management
3.       More suitable for web browser and other web applications, because of its large size
4.       Does not support HttpResponseCache mechanism, hence leading to increased network usage and battery consumption.

HTTP URLCONNECTION:

HttpUrlConnection is a light weight HTTP client, used to access network resources, and hence, suitable for mobile applications and recommended by Google to use HttpUrlConnection, instead of the other HTTP clients.

According to google blog Apache HTTP client has fewer bugs on Eclair and Froyo. It is the best choice for these releases. For Gingerbread, HttpURLConnection is the best choice. It’s simple API and small size makes it great fit for Android.
Transparent compression and response caching reduce network use, improve speed and save battery. New applications should use HttpURLConnection; it is where we will be spending our energy going forward.”

Advantage of HttpUrlConnection that is useful for android

1.       Light weight APIs helps in easier management and reduces compatibility issues.
2.       Automatic handling of the caching mechanisms, with the help of HttpResponseCache.
3.       Reduces the network usage and also, the battery consumption.





Wednesday, May 11, 2016

Android Custom Permission with example

Android Custom Permission:

Android allows mobile application developers to define custom permissions in their apps. Custom permissions are often used to protect different application components, such as Activities, Services, Content Providers, and Broadcast Receivers, from 3rd- party applications installed on the device. For example, if an organization wanted to share data between a few of its own Android applications, it could use Content Providers via custom permissions to share the data.

Declare Syntex:
<permission android:description="string resource"
            android:icon="drawable resource"
            android:label="string resource"
            android:name="string"
            android:permissionGroup="string"
            android:protectionLevel=["normal" | "dangerous" |
                                     "signature" | "signatureOrSystem"] />

Access syntax:
<uses-permission android:name=" string "/>


Here android:name and android:protectionLevel are mandatory attribute other are optional > It is a good practice to add all attribute.

Android Name:

The name of the permission. This is the name that will be used in code to refer to the permission — for example, in a <uses-permission> element and the permission attributes of application components.
The name must be unique, so it should use Java-style scoping — for example, "com.example.project.PERMITTED_ACTION".

Protection Level:

Characterizes the potential risk implied in the permission and indicates the procedure the system should follow when determining whether or not to grant the permission to an application requesting it. The value can be set to one of the following strings:
1.       Normal: Low Risk. This is the default protection level. Automatically granted to the application upon installation. The user’s approval is not required during installation.

2.       Dangerous: Higher Risk than Normal. User’s approval is required before an application is granted this permission.


3.       Signature: Only applications that have the same signature as of the application defining the permission are granted this permission. The user’s approval is not required during installation.

4.       SignatureOrSystem: Only applications in the android’s system image or applications that have the same signature as of the application defining the permission are granted this permission. The user’s approval is not required during installation.



Here I want to take an example like in my one app I have create an activity and this activity would be accessible from other client app with specific permission then we have to implement an custom permission for the same. Custom permission can be protect any android component like Activities, services etc.
Application with custom permission is mandatory to install first and then user can install second app.

             First app with declared custom permission

Here is the manifest file of my first application in which I declare permission and protect to provide access other client application.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.mypackage.mycustompermissin"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="10" />
    <permission android:name="com.mypackage.mypermission" android:label="my_permission" android:protectionLevel="dangerous"></permission>

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:permission="com.mypackage.mypermission"
            android:name=".PermissionTestActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

            <intent-filter >
                <action android:name="com.mypackage.permissiontestclient.MyAction" />
                <category android:name="android.intent.category.DEFAULT" />               
            </intent-filter>
        </activity>
    </application>

</manifest>

Activity here I am showing only blank activity for example purpose.

package com.mypackage.mycustompermissin;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class PermissionTestActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

  }
}



   Second app with uses permission:

This is the second application uses permission which we declared in first application. In this application we are opening the first application that we secured from android custom permissions.
Here is  Manifest file  

<?xml version="1.0" encoding="utf-8"?>
<uses-sdk android:minSdkVersion="10" />
<uses-permission android:name="com.mypackage.client "/>

<application
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name" >
    <activity
        android:name=".PermissionTestClientActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

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

</manifest>


Activity that calls first application activity with permissions.


package  com.mypackage.client;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class PermissionTestClientActivity extends Activity {

    private static final String TAG = "PermissionTestClientActivity";
    Button btnTest;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        btnTest = (Button) findViewById(R.id.btnTest);
        btnTest.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Log.d(TAG, "Button click");
                Intent in = new Intent();
                in.setAction("com.mypackage.permissiontestclient.MyAction");
                in.addCategory("android.intent.category.DEFAULT");
                startActivity(in);
            }
        });
    }
}