Thursday, February 9, 2017

Update content of spinner after selecting item in Android

Are your spinners in different activities? 

If they are, so you can just pass the selected value of the first spinner via Intent (See the putExtra section) and retrieve the value from the next activity so that you can set accordingly the next spinners. 

Edit: 
Here is an example that changes the selected item in the 2nd and 3rd spinner. Update the listener (onItemSelected method) with your logic

Create Activity:

private Spinner s;
private Spinner s2;
private Spinner s3;

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

    setContentView(R.layout.main);
    String[] myList = new String[] {
        Hello,
        World,
        Foo,
        Bar
    };
    String[] myList2 = new String[] {
        Hello2,
        World2,
        Foo2,
        Bar2
    };
    String[] myList3 = new String[] {
        Hello3,
        World3,
        Foo3,
        Bar3
    };

    s = (Spinner) findViewById(R.id.spinner1);
    s2 = (Spinner) findViewById(R.id.spinner2);
    s3 = (Spinner) findViewById(R.id.spinner3);

    s.setAdapter(new ArrayAdapter(this, android.R.layout.simple_spinner_item, myList));
    s2.setAdapter(new ArrayAdapter(this, android.R.layout.simple_spinner_item, myList2));
    s3.setAdapter(new ArrayAdapter(this, android.R.layout.simple_spinner_item, myList3));

    s.setOnItemSelectedListener(new OnItemSelectedListener() {

        @Override
        public void onItemSelected(AdapterView parent, View v,
            int pos, long id) {
            s2.setSelection(pos);
            s3.setSelection(pos);
        }

        @Override
        public void onNothingSelected(AdapterView arg0) {

        }
    });
}

Create main.xml

<?xml version=”1.0″ encoding=”utf-8″?>
<LinearLayout android:layout_width=”fill_parent” xmlns:android=”http://schemas.android.com/apk/res/android”
android:layout_height=”wrap_content”
android:orientation=”vertical”>
<Spinner android:id=”@+id/spinner1″ android:layout_height=”wrap_content” android:layout_width=”fill_parent” />
<Spinner android:id=”@+id/spinner2″ android:layout_height=”wrap_content” android:layout_width=”fill_parent” />
<Spinner android:id=”@+id/spinner3″ android:layout_height=”wrap_content” android:layout_width=”fill_parent” />
</LinearLayout>

Monday, February 6, 2017

Swipe gesture implementation in android

1st way of making swipe gesture:
 public class OnSwipeTouchListener implements OnTouchListener {  
   private final GestureDetector gestureDetector = new GestureDetector(new GestureListener());  
   public boolean onTouch(final View view, final MotionEvent motionEvent) {  
     return gestureDetector.onTouchEvent(motionEvent);  
   }  
   private final class GestureListener extends SimpleOnGestureListener {  
     private static final int SWIPE_THRESHOLD = 100;  
     private static final int SWIPE_VELOCITY_THRESHOLD = 100;  
     @Override  
     public boolean onDown(MotionEvent e) {  
       return true;  
     }  
     @Override  
     public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {  
       boolean result = false;  
       try {  
         float diffY = e2.getY() - e1.getY();  
         float diffX = e2.getX() - e1.getX();  
         if (Math.abs(diffX) > Math.abs(diffY)) {  
           if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {  
             if (diffX > 0) {  
               onSwipeRight();  
             } else {  
               onSwipeLeft();  
             }  
           }  
         } else {  
           if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {  
             if (diffY > 0) {  
               onSwipeBottom();  
             } else {  
               onSwipeTop();  
             }  
           }  
         }  
       } catch (Exception exception) {  
         exception.printStackTrace();  
       }  
       return result;  
     }  
   }  
   public void onSwipeRight() {  
   }  
   public void onSwipeLeft() {  
   }  
   public void onSwipeTop() {  
   }  
   public void onSwipeBottom() {  
   }  
 }  
 //call OnSwipeTouchListener to set gesture to particular control.  
 relParent.setOnTouchListener(new OnSwipeTouchListener() {  
         public void onSwipeTop() {  
           Toast.makeText(this, "top", Toast.LENGTH_SHORT).show();  
         }  
         public void onSwipeRight() {  
           Toast.makeText(this, "right", Toast.LENGTH_SHORT).show();  
         }  
         public void onSwipeLeft() {  
           Toast.makeText(this, "left", Toast.LENGTH_SHORT).show();  
         }  
         public void onSwipeBottom() {  
           Toast.makeText(this, "bottom", Toast.LENGTH_SHORT).show();  
         }  
       });  
