Tuesday, January 31, 2017

Issue Handling - RadioGroup setOnCheckedChangeListener getting call multiple times during initialization in Android

 mRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {  
   private boolean isChecked(RadioGroup group, int viewId) {  
     if (viewId != -1) {  
       View v = group.findViewById(viewId);  
       if (v instanceof RadioButton) {  
         return ((RadioButton) v).isChecked();  
       }  
     }  
     return true;  
   }  
   @Override  
   public void onCheckedChanged(RadioGroup group, int checkedId) {  
     if (!isChecked(group, checkedId)) {  
       return;  
     }  
     // put your code here  
   }  
 });  

Handle nested scrollbar in Android

You have to just replace your <ScrollView ></ScrollView> in layout XML file with this Custom ScrollView like <com.tmd.utils.VerticalScrollview > </com.tmd.utils.VerticalScrollview >

 package com.tmd.utils;  
 import android.content.Context;  
 import android.util.AttributeSet;  
 import android.util.Log;  
 import android.view.MotionEvent;  
 import android.widget.ScrollView;  
 public class VerticalScrollview extends ScrollView{  
   public VerticalScrollview(Context context) {  
     super(context);  
   }  
    public VerticalScrollview(Context context, AttributeSet attrs) {  
       super(context, attrs);  
     }  
     public VerticalScrollview(Context context, AttributeSet attrs, int defStyle) {  
       super(context, attrs, defStyle);  
     }  
   @Override  
   public boolean onInterceptTouchEvent(MotionEvent ev) {  
     final int action = ev.getAction();  
     switch (action)  
     {  
       case MotionEvent.ACTION_DOWN:  
           Log.i("VerticalScrollview", "onInterceptTouchEvent: DOWN super false" );  
           super.onTouchEvent(ev);  
           break;  
       case MotionEvent.ACTION_MOVE:  
           return false; // redirect MotionEvents to ourself  
       case MotionEvent.ACTION_CANCEL:  
           Log.i("VerticalScrollview", "onInterceptTouchEvent: CANCEL super false" );  
           super.onTouchEvent(ev);  
           break;  
       case MotionEvent.ACTION_UP:  
           Log.i("VerticalScrollview", "onInterceptTouchEvent: UP super false" );  
           return false;  
       default: Log.i("VerticalScrollview", "onInterceptTouchEvent: " + action ); break;  
     }  
     return false;  
   }  
   @Override  
   public boolean onTouchEvent(MotionEvent ev) {  
     super.onTouchEvent(ev);  
     Log.i("VerticalScrollview", "onTouchEvent. action: " + ev.getAction() );  
      return true;  
   }  
 }  

How to handle issue "Cannot perform this operation because the connection pool has been closed" – Android

Problem:
If you try another operation after closing the database, it will give you that exception.Because db.close(); releases a reference to the object, closing the object if the last reference was released.

Solution:
Keep a single SQLiteOpenHelper instance(Singleton) in a static context. Do lazy initialization, and synchronize that method. Such as
 public class DatabaseHelper  
 {  
   private static DatabaseHelper instance;  
   public static synchronized DatabaseHelper getInstance(Context context)  
   {  
     if (instance == null)  
       instance = new DatabaseHelper(context);  
     return instance;  
   }  
 //Other stuff...   
 }  
And you don’t have to close it? When the app shuts down, it’ll let go of the file reference, if its even holding on to it. i.e. You should not close the DB since it will be used again in the next call. So Just remove
 db.close();  

BroadcastReceiver receives multiple identical messages for one event – Android

Receiving multiple broadcast is a device specific problem. Some phones just send one broadcast while other send 2 or 3. But there is a work around:

Assuming you get the disconnect message when the wifi is disconnected, I would guess the first one is the correct one and the other 2 are just echoes for some reason.

