SHA-1 encryption in android

private static String convertToHex(byte[] data) {
		StringBuilder buf = new StringBuilder();
		for (byte b : data) {
			int halfbyte = (b >>> 4) & 0x0F;
			int two_halfs = 0;
			do {
				buf.append((0 <= halfbyte) && (halfbyte <= 9) ? (char) ('0' + halfbyte) : (char) ('a' + (halfbyte - 10)));
				halfbyte = b & 0x0F;
			} while (two_halfs++ < 1);
		}
		return buf.toString();
	}

	public static String computeSHAHash(String text) {
		MessageDigest md;
		byte[] sha1hash = null;
		try {
			md = MessageDigest.getInstance("SHA-1");
			md.update(text.getBytes("iso-8859-1"), 0, text.length());
			sha1hash  = md.digest();
		} catch (Exception e) {
			e.printStackTrace();
		}

		return convertToHex(sha1hash);
	}

How to read file from asset in Android?

E.g. Consider fileName as “myfile.txt”

public String ReadFromAssetfile(String fileName) {
	    StringBuilder returnString = new StringBuilder();
	    InputStream fIn = null;
	    InputStreamReader isr = null;
	    BufferedReader input = null;
	    try {
	        fIn = getResources().getAssets()
	                .open(fileName, Context.MODE_WORLD_READABLE);
	        isr = new InputStreamReader(fIn);
	        input = new BufferedReader(isr);
	        String line = "";
	        while ((line = input.readLine()) != null) {
	            returnString.append(line);
	        }
	    } catch (Exception e) {
	        e.getMessage();
	    } finally {
	        try {
	            if (isr != null)
	                isr.close();
	            if (fIn != null)
	                fIn.close();
	            if (input != null)
	                input.close();
	        } catch (Exception e2) {
	            e2.getMessage();
	        }
	    }
	    return returnString.toString();
	}

Service vs Intent service

Service

  1. Task with no UI,but should not use for long Task. Use Thread within service for long Task
  2. invoke by onStartService()
  3. Triggered from any Thread
  4. Runs On Main Thread
  5. May block main(UI) thread

IntentService

  1. Long task usually no communication with main thread if communication is needed then it is done by Handler or broadcast
  2. invoke via Intent
  3. triggered from Main Thread (Intent is received on main Thread and worker thread is spawed)
  4. runs on separate thread
  5. can’t run task in parallel and multiple intents are Queued on the same worker thread.

How to access SSL webservice in Android

Most recently I have faced with error when accessing https service in android.The problem was “javax.net.ssl.SSLPeerUnverifiedException: No peer certificate”.So I can’t access it normal way.I searched on internet and had some workaround for fix that problem.

First we need to override SSLSocketFactory and create new one.

import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;


import org.apache.http.conn.ssl.SSLSocketFactory;

public class ExSSLSocketFactory extends SSLSocketFactory {
  SSLContext sslContext = SSLContext.getInstance("TLS");

    public ExSSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
        super(truststore);
        TrustManager x509TrustManager = new X509TrustManager() {
            public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            }

            public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            }

            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }
        };
       
        sslContext.init(null, new TrustManager[] { x509TrustManager }, null);
    }

    public ExSSLSocketFactory(SSLContext context) throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException, UnrecoverableKeyException {
       super(null);
       sslContext = context;
    }

    @Override
    public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {
        return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
    }

    @Override
    public Socket createSocket() throws IOException {
        return sslContext.getSocketFactory().createSocket();
    }
}

after that we have to create modified HttpClient insteed of DefaultHttpClient in apache using created SSLSocketFactory

public static HttpClient getHttpsClient(HttpClient client) {
     try{
		   X509TrustManager x509TrustManager = new X509TrustManager() { 	           
				@Override
				public void checkClientTrusted(X509Certificate[] chain,
						String authType) throws CertificateException {
				}

				@Override
				public void checkServerTrusted(X509Certificate[] chain,
						String authType) throws CertificateException {
				}

				@Override
				public X509Certificate[] getAcceptedIssuers() {
					return null;
				}
	        };
	        
	        SSLContext sslContext = SSLContext.getInstance("TLS");
	        sslContext.init(null, new TrustManager[]{x509TrustManager}, null);
	        SSLSocketFactory sslSocketFactory = new ExSSLSocketFactory(sslContext);
	        sslSocketFactory.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
	        ClientConnectionManager clientConnectionManager = client.getConnectionManager();
	        SchemeRegistry schemeRegistry = clientConnectionManager.getSchemeRegistry();
	        schemeRegistry.register(new Scheme("https", sslSocketFactory, 443));
	        return new DefaultHttpClient(clientConnectionManager, client.getParams());
	    } catch (Exception ex) {
	        return null;
	    }
	}

Then we can use this HttpClient to deal with Https enable service.