2nd way of implementing swipe gesture:
 @Override  
   public boolean onTouchEvent(MotionEvent touchevent) {  
     //return super.onTouchEvent(event);  
     switch (touchevent.getAction()){  
     // when user first touches the screen we get x and y coordinate  
     case MotionEvent.ACTION_DOWN: {  
       x1 = touchevent.getX();  
       y1 = touchevent.getY();  
       break;  
     }  
     case MotionEvent.ACTION_UP: {  
       x2 = touchevent.getX();  
       y2 = touchevent.getY();  
       //if left to right sweep event on screen  
       if (x1 < x2) {                Toast.makeText(this, "Left to Right Swap Performed", Toast.LENGTH_LONG).show();       }      // if right to left sweep event on screen      if (x1 > x2){  
         Toast.makeText(this, "Right to Left Swap Performed", Toast.LENGTH_LONG).show();  
       }  
       // if UP to Down sweep event on screen  
       if (y1 < y2) {        Toast.makeText(this, "UP to Down Swap Performed", Toast.LENGTH_LONG).show();      }      //if Down to UP sweep event on screen      if (y1 > y2){  
         Toast.makeText(this, "Down to UP Swap Performed", Toast.LENGTH_LONG).show();  
       }  
       break;  
     }  
     }  
     return false;  
   }  

Find address as per input using Google Places api in android

By using Google Places API we can find particular address details. APIs thereby providing response in terms of XML or JSON format. I assume that you have API key with you.

To achieve this follow some simple steps below:












Step 1: Create PlaceSearchActivity.java class
 public class PlaceSearchActivity extends Activity{  
   PlacesTask placesTask;  
   EditText etxtPlaces;  
   ListView listViewPlaces;  
   PlaceAdapter adapter;  
   @Override  
   protected void onCreate(Bundle savedInstanceState) {  
     super.onCreate(savedInstanceState);  
     try {  
       setContentView(R.layout.activity_main);  
       initializeControls();  
       handleTextChangeListner();  
     } catch (Exception e) {  
       e.toString();  
     }  
   }  
   private void initializeControls(){  
     try {  
       etxtPlaces = (EditText)findViewById(R.id.etxtPlaces);  
       listViewPlaces = (ListView)findViewById(R.id.listViewPlaces);  
     } catch (Exception e) {  
       e.toString();  
     }  
   }  
   private void handleTextChangeListner(){  
     try {  
       etxtPlaces.addTextChangedListener(new TextWatcher() {  
         @Override  
         public void onTextChanged(CharSequence s, int start, int before, int count) {          
         }  
         @Override  
         public void beforeTextChanged(CharSequence s, int start, int count,  
             int after) {  
         }  
         @Override  
         public void afterTextChanged(Editable s) {  
           // TODO Auto-generated method stub  
           placesTask = new PlacesTask();  
           placesTask.execute(s.toString());  
         }  
       });  
     } catch (Exception e) {  
       e.toString();  
     }  
   }  
   private class PlacesTask extends AsyncTask<String, Void, String>{  
     @Override  
     protected String doInBackground(String... place) {  
       // For storing data from web service  
       String data = "";  
       try {  
         // Obtain browser key from https://code.google.com/apis/console  
         String key = "key=YOUR API KEY";  
         String input="";  
         input = "input=" + URLEncoder.encode(place[0], "utf8");  
         // place type to be searched  
         String types = "types=geocode";  
         // Sensor enabled  
         String sensor = "sensor=false";       
         // Building the parameters to the web service  
         String parameters = input+"&"+types+"&"+sensor+"&"+key;  
         // Output format  
         String output = "json";  
         // Building the url to the web service  
         String url = "https://maps.googleapis.com/maps/api/place/autocomplete/"+output+"?"+parameters;  
         try {  
           data = downloadUrl(url);  
         } catch (IOException e) {  
           e.printStackTrace();  
         }  
       } catch (UnsupportedEncodingException e) {  
         e.printStackTrace();  
       }  
       return data;  
     }  
     @Override  
     protected void onPostExecute(String result) {  
       super.onPostExecute(result);  
       try {  
         parseAndBindDataToListview(result);  
       } catch (Exception e) {  
         e.printStackTrace();  
       }  
     }  
   }  
   private void parseAndBindDataToListview(String result){  
     try {  
       JSONObject jsonObject2 = new JSONObject(result);  
       JSONArray array = jsonObject2.getJSONArray("predictions");  
       JSONObject[] jsonObject = new JSONObject[array.length()];  
       for (int i = 0; i < array.length(); i++) {  
         jsonObject[i] = array.getJSONObject(i);  
       }  
       adapter = new PlaceAdapter(PlaceSearchActivity.this, R.layout.place_list_row, jsonObject);  
       listViewPlaces.setAdapter(adapter);  
     } catch (Exception e) {  
       e.toString();  
     }  
   }  
   /** A method to download json data from url */  
   private String downloadUrl(String strUrl) throws IOException{  
     String data = "";  
     InputStream iStream = null;  
     HttpURLConnection urlConnection = null;  
     try{  
       URL url = new URL(strUrl);          
       // Creating an http connection to communicate with url  
       urlConnection = (HttpURLConnection) url.openConnection();  
       // Connecting to url  
       urlConnection.connect();  
       // Reading data from url  
       iStream = urlConnection.getInputStream();  
       BufferedReader br = new BufferedReader(new InputStreamReader(iStream));  
       StringBuffer sb = new StringBuffer();  
       String line = "";  
       while( ( line = br.readLine()) != null){  
         sb.append(line);  
       }  
       data = sb.toString();  
       br.close();  
     }catch(Exception e){  
       Log.d("Exception while downloading url", e.toString());  
     }finally{  
       iStream.close();  
       urlConnection.disconnect();  
     }  
     return data;  
   }    
 }  