To know that the message has been called, you could have a static boolean that gets toggled between connect and disconnect and only call your sub-routines when you receive a connection and the boolean is true. Something like:
 public class ConnectionChangeReceiver extends BroadcastReceiver {  
   private static boolean firstConnect = true;  
   @Override  
   public void onReceive(Context context, Intent intent) {  
     final ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);  
     final NetworkInfo activeNetInfo = connectivityManager.getActiveNetworkInfo();  
     if (activeNetInfo != null) {  
       if(firstConnect) {   
         // do subroutines here  
         firstConnect = false;  
       }  
     }  
     else {  
       firstConnect= true;  
     }  
   }  
 }  

How to handle ListView inside ScrollView is not scrolling issue on Android

Sometimes we face issue of ListView height if we put ListView inside ScrollView. One more issue comes with this is we are unable to scroll the page. ListView inside ScrollView is a bad practice but there is one solution for it.

Create class as shown below and just use that as a Listview and start binding data to it.
 package com.example.logactivity;  
 import android.content.Context;  
 import android.util.AttributeSet;  
 import android.view.MotionEvent;  
 import android.view.View;  
 import android.view.View.MeasureSpec;  
 import android.view.View.OnTouchListener;  
 import android.view.ViewGroup;  
 import android.view.ViewGroup.LayoutParams;  
 import android.widget.AbsListView;  
 import android.widget.AbsListView.OnScrollListener;  
 import android.widget.ListAdapter;  
 import android.widget.ListView;  
 public class NestedListView extends ListView implements OnTouchListener, OnScrollListener {  
   private int listViewTouchAction;  
   private static final int MAXIMUM_LIST_ITEMS_VIEWABLE = 99;  
   public NestedListView(Context context, AttributeSet attrs) {  
     super(context, attrs);  
     listViewTouchAction = -1;  
     setOnScrollListener(this);  
     setOnTouchListener(this);  
   }  
   @Override  
   public void onScroll(AbsListView view, int firstVisibleItem,  
       int visibleItemCount, int totalItemCount) {  
     if (getAdapter() != null && getAdapter().getCount() > MAXIMUM_LIST_ITEMS_VIEWABLE) {  
       if (listViewTouchAction == MotionEvent.ACTION_MOVE) {  
         scrollBy(0, -1);  
       }  
     }  
   }  
   @Override  
   public void onScrollStateChanged(AbsListView view, int scrollState) {  
   }  
   @Override  
   protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
     super.onMeasure(widthMeasureSpec, heightMeasureSpec);  
     int newHeight = 0;  
     final int heightMode = MeasureSpec.getMode(heightMeasureSpec);  
     int heightSize = MeasureSpec.getSize(heightMeasureSpec);  
     if (heightMode != MeasureSpec.EXACTLY) {  
       ListAdapter listAdapter = getAdapter();  
       if (listAdapter != null && !listAdapter.isEmpty()) {  
         int listPosition = 0;  
         for (listPosition = 0; listPosition < listAdapter.getCount()  
             && listPosition < MAXIMUM_LIST_ITEMS_VIEWABLE; listPosition++) {  
           View listItem = listAdapter.getView(listPosition, null, this);  
           //now it will not throw a NPE if listItem is a ViewGroup instance  
           if (listItem instanceof ViewGroup) {  
             listItem.setLayoutParams(new LayoutParams(  
                 LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));  
           }  
           listItem.measure(widthMeasureSpec, heightMeasureSpec);  
           newHeight += listItem.getMeasuredHeight();  
         }  
         newHeight += getDividerHeight() * listPosition;  
       }  
       if ((heightMode == MeasureSpec.AT_MOST) && (newHeight > heightSize)) {  
         if (newHeight > heightSize) {  
           newHeight = heightSize;  
         }  
       }  
     } else {  
       newHeight = getMeasuredHeight();  
     }  
     setMeasuredDimension(getMeasuredWidth(), newHeight);  
   }  
   @Override  
   public boolean onTouch(View v, MotionEvent event) {  
     if (getAdapter() != null && getAdapter().getCount() > MAXIMUM_LIST_ITEMS_VIEWABLE) {  
       if (listViewTouchAction == MotionEvent.ACTION_MOVE) {  
         scrollBy(0, 1);  
       }  
     }  
     return false;  
   }  
 }  