public static String sendData(String id,String name) {
	String resutString="";
	StringBuilder builder = new StringBuilder();
	HttpClient client = Utils.getHttpsClient(new DefaultHttpClient());
	HttpParams params = new BasicHttpParams();
        HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
        HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);

		try {
			//Add your request URL
			String url = "https://www.webservice/sendnfctag";
			JSONObject nfcTag=new  JSONObject();
			nfcTag.put("Value", id);
			nfcTag.put("Other",name);

			
			HttpPost httpPost = new HttpPost(url);
			httpPost.setParams(params);
			StringEntity entity = new StringEntity(nfcTag.toString(), HTTP.UTF_8);
			entity.setContentType("application/json");
			httpPost.setEntity(entity);
			HttpResponse response = client.execute(httpPost);
			StatusLine statusLine = response.getStatusLine();
			int statusCode = statusLine.getStatusCode();
			
			

			if (statusCode == 200) {
				HttpEntity entityResponse = response.getEntity();
				InputStream content = entityResponse.getContent();
				BufferedReader reader = new BufferedReader(new InputStreamReader(content));
				String line=null;
				while ((line = reader.readLine()) != null) {
					builder.append(line+"\n");
				}
				reader.close();
				resutString=builder.toString();
				Log.d(TAG,"Successfuly :"+resutString);
			} else {
				Log.d(TAG,"Error seding data");
			}
		} catch (ConnectTimeoutException e) {
			Log.w("Connection Tome Out", e);
		} catch (ClientProtocolException e) {
			Log.w("ClientProtocolException", e);
		} catch (SocketException e) {
			Log.w("SocketException", e);
		} catch (IOException e) {
			Log.w("IOException", e);
		} catch (JSONException e) {
			e.printStackTrace();
		}
		return resutString;
	}

Implement Rate It feature in Android App

app raterI implemented this a while back, to some extent. It is impossible to know whether or not a user has rated an app, to prevent ratings from becoming a currency (some developers might add an option like “Rate this app and get so and so in the app for free”).

The class I wrote provides three buttons, and configures the dialog so that it is only shown after the app has been launched n times (users have a higher chance of rating the app if they’ve used it a bit before. Most of them are unlikely to even know what it does on the first run):

public class AppRater {
    private final static String APP_TITLE = "App Name";// App Name
    private final static String APP_PNAME = "com.example.name";// Package Name

    private final static int DAYS_UNTIL_PROMPT = 3;//Min number of days
    private final static int LAUNCHES_UNTIL_PROMPT = 3;//Min number of launches

    public static void app_launched(Context mContext) {
        SharedPreferences prefs = mContext.getSharedPreferences("apprater", 0);
        if (prefs.getBoolean("dontshowagain", false)) { return ; }

        SharedPreferences.Editor editor = prefs.edit();

        // Increment launch counter
        long launch_count = prefs.getLong("launch_count", 0) + 1;
        editor.putLong("launch_count", launch_count);

        // Get date of first launch
        Long date_firstLaunch = prefs.getLong("date_firstlaunch", 0);
        if (date_firstLaunch == 0) {
            date_firstLaunch = System.currentTimeMillis();
            editor.putLong("date_firstlaunch", date_firstLaunch);
        }

        // Wait at least n days before opening
        if (launch_count >= LAUNCHES_UNTIL_PROMPT) {
            if (System.currentTimeMillis() >= date_firstLaunch + 
                    (DAYS_UNTIL_PROMPT * 24 * 60 * 60 * 1000)) {
                showRateDialog(mContext, editor);
            }
        }

        editor.commit();
    }   

    public static void showRateDialog(final Context mContext, final SharedPreferences.Editor editor) {
        final Dialog dialog = new Dialog(mContext);
        dialog.setTitle("Rate " + APP_TITLE);

        LinearLayout ll = new LinearLayout(mContext);
        ll.setOrientation(LinearLayout.VERTICAL);

        TextView tv = new TextView(mContext);
        tv.setText("If you enjoy using " + APP_TITLE + ", please take a moment to rate it. Thanks for your support!");
        tv.setWidth(240);
        tv.setPadding(4, 0, 4, 10);
        ll.addView(tv);

        Button b1 = new Button(mContext);
        b1.setText("Rate " + APP_TITLE);
        b1.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                mContext.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + APP_PNAME)));
                dialog.dismiss();
            }
        });        
        ll.addView(b1);

        Button b2 = new Button(mContext);
        b2.setText("Remind me later");
        b2.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                dialog.dismiss();
            }
        });
        ll.addView(b2);

        Button b3 = new Button(mContext);
        b3.setText("No, thanks");
        b3.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                if (editor != null) {
                    editor.putBoolean("dontshowagain", true);
                    editor.commit();
                }
                dialog.dismiss();
            }
        });
        ll.addView(b3);

        dialog.setContentView(ll);        
        dialog.show();        
    }
}

Integrating the class is as simple as adding:

AppRater.app_launched(this);

To your Activity. It only needs to be added to one Activity in the entire app.

Prevent user from setting previous DateTime in android

datetime
This can be achieved in two ways.
Let’s consider 1st way of doing this is as follows:

package com.example.datetimedemo;