Step 2: Create PlaceAdapter.java class
 public class PlaceAdapter extends ArrayAdapter<JSONObject>{  
   private Context context;  
   private int textViewResourceId;  
   private JSONObject[] data;  
   public PlaceAdapter(Context context, int textViewResourceId, JSONObject[] objects) {  
     super(context, textViewResourceId, objects);  
     this.context = context;  
     this.textViewResourceId = textViewResourceId;  
     data = objects;  
   }  
   @Override  
   public View getView(int position, View convertView, ViewGroup parent) {  
     Viewholder holder = null;  
     try {  
       if(convertView==null){  
         holder = new Viewholder();  
         LayoutInflater inflater = (LayoutInflater) context  
             .getSystemService(Context.LAYOUT_INFLATER_SERVICE);  
         convertView = inflater.inflate(textViewResourceId, parent, false);  
         holder.txtPlace = (TextView) convertView.findViewById(R.id.txtPlace);  
       }  
       holder.txtPlace.setText(data[position].getString("description"));  
     } catch (Exception e) {  
       e.printStackTrace();  
     }  
     return convertView;  
   }  
   static class Viewholder{  
     TextView txtPlace;  
   }  
 }  
Step 3: Create layout activity_main.xml
 <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=".MainActivity" >  
   <EditText  
     android:id="@+id/etxtPlaces"  
     android:layout_width="match_parent"  
     android:layout_height="wrap_content"  
     android:layout_alignParentTop="true"  
     android:layout_centerHorizontal="true"  
     android:layout_marginTop="18dp"  
     android:ems="10" />  
   <ListView  
     android:id="@+id/listViewPlaces"  
     android:layout_width="match_parent"  
     android:layout_height="wrap_content"  
     android:layout_below="@+id/etxtPlaces"  
     android:layout_centerHorizontal="true"  
     android:layout_marginTop="29dp" >  
   </ListView>  
 </RelativeLayout>  
Step 4: Create layout place_list_row.xml which includes row data, how it will look
 <?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" >  
   <TextView  
     android:id="@+id/txtPlace"  
     android:layout_width="wrap_content"  
     android:padding="10dp"  
     android:layout_height="wrap_content"  
     android:text="TextView" />  
 </LinearLayout>  
Step 5: Mention internet permission in manifest
 <uses-permission android:name="android.permission.INTERNET"/>  
You are done ๐Ÿ˜„ ๐Ÿ™Œ

Sunday, February 5, 2017

Difference between @SuppressLint vs @TargetApi

The difference is that with @TargetApi, you declare, via the parameter, what API level you have addressed in your code, so that the error can pop up again if you later modify the method to try referencing something newer than the API level cited in @TargetApi.