Your ListView inside your layout should be:
 <com.example.logactivity.NestedListView  
         android:id="@+id/listView"  
         android:layout_width="match_parent"  
         android:layout_height="match_parent"  
         android:layout_centerHorizontal="true"  
         android:layout_marginBottom="5dp"  
         android:layout_marginTop="5dp"  
         android:divider="@android:color/transparent"  
         android:scrollbars="none" >  
 </com.example.logactivity.NestedListView>  

Find start and end date of week from input date in java

// set the date e.g. 12 June 2015
Calendar cal = Calendar.getInstance();
cal.set(2015, 6 – 1, 12);

// “calculate” the start date of the week
Calendar first = (Calendar) cal.clone();
first.add(Calendar.DAY_OF_WEEK, first.getFirstDayOfWeek() – first.get(Calendar.DAY_OF_WEEK));

// and add six days to the end date
Calendar last = (Calendar) first.clone();
last.add(Calendar.DAY_OF_YEAR, 6);

// print the result
SimpleDateFormat df = new SimpleDateFormat(“yyyy-MM-dd”);
System.out.println(df.format(first.getTime()) + ” -> ” +
df.format(last.getTime()));

OUTPUT:
2015-06-08 -> 2015-06-14

How to sort JSONArray in Android?

 /**  
  *   
  * @param jsonArr = Input your json array  
  * @param sortBy = column name which needs to sort  
  * @return required sorted jsonarray   
  */  
 public static JSONArray sortArray(JSONArray jsonArr, final String sortBy) {  
  JSONArray sortedJsonArray = new JSONArray();  
  try {  
  List < JSONObject > jsonValues = new ArrayList < JSONObject > ();  
  for (int i = 0; i < jsonArr.length(); i++) {  
   jsonValues.add(jsonArr.getJSONObject(i));  
  }  
  Collections.sort(jsonValues, new Comparator < JSONObject > () {  
   @Override  
   public int compare(JSONObject a, JSONObject b) {  
   String valA = new String();  
   String valB = new String();  
   try {  
    valA = (String) a.get(sortBy);  
    valB = (String) b.get(sortBy);  
   } catch (JSONException e) {  
    //do something  
   }  
   return valA.compareTo(valB);  
   //if you want to change the sort order, simply use the following:  
   //return -valA.compareTo(valB);  
   }  
  });  
  for (int i = 0; i < jsonArr.length(); i++) {  
   sortedJsonArray.put(jsonValues.get(i));  
  }  
  } catch (JSONException e) {  
  e.printStackTrace();  
  }  
  return sortedJsonArray;  
 }  

Multiline push notification in Android

 int mNotificationId = 001;  
 private void generateNotification(Context mContext, String message) {  
  Intent notificationIntent = new Intent(mContext, MainActivity.class);  
  // set intent so it does not start a new activity  
  notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);  
  PendingIntent resultPendingIntent =  
  PendingIntent.getActivity(mContext, 0, notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);  
  NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(mContext);  
  Notification notification = mBuilder.setSmallIcon(R.drawable.alert).setTicker(getResources().getString(R.string.app_name)).setWhen(0)  
  .setAutoCancel(true)  
  .setContentTitle(getResources().getString(R.string.app_name))  
  .setStyle(new NotificationCompat.BigTextStyle().bigText(message))  
  .setContentIntent(resultPendingIntent)  
  .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))  
  .setLargeIcon(BitmapFactory.decodeResource(mContext.getResources(), R.drawable.ic_logo))  
  .setContentText(message).build();  
  NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);  
  notificationManager.notify(mNotificationId, notification);  
 }  