import java.util.Calendar;
import java.util.Date;

import android.app.Activity;
import android.os.Bundle;
import android.text.format.DateFormat;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.Toast;

public class MainActivity extends Activity{
	DatePicker datePicker;
	TimePicker timePicker;
	TextView textView;
	Date currentDate,selectedDate;
	Calendar calendar;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		try {
			setContentView(R.layout.main_layout);	

			textView = (TextView)findViewById(R.id.textView1);
			datePicker = (DatePicker)findViewById(R.id.datePicker1);
			timePicker = (TimePicker)findViewById(R.id.timePicker1);
			calendar = Calendar.getInstance();

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

				@Override
				public void onClick(View v) {
					int currentDay = calendar.get(Calendar.DAY_OF_MONTH);
					int currentMonth = calendar.get(Calendar.MONTH);
					int currentYear = calendar.get(Calendar.YEAR) - 1900;
					int currentHour = calendar.get(Calendar.HOUR_OF_DAY);
					int currentMin = calendar.get(Calendar.MINUTE);
					currentDate = new Date(currentYear, currentMonth, currentDay, currentHour, currentMin);

				 	int selectedYear = datePicker.getYear();
				 	int selectedDay = datePicker.getDayOfMonth();
				 	int selectedMonth = datePicker.getMonth();
				 	int selectedHour = timePicker.getCurrentHour();
				 	int selectedMin = timePicker.getCurrentMinute();
					selectedDate = new Date(selectedYear - 1900, selectedMonth, selectedDay, selectedHour, selectedMin);

					if(selectedDate.compareTo(currentDate)<0){
						Toast.makeText(getApplicationContext(), "Cannot set previous datetime.", Toast.LENGTH_SHORT).show();
						textView.setText("");
					}
					else {
						textView.setText(DateFormat.format("hh:mm a dd/MMM/yyyy", selectedDate)); //Output: 03:06 pm 07/Apr/2014
					}
				}
			});
		} catch (Exception e) {
			e.toString();
		}
	}
}
<?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" >

    <ScrollView
        android:id="@+id/scrollView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center_horizontal"
            android:orientation="vertical" >

            <DatePicker
                android:id="@+id/datePicker1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:calendarViewShown="false" />

            <TimePicker
                android:id="@+id/timePicker1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />

            <Button
                android:id="@+id/button1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Done" />

            <TextView
                android:id="@+id/textView1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="15dp"
                android:text="TextView" />
        </LinearLayout>
    </ScrollView>

</LinearLayout>

2nd way of implementing above stuff is mentioned as shown below. Only slight change includes, user cannot select datetime before our predefined datetime. i.e. If we want that user should not select datetime before 20 min if he does that then will display message saying you cannot select past datetime. Assuming the same layout.

package com.example.datetimedemo;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.Toast;

public class MainActivity extends Activity{
	DatePicker datePicker;
	TimePicker timePicker;
	TextView textView;
	Date currentDate,selectedDate;
	Calendar calendar;
	@Override
	protected void onCreate(Bundle savedInstanceState) {		
		super.onCreate(savedInstanceState);
		try {
			setContentView(R.layout.main_layout);	
			
			textView = (TextView)findViewById(R.id.textView1);
			datePicker = (DatePicker)findViewById(R.id.datePicker1);
			timePicker = (TimePicker)findViewById(R.id.timePicker1);
			calendar = Calendar.getInstance();
			
			Button button = (Button)findViewById(R.id.button1);
			button.setOnClickListener(new OnClickListener() {
				
				@SuppressLint("SimpleDateFormat")
				@Override
				public void onClick(View v) {				
					Calendar cal = Calendar.getInstance();
					cal.add(Calendar.MINUTE, 20); // Set our predefined value here. 
					
				 	calendar.clear();
				 	calendar.set(Calendar.YEAR, datePicker.getYear());
				 	calendar.set(Calendar.DAY_OF_MONTH, datePicker.getDayOfMonth());
				 	calendar.set(Calendar.MONTH, datePicker.getMonth());
				 	calendar.set(Calendar.HOUR_OF_DAY, timePicker.getCurrentHour());
				 	calendar.set(Calendar.MINUTE, timePicker.getCurrentMinute());				 	
					
				 	if(validateTime(cal.getTimeInMillis()/1000L, calendar.getTimeInMillis()/1000L)) {
				 		SimpleDateFormat format = new SimpleDateFormat("hh:mm a dd/MMM/yyyy");
				 		Date date = calendar.getTime();
				 		textView.setText(format.format(date).toString()); //Output: 03:06 pm 07/Apr/2014
				 		Toast.makeText(MainActivity.this, "Success", Toast.LENGTH_SHORT).show();
				 	}else {
				 		Toast.makeText(MainActivity.this, "Wrong", Toast.LENGTH_SHORT).show();
				 	}
				}
			});
		} catch (Exception e) {
			e.toString();
		}		
	}
	
	private boolean validateTime(long current, long selected) {
		if(selected > current)
			return true;
		return false;
	}
}