For example, suppose that, instead of blocking the StrictMode complaints about your networking bug, you were trying to work around the issue of AsyncTask being serialized on newer versions of Android. You have a method like this in your code to opt into the thread pool on newer devices and use the default multithread behavior on older devices:
 @TargetApi(11)  
 static public<T> void executeAsyncTask(AsyncTask<T,?,?> task,  
                      T...params){  
 if(Build.VERSION.SDK_INT >=Build.VERSION_CODES.HONEYCOMB){  
    task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,params);  
 }else{  
    task.execute(params);  
 }  
 }  
Having @TargetApi(11) means that if Lint detects that I am using something newer than my android:minSdkVersion, but up to API Level 11, Lint will not complain. In this case, that works. If, however, I modified this method to reference something that wasn’t added until API Level 14, then the Lint error would appear again, because my @TargetApi(11) annotation says that I only fixed the code to work on API Level 11 and below, not API Level 14 and below. Using @SuppressLint(‘NewApi’), I would lose the Lint error for any API level, regardless of what my code references and what my code is set up to handle. Hence, @TargetApi is the preferred annotation, as it allows you to tell the build tools “OK, I fixed this category of problems” in a more fine-grained fashion.

Saturday, February 4, 2017

How to call webservice in Android

Just insert code below in your project and as per requirement add Key/Value pairs in request.addProperty. Whereas StrictMode is a developer tool which detects things you might be doing by accident and brings them to your attention so you can fix them.

StrictMode is most commonly used to catch accidental disk or network access on the application’s main thread, where UI operations are received and animations take place. Keeping disk and network operations off the main thread makes for much smoother, more responsive applications. By keeping your application’s main thread responsive, you also prevent ANR dialogs from being shown to users.
 public String callGetSecurityQuestions() throws Exception{  
     String NAMESPACE = "YOUR NAMESPACE HERE" //e.g. "http://namespace/";  
     String URL = "YOUR URL HERE" //e.g. "http://domainname/asmx name";  
     String METHOD_NAME = "YOUR METHOD NAME" //e.g. "GetSecurityQuestions";  
     String SOAP_ACTION = NAMESPACE+METHOD_NAME;  
     String response = "";  
     try {  
       if (android.os.Build.VERSION.SDK_INT > 9) {  
         StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();  
         StrictMode.setThreadPolicy(policy);  
       }  
       SoapObject request = new SoapObject(CommonEnviornment.NAMESPACE,METHOD_NAME);  
       request.addProperty("key1", value1);        
       request.addProperty("key2", value2);  
       SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);  
       envelope.dotNet = true;  
       envelope.setOutputSoapObject(request);  
       HttpTransportSE androidHttpTransport = new HttpTransportSE(CommonEnviornment.URL);  
       androidHttpTransport.call(SOAP_ACTION, envelope);  
       SoapObject result = (SoapObject)envelope.bodyIn;  
       response = result.toString();  
       System.out.println(result.toString());  
     } catch (Exception e) {  
       throw e;  
     }  
     return response;  
   }  

Prevent user from setting previous DateTime in android

This can be achieved in two ways.
1st Way:
 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();  
     }  
   }  
 }  
Create layout:
 <?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: 
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;  
   }  
 }  

How to use Facebook login in android studio

Implement "Rate Us" feature in Android App

I 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.

Friday, February 3, 2017

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;  
   }  

Service vs Intent service - Android

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 read file from asset in Android?

In my case 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();  
   }  

Program to find 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);  
   }  

Thursday, February 2, 2017

How to enable wireless debugging with the ADB Android


  1. Open cmd 
  2. go to path till
    C:\Users\servpro.nikhil\AppData\Local\Android\sdk\platform-tools

  3. Type
  4. adb usb

  5. Type
  6. adb devices

  7. Type
  8. adb tcpip 5556

  9. Type
  10. adb connect <Your device IP address>
    Note: To check device IP address go to settings > About Phone > Status > IP address
    You will find status ad Connected to

  11. Remove USB and Enjoy

Fetch contact list from device – Android