Handle image orientation with custom camera activity - Android

 ExifInterface exif = new ExifInterface(_path);  
 int exifOrientation = exif.getAttributeInt(  
  ExifInterface.TAG_ORIENTATION,  
  ExifInterface.ORIENTATION_NORMAL);  
 int rotate = 0;  
 switch (exifOrientation) {  
  case ExifInterface.ORIENTATION_ROTATE_90:  
  rotate = 90;  
  break;  
  case ExifInterface.ORIENTATION_ROTATE_180:  
  rotate = 180;  
  break;  
  case ExifInterface.ORIENTATION_ROTATE_270:  
  rotate = 270;  
  break;  
 }  
 if (rotate != 0) {  
  int w = bitmap.getWidth();  
  int h = bitmap.getHeight();  
  // Setting pre rotate  
  Matrix mtx = new Matrix();  
  mtx.preRotate(rotate);  
  // Rotating Bitmap & convert to ARGB_8888, required by tess  
  bitmap = Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, false);  
  bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);  
 }  

Handle onKeyListener in Fragment – Android

 public static class MyFragment extends Fragment {  
     @Override  
     public void onResume() {  
       super.onResume();  
       getView().setFocusableInTouchMode(true);  
       getView().requestFocus();  
       getView().setOnKeyListener(new View.OnKeyListener() {  
         @Override  
         public boolean onKey(View v, int keyCode, KeyEvent event) {  
           //YOUR CODE  
           return false;  
         }  
       });  
     }  
   }  

ViewPager update fragment on swipe – Android

1) Attach the Listener:
 mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {  
       @Override  
       public void onPageScrolled(final int i, final float v, final int i2) {  
       }  
       @Override  
       public void onPageSelected(final int i) {  
         YourFragmentInterface fragment = (YourFragmentInterface) mPagerAdapter.instantiateItem(mViewPager, i);  
         if (fragment != null) {  
           fragment.fragmentBecameVisible();  
         }   
       }  
       @Override  
       public void onPageScrollStateChanged(final int i) {  
       }  
     });  
2) This is your Interface:
 public interface YourFragmentInterface {  
   void fragmentBecameVisible();  
 }  
3) Change your fragments so they implement this:
 public class YourLovelyFragment extends Fragment implements YourFragmentInterface {  
4) Implement the interface in the fragment
 @Override  
 public void fragmentBecameVisible() {  
   // You can do your animation here because we are visible! (make sure onViewCreated has been called too and the Layout has been laid. Source for another question but you get the idea.  
 }  

How to do clear data through app – Android

 public void clearApplicationData() {  
  File cache = getCacheDir();  
  File appDir = new File(cache.getParent());  
  if (appDir.exists()) {  
  String[] children = appDir.list();  
  for (String s: children) {  
   if (!s.equals("lib")) {  
   deleteDir(new File(appDir, s));  
   Log.i("TAG", "**************** File /data/data/APP_PACKAGE/" + s + " DELETED *******************");  
   }  
  }  
  }  
 }  
 public static boolean deleteDir(File dir) {  
  if (dir != null & amp; & amp; dir.isDirectory()) {  
  String[] children = dir.list();  
  for (int i = 0; i & lt; children.length; i++) {  
   boolean success = deleteDir(new File(dir, children[i]));  
   if (!success) {  
   return false;  
   }  
  }  
  }  
  return dir.delete();  
 }  

Monday, January 30, 2017

Remove app from recent apps programmatically

Add New Activity:
 public class ExitActivity extends Activity{  
   @Override protected void onCreate(Bundle savedInstanceState){  
     super.onCreate(savedInstanceState);  
     if(android.os.Build.VERSION.SDK_INT >= 21){  
       finishAndRemoveTask();  
     }  
     else{  
       finish();  
     }  
   }  
   public static void exitApplicationAnRemoveFromRecent(Context mContext){  
     Intent intent = new Intent(mContext, ExitActivity.class);  
     intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS | Intent.FLAG_ACTIVITY_NO_ANIMATION);  
     mContext.startActivity(intent);  
   }  
 }  
Now exit from other Activity:
 @Override  
 public void onBackPressed() {  
  ExitActivity.exitApplicationAnRemoveFromRecent(mContext);  
  super.onBackPressed();  
 }  
Disclaimer: Hiren Patel (http://stackoverflow.com/questions/13385289/remove-app-from-recent-apps-programmatically)

Divider in RecyclerView with ItemDecoration - Android


1. Create class DividerItemDecoration.java
 package com.nikshit.Utilities;  
 import android.graphics.Canvas;  
 import android.graphics.Rect;  
 import android.graphics.drawable.Drawable;  
 import android.support.v7.widget.RecyclerView;  
 import android.view.View;  
 public class DividerItemDecoration extends RecyclerView.ItemDecoration{  
   private Drawable mDivider;  
   public DividerItemDecoration(Drawable divider) {  
     mDivider = divider;  
   }  
   @Override  
   public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {  
     super.getItemOffsets(outRect, view, parent, state);  
     if (parent.getChildAdapterPosition(view) == 0) {  
       return;  
     }  
     outRect.top = mDivider.getIntrinsicHeight();  
   }  
   @Override  
   public void onDraw(Canvas canvas, RecyclerView parent, RecyclerView.State state) {  
     int dividerLeft = parent.getPaddingLeft();  
     int dividerRight = parent.getWidth() - parent.getPaddingRight();  
     int childCount = parent.getChildCount();  
     for (int i = 0; i < childCount - 1; i++) {  
       View child = parent.getChildAt(i);  
       RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();  
       int dividerTop = child.getBottom() + params.bottomMargin;  
       int dividerBottom = dividerTop + mDivider.getIntrinsicHeight();  
       mDivider.setBounds(dividerLeft, dividerTop, dividerRight, dividerBottom);  
       mDivider.draw(canvas);  
     }  
   }  
 }  
2. Create divider.xml
 <?xml version="1.0" encoding="utf-8"?>  
 <shape xmlns:android="http://schemas.android.com/apk/res/android" >  
   <size android:height=".5dip" />  
   <solid android:color="@android:color/darker_gray" />  
 </shape>  
3. Add lines below where you have defined RecyclerView
 RecyclerView.ItemDecoration dividerItemDecoration = new DividerItemDecoration(getResources().getDrawable(R.drawable.divider));  
        mRVFishPrice.addItemDecoration(dividerItemDecoration);  

Implement Endless scrolling using StaggeredLayoutManager – Android

You can use one of two methods in the StaggeredGridLayoutManager:

  1. mLayoutManager.findFirstVisibleItemPositions 
  2. mLayoutManager.findFirstCompletelyVisibleItemPositions

Pass an empty int array that will get initialized with the positions and use the one that makes sense for you.
private boolean loading = true;  
 private int pastVisibleItems, visibleItemCount, totalItemCount;  
 mRecyclerView.setOnScrollListener(new RecyclerView.OnScrollListener({  
     @Override  
     public void onScrolled(RecyclerView recyclerView, int dx, int dy) {  
     visibleItemCount = mLayoutManager.getChildCount();  
     totalItemCount = mLayoutManager.getItemCount();  
     int[] firstVisibleItems = null;  
     firstVisibleItems = mLayoutManager.findFirstVisibleItemPositions(firstVisibleItems);  
     if(firstVisibleItems != null && firstVisibleItems.length > 0) {  
       pastVisibleItems = firstVisibleItems[0];  
     }  
     if (loading) {  
       if ((visibleItemCount + pastVisibleItems) >= totalItemCount) {  
         loading = false;  
         Log.d("tag", "LOAD NEXT ITEM");  
       }  
     }  
   }  
 });