Just add below patch in your code and you will see result as shown above:
 private ArrayList<Map<String, String>> mPeopleList;  
 private SimpleAdapter mAdapter;  
 private AutoCompleteTextView mTxtPhoneNo;  
 class FetchPeopleTask extends AsyncTask<String, String, String>{  
     @Override  
     protected String doInBackground(String... params) {  
       Log.d(TAG, "Fetching people task start.");  
       PopulatePeopleList();  
       return null;  
     }  
     @Override  
     protected void onPostExecute(String result) {  
       super.onPostExecute(result);  
       Log.d(TAG, "Fetching people task complete.");  
     }  
   }  
 public void PopulatePeopleList() {  
     try {  
       mPeopleList.clear();  
       Cursor people = getContentResolver().query(  
           ContactsContract.Contacts.CONTENT_URI, null, null, null, null);  
       while (people.moveToNext()) {  
         String contactName = people.getString(people  
             .getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));  
         String contactId = people.getString(people  
             .getColumnIndex(ContactsContract.Contacts._ID));  
         String hasPhone = people  
             .getString(people  
                 .getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER));  
         if ((Integer.parseInt(hasPhone) > 0)){  
           // You know have the number so now query it like this  
           Cursor phones = getContentResolver().query(  
               ContactsContract.CommonDataKinds.Phone.CONTENT_URI,  
               null,  
               ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = "+ contactId,  
               null, null);  
           while (phones.moveToNext()){  
             //store numbers and display a dialog letting the user select which.  
             String phoneNumber = phones.getString(  
                 phones.getColumnIndex(  
                     ContactsContract.CommonDataKinds.Phone.NUMBER));  
             String numberType = phones.getString(phones.getColumnIndex(  
                 ContactsContract.CommonDataKinds.Phone.TYPE));  
             Map<String, String> NamePhoneType = new HashMap<String, String>();  
             NamePhoneType.put("Name", contactName);  
             NamePhoneType.put("Phone", phoneNumber);  
             if(numberType.equals("0"))  
               NamePhoneType.put("Type", "Work");  
             else  
               if(numberType.equals("1"))  
                 NamePhoneType.put("Type", "Home");  
               else if(numberType.equals("2"))  
                 NamePhoneType.put("Type", "Mobile");  
               else  
                 NamePhoneType.put("Type", "Other");  
             //Then add this map to the list.  
             mPeopleList.add(NamePhoneType);  
           }  
           phones.close();  
         }  
       }  
       people.close();  
     } catch (NumberFormatException e) {       
       e.printStackTrace();  
     }  
   }  
 private void bindAutocompletContact(){  
     try {  
       mAdapter = new SimpleAdapter(this, mPeopleList, R.layout.autocomplete_contact_layout,  
           new String[] { "Name", "Phone", "Type" }, new int[] {  
           R.id.ccontName, R.id.ccontNo, R.id.ccontType });  
       mTxtPhoneNo.setAdapter(mAdapter);  
       mTxtPhoneNo.setOnItemClickListener(new OnItemClickListener() {  
         @Override  
         public void onItemClick(AdapterView<?> av, View arg1, int index,  
             long arg3) {  
           Map<String, String> map = (Map<String, String>) av.getItemAtPosition(index);  
           String name = map.get("Name");  
           String number = map.get("Phone");  
           mTxtPhoneNo.setText(number);  
         }  
       });  
     } catch (Exception e) {       
       e.printStackTrace();  
     }  
   }  
Nikhil Sanjay Lotke
Android Developer

My objective in life is knowledge! I always consider knowledge as my most basic need for my self.I feel it doesn’t necessary to have knowledge of everything but be best in your field where you work and where you stand!

๐Ÿ˜ƒ My Featured Apps on Play Store ๐Ÿ˜ƒ


TNews: Tiny always with you

TNews app will keeps you ahead and informed every day. Always find real-time updates of Latest, Top & Popular News.

Features:
- Simple and Optimized News
- Share News Details to Friends & Family
- News based on Source selection
- Get News details to choose particular News
- Ad free build for 30 days

Download via Play Store: https://goo.gl/TvnT5J

SMS Routine

Send Text Messages to recipients with your decided time.

Features:
- You can schedule the message.
- Find Sent as well as Draft messages.
- Directly send messages to recipients.
- Facility to Edit, Delete and View Details of the Draft messages.
- Get appropriate notifications once message sent or problem occurs while sending/receiving.
- Tutorials for better understanding.

Download via Play Store: https://goo.gl/TuWi1g

Movie Downloader Pro

No. 1 app on Google Play Store which will download latest movies for you.

Features:
- Support for 2.2 (Froyo) and above.
- Always find latest 50 movies
- Multi categories to download movies.
- Download multiple movies at a time.
- Get appropriate notifications related to download.

Thank you so much to all of you for using my app and giving positive feedback. Unfortunately I have to shutdown this app support. You will not find this app anywhere and completely down. Apologies for the inconvenience.

Wednesday, February 1, 2017

android.database.StaleDataException: Attempted to access a cursor after it has been closed.

During my android development, I came across this during run time:

android.database.StaleDataException: Attempted to access a cursor after it has been closed

I looked over the internet to look for solution on this issue. Many suggestions came out but only one suggestion solved “android.database.StaleDataException: Attempted to access a cursor after it has been closed” error.

It is by using startManagingCursor(cursor). The “cursor” is your result holder of your db query.

Recommend you that do not use startManagingCursor(cursor).  This method was deprecated in API level 11. 

Use the new CursorLoader class with LoaderManager instead; this is also available on older platforms through the Android compatibility package.

How to implement UncaughtExceptionHandler in Android

If you do not handle a runtime exception in your program, the default behaviour will be to terminate the program and dump the call stacktrace on the console.

Java provides an elegant mechanism of handling Runtime Exceptions that you might have not handled in your program.
UncaughtExceptionHandler can be defined at three levels. From highest to lowest they are:
  1. Thread.setDefaultUncaughtExceptionHandler
  2. ThreadGroup.uncaughtException
  3. Thread.setUncaughtExceptionHandler
 package com.example.common;  
 import android.app.Activity;  
 public class TopExceptionHandler implements Thread.UncaughtExceptionHandler{  
   private Activity objApp;  
   public TopExceptionHandler(Activity app) {  
     objApp = app;  
     Thread.getDefaultUncaughtExceptionHandler();  
   }  
   @Override  
   public void uncaughtException(Thread thread, Throwable ex) {  
     // TODO Auto-generated method stub  
     try{  
       StackTraceElement[] arr = ex.getStackTrace();  
       String report = ex.toString();  
       String strStack = "";  
       strStack += "Stack trace: ";  
       for (int i=0; i<arr.length; i++){  
         strStack += "  "+arr[i].toString()+"\t";  
       }  
       // If the exception was thrown in a background thread inside  
       // AsyncTask, then the actual exception can be found with getCause  
       String strCause = "";  
       strCause += "Cause: ";  
       Throwable cause = ex.getCause();  
     }  
     catch(Exception ex1){  
       System.err.println(ex1);  
     }  
   }  
 }  
Now call TopExceptionHandler class as shown below:
 public class MyActivity extends AppCompatActivity{  
   @Override  
   protected void onCreate(Bundle savedInstanceState) {  
     super.onCreate(savedInstanceState);  
     setContentView(R.layout.activity_layout);  
     new TopExceptionHandler(this);  
   }  
 }  
Run the app and check Logcat for all runtime exceptions.

Handle Failure [INSTALL_FAILED_OLDER_SDK] issue in Android Studio

I solved out it just now.
It seems that something wrong in SDK 20
I install SDK-19.0.1 and rewrite the file “build.gradle”
 android {  
   compileSdkVersion 19  
   buildToolsVersion "19.1.0"  
   defaultConfig {  
     minSdkVersion 10  
     targetSdkVersion 19  
     versionCode 1  
     versionName "1.0"  
   }  
   buildTypes {  
     release {  
       runProguard false  
       proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'  
     }  
   }  
 }  
 dependencies {  
   compile fileTree(dir: 'libs', include: ['*.jar'])  
   // You must install or update the Google Repository through the SDK manager to use this dependency.  
   compile 'com.android.support:appcompat-v7:19.+'  
   compile 'com.android.support:support-v4:19.+'  
 }  
Success finally!

Android Studio - UNEXPECTED TOP-LEVEL EXCEPTION:

Just add below code inside build.gradle
 configurations {  
   all*.exclude group: 'com.android.support', module: 'support-v4'  
 }  
If you have more then one support libs included in the dependencies like this, you may want to remove one of them:

How to check Android device supports BLE (Bluetooth Low Energy)

public void checkBluetoothSupport(){  
     // Initializes a Bluetooth adapter. For API level 18 and above, get a reference to  
     // BluetoothAdapter through BluetoothManager.  
     final BluetoothManager bluetoothManager =  
         (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);  
     BluetoothAdapter mBluetoothAdapter = bluetoothManager.getAdapter();  
     // Checks if Bluetooth is supported on the device.  
     if (mBluetoothAdapter == null) {  
       Toast.makeText(context, "Device does not supports BLE", Toast.LENGTH_SHORT).show();  
       return;  
     }  
     else{  
      Toast.makeText(context, "Device supports BLE", Toast.LENGTH_SHORT).show();  
     }  
   }  

Trick to download YouTube videos without software - Guaranteed๐Ÿ˜ฑ๐Ÿ˜€๐Ÿค—