Get images from Raw folder using only name of Images in Andriod

Sometime we need to get images from raw folder using its name. I came across one scenario where unity developer drop images in raw folder of Android system. Developer returned me only names of that images. And i needed to show dialog of that images using frame animation. There are only three steps to get images from raw folder through its name.

Step - 1: Get resource id of image using its name


int rid = context.getResources()
        .getIdentifier("image_name","raw", context.getPackageName());

Step - 2: Get input stream of image file using that resource id


Resources res = context.getResources();
InputStream in = res.openRawResource(rid);

Step- 3: Get drawable using that input stream


Drawable image = Drawable.createFromStream(in, "image_name"); 

Code snippet :


AnimationDrawable animation = new AnimationDrawable();
for (int count = 0; count < names.length; count++) {
 try {
  int rid = context.getResources().getIdentifier(names[count],
      "raw", context.getPackageName());
  Resources res = context.getResources();
  InputStream in = res.openRawResource(rid);

  byte[] b = new byte[in.available()];
  in.read(b);
  animation.addFrame(Drawable.createFromStream(in, names[count]),
      durationPerFrame);
 } catch (Exception e) {
  e.printStackTrace();
 }
}

animation.setOneShot(false);

Tips for working with Android 4.3 (An Even Sweeter Jelly Bean)


Welcome to Android 4.3, a sweeter version of Jelly Bean! Android 4.3 includes performance optimizations and great new features for users and developers.



I discuss about few things that can be take in care while running your previously published app on Android 4.3.If you have previously published an app for Android, be aware that your app might be affected by changes in Android 4.3. The new feature called Restricted profiles, a new way to manage users and their capabilities on a single device.

There are many cases where your app can misbehave in restricted profile :
  1. If your app uses implicit intents...

    For example, a restricted profile might have the web browser and camera app disabled. So your app should not make assumptions about which apps are available, because if you call startActivity() without verifying whether an app is available to handle theIntent, your app might crash in a restricted profile.When using an implicit intent, you should always verify that an app is available to handle the intent by callingresolveActivity() or queryIntentActivities(). For example:
     
    Intent intent = new Intent(Intent.ACTION_SEND);
    ...
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    } else {
        Toast.makeText(context, R.string.app_not_available, Toast.LENGTH_LONG).show();
    }
  2. If your app depends on accounts...
    Any accounts added to the primary user are available to a restricted profile, but the accounts are not accessible from theAccountManager APIs by default.

    Due to these restrictions, you have the following three options:

    • Allow access to the owner’s accounts from a restricted profile.
      To get access to an account from a restricted profile, you must add the android:restrictedAccountType attribute to the <application> tag:
      <application ...
          android:restrictedAccountType="com.example.account.type" >
    • Disable certain functionality when unable to modify accounts.
       If you want to use accounts, but don’t actually require them for your app’s primary functionality, you can check for account availability and disable features when not available.
      UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
      Bundle restrictions = um.getUserRestrictions();
      if (restrictions.getBoolean(UserManager.DISALLOW_MODIFY_ACCOUNTS, false)) {
         // cannot add accounts, disable some functionality
      }

    • Disable your app when unable to access private accounts.
      If it’s instead important that your app not be available to restricted profiles because your app depends on sensitive personal information in an account (and because restricted profiles currently cannot add new accounts), add the android:requiredAccountType attribute to the <application> tag:
      <application ...
          android:requiredAccountType="com.example.account.type" >

  3. Bluetooth Low Energy (Smart Ready)
    You can only scan for Bluetooth LE devices or scan for Classic Bluetooth devices using previous APIs. You cannot scan for both LE and Classic Bluetooth devices at once.

Clustering on Google Map V2 Part-2

We have gone through Clustering on Google map V2 in Clustering on Google Map V2 Part-1 .To overcome drawback of it , I searched for few days and i found one more library which independent from google play service library.

Screenshots :


Features :

  • Clustering based on pixel proximity, not grid membership
  • Animated cluster transitions
  • Supports Android v2.2 (Froyo) and higher

Getting started : 

  • It's easy to add Clusterkraf to your app. Add the Clusterkraf library folder as an Android project to your Eclipse/ADT workspace, and reference it from your app as a library project.
  • Clusterkraf provides an InputPoint class which holds a LatLng position and an Object tag. You just need to construct an ArrayList<InputPoint> object based on your model objects.


    public class YourActivity extends FragmentActivity {
        YourMapPointModel[] yourMapPointModels = new YourMapPointModel[] { new YourMapPointModel(new LatLng(0d, 1d) /* etc */ ) };
        ArrayList inputPoints;
    
        private void buildInputPoints() {
            this.inputPoints = new ArrayList(yourMapPointModels.length);
            for (YourMapPointModel model : this.yourMapPointModels) {
                this.inputPoints.add(new InputPoint(model.latLng, model));
            }
        }
    }
    
  • When your GoogleMap is initialized and your ArrayList<InputPoint> is built, you can then initialize Clusterkraf.
    // YourActivity
    
        Clusterkraf clusterkraf;
    
        private void initClusterkraf() {
            if (this.map != null && this.inputPoints != null && this.inputPoints.size() > 0) {
                com.twotoasters.clusterkraf.Options options = new com.twotoasters.clusterkraf.Options();
                // customize the options before you construct a Clusterkraf instance
                this.clusterkraf = new Clusterkraf(this.map, this.options, this.inputPoints);
            }
        }
    


Advance Options :

  1. To set any type of interpolator in cluster animation :
    options.setTransitionInterpolator(interpolator); 
    /* Types : AccelerateDecelerateInterpolator, AccelerateInterpolator, AnticipateInterpolator,
    AnticipateOvershootInterpolator, BounceInterpolator, DecelerateInterpolator,
    LinearInterpolator, OvershootInterpolator */
    
  2. Clusterkraf calculates whether InputPoint objects should join a cluster based on their pixel proximity. If you want to offer your app on devices with different screen densities, you should identify a Device Independent Pixel measurement and convert it to pixels based on the device's screen density at runtime.
    options.setPixelDistanceToJoinCluster(dipDistanceToJoinCluster);
    
  3. To set zoom to bound animation duration :

    options.setZoomToBoundsAnimationDuration(zoomToBoundsAnimationDuration);
    
  4. To set showInfoWindow animation duration :

    options.setShowInfoWindowAnimationDuration(showInfoWindowAnimationDuration);
    
  5. To set behavior of marker click :

    options.setSinglePointClickBehavior(singlePointClickBehavior);
    /* select from two types SHOW_INFO_WINDOW, NO_OP. */
    
  6. To set behavior of cluster click :

    options.setClusterClickBehavior(this.options.clusterClickBehavior);
    /* select from three types ZOOM_TO_BOUNDS, SHOW_INFO_WINDOW, NO_OP. */
    
  7. To set behavior of cluster info window click :

    options.setClusterInfoWindowClickBehavior(this.options.clusterInfoWindowClickBehavior);
    /* select from three types ZOOM_TO_BOUNDS, HIDE_INFO_WINDOW, NO_OP. */
    
  8. To set padding from window sides after zooming :

    options.setZoomToBoundsPadding(pixels);
    /* When zooming to the bounds of a marker's backing ClusterPoint, zoom until
     * all of the points are at least this far from the edge of the GoogleMap's
     * bounds
     */
    
  9. To set marker click listner :

    options.setOnMarkerClickDownstreamListener(new OnMarkerClickDownstreamListener(new OnMarkerClickDownstreamListener() {
       
       @Override
       public boolean onMarkerClick(Marker marker, ClusterPoint clusterPoint) {
        // TODO Auto-generated method stub
        return false;
       }
      }));
    
  10. To get methods of starting and finishing clustering :

    options.setProcessingListener(this);
    /* generate two methods */
    @Override
     public void onClusteringStarted() {
      
     }
    
     @Override
     public void onClusteringFinished() {
     }

Download Source code : ClusterOnGoogleMapV2


Reference Link: Clusterkraf

Clustering on Google Map V2 Part-1

Introduction: 

I had done with clustering on Google Map V1. After it is deprecated, i was searching for clustering on Google Map V2. And i found one library Android Maps Extensions. It is working great but depends on your implementation how will you use it in your project.

Drawback : This library use google-play-services.jar and has its own implementation of GoogleMap. Hence if there will any change happen in Map v2 API, takes time to implement that changes in this library.

Screenshots:



Getting Started:

  1. Download zip from above link and import library project.
  2. Import this library to project.
    Note:
    No need to import google play service library project as this library contains it.
  3. Get Map key from API Console.

Map Implementation:

  • Activity extends FragmentActivity
  • FragmentManager fm = getSupportFragmentManager();
  • SupportMapFragment f = (SupportMapFragment) fm.findFragmentById(R.id.map); GoogleMap map = f.getExtendedMap();

Cluster Implementatioin:

map.setClustering(new ClusteringSettings().iconDataProvider(new DemoIconProvider(getResources())));


DemoIconProvider.java:


public class DemoIconProvider implements IconDataProvider {

 private static final int[] res = { R.drawable.m1, R.drawable.m2, R.drawable.m3, R.drawable.m4, R.drawable.m5 };

 private static final int[] forCounts = { 10, 100, 1000, 10000, Integer.MAX_VALUE };

 private Bitmap[] baseBitmaps;

 private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
 private Rect bounds = new Rect();

 private MarkerOptions markerOptions = new MarkerOptions().anchor(0.5f, 0.5f);

 public DemoIconProvider(Resources resources) {
  baseBitmaps = new Bitmap[res.length];
  for (int i = 0; i < res.length; i++) {
   baseBitmaps[i] = BitmapFactory.decodeResource(resources, res[i]);
  }
  paint.setColor(Color.WHITE);
  paint.setTextAlign(Align.CENTER);
  paint.setTextSize(resources.getDimension(R.dimen.text_size));
 }

 @Override
 public MarkerOptions getIconData(int markersCount) {
  Bitmap base;
  int i = 0;
  do {
   base = baseBitmaps[i];
  } while (markersCount >= forCounts[i++]);

  Bitmap bitmap = base.copy(Config.ARGB_8888, true);

  String text = String.valueOf(markersCount);
  paint.getTextBounds(text, 0, text.length(), bounds);
  float x = bitmap.getWidth() / 2.0f;
  float y = (bitmap.getHeight() - bounds.height()) / 2.0f - bounds.top;

  Canvas canvas = new Canvas(bitmap);
  canvas.drawText(text, x, y, paint);

  BitmapDescriptor icon = BitmapDescriptorFactory.fromBitmap(bitmap);
  return markerOptions.icon(icon);
 }
}

TO overcome from drawback, I found one library Clustering on Google Map V2 Part-2 .
It is easy to implement and more customizable.

Download Source code : ClusterMap2


Reference Link: Android Maps Extensions

ListView Animation Tutorial


This simple tutorial shows you how to give animation to list view row. There are plenty of animations i covered here. First create anim folder in res folder and create different  XML for  different animation.

List of Animation

  1. Fade IN:
  2. <alpha xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="100"
        android:fromAlpha="0.0"
        android:interpolator="@android:anim/accelerate_interpolator"
        android:toAlpha="1.0" />
    

  3. Hyperspace Out:
  4. <set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="false">
       <scale
          android:interpolator="@android:anim/accelerate_decelerate_interpolator"
          android:fromXScale="1.0"
          android:toXScale="1.4"
          android:fromYScale="1.0"
          android:toYScale="0.6"
          android:pivotX="50%"
          android:pivotY="50%"
          android:fillAfter="false"
          android:duration="700" />
       <set
          android:interpolator="@android:anim/accelerate_interpolator"
                    android:startOffset="700">
          <scale
             android:fromXScale="1.4"
             android:toXScale="0.0"
                  android:fromYScale="0.6"
              android:toYScale="0.0"
              android:pivotX="50%"
              android:pivotY="50%"
              android:duration="400" />
          <rotate
             android:fromDegrees="0"
             android:toDegrees="-45"
              android:toYScale="0.0"
              android:pivotX="50%"
              android:pivotY="50%"
              android:duration="400" />
       </set>
    </set>
    

  5. Push Left In:
  6. <set xmlns:android="http://schemas.android.com/apk/res/android">
       <translate android:fromXDelta="100%p" android:toXDelta="0"
             android:duration="300"/>
       <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
             android:duration="300" />
    </set>
    

  7. Push Left Out:
  8. <set xmlns:android="http://schemas.android.com/apk/res/android">
       <translate android:fromXDelta="0" android:toXDelta="-100%p"
            android:duration="300"/>
       <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
            android:duration="300" />
    </set>
    

  9. Push Up In:
  10. <set xmlns:android="http://schemas.android.com/apk/res/android">
       <translate android:fromYDelta="100%p" android:toYDelta="0"
              android:duration="500"/>
       <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
              android:duration="500" />
    </set>
    

  11. Push Up Out:
  12. <set xmlns:android="http://schemas.android.com/apk/res/android">
       <translate android:fromYDelta="0" android:toYDelta="-100%p"
             android:duration="500"/>
       <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
             android:duration="500" />
    </set>
    

  13. Shake:
  14. <translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXDelta="0" android:toXDelta="10"
    android:duration="1000" android:interpolator="@anim/cycle" />
    

  15. Cycle:
  16. <cycleInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
    android:cycles="7" />
    

  17. Slide In Top:
  18. <set xmlns:android="http://schemas.android.com/apk/res/android" >
        <translate
            android:duration="1000"
            android:fromYDelta="-100%p"
            android:toYDelta="1" />
    </set>
    

  19. Slide Top to Bottom:
  20. <set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/accelerate_interpolator">
        <translate android:fromYDelta="-100%" android:toXDelta="0"
            android:duration="100" />
        <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
            android:duration="50" />
    </set>
    

  21. Wave Scale:
  22. <set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/accelerate_interpolator">
        <alpha
            android:fromAlpha="0.0"
            android:toAlpha="1.0"
            android:duration="100" />
        <scale
            android:fromXScale="0.5" android:toXScale="1.5"
            android:fromYScale="0.5" android:toYScale="1.5"
            android:pivotX="50%" android:pivotY="50%"
            android:duration="200" />
        <scale
            android:fromXScale="1.5" android:toXScale="1.0"
            android:fromYScale="1.5" android:toYScale="1.0"
            android:pivotX="50%" android:pivotY="50%"
            android:startOffset="200"
            android:duration="100" />
    </set>
    

Create Main activity to create listview and give animation.

MainActivity :
import java.util.ArrayList;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.ScaleAnimation;
import android.view.animation.TranslateAnimation;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;

public class MainActivity extends Activity {

 private ListView listview;
 private DisplayMetrics metrics;

 private int mode = 1;
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  
  metrics = new DisplayMetrics();
  getWindowManager().getDefaultDisplay().getMetrics(metrics);

  listview = new ListView(this);
  listview.setFadingEdgeLength(0);
  ArrayList<string> strings = new ArrayList<string>();

  for (int i = 0; i &lt; 300; i++) {
   strings.add("Item:#" + (i + 1));
  }

  MainAdapter mAdapter = new MainAdapter(this, strings, metrics);
  listview.setAdapter(mAdapter);
  setContentView(listview);
 }

 public boolean onCreateOptionsMenu(Menu menu) {
  boolean result = super.onCreateOptionsMenu(menu);
  menu.add(Menu.NONE, 1, 0, "TranslateAnimation1");
  menu.add(Menu.NONE, 2, 0, "TranslateAnimation2");
  menu.add(Menu.NONE, 3, 0, "ScaleAnimation");
  menu.add(Menu.NONE, 4, 0, "fade_in");
  menu.add(Menu.NONE, 5, 0, "hyper_space_in");
  menu.add(Menu.NONE, 6, 0, "hyper_space_out");
  menu.add(Menu.NONE, 7, 0, "wave_scale");
  menu.add(Menu.NONE, 8, 0, "push_left_in");
  menu.add(Menu.NONE, 9, 0, "push_left_out");
  menu.add(Menu.NONE, 10, 0, "push_up_in");
  menu.add(Menu.NONE, 11, 0, "push_up_out");
  menu.add(Menu.NONE, 12, 0, "shake");
  return result;
 }

 @Override
 public boolean onOptionsItemSelected(MenuItem item) {
  mode = item.getItemId();
  return super.onOptionsItemSelected(item);
 }

 public class MainAdapter extends ArrayAdapter<string> {
  private Context context;
  private LayoutInflater mInflater;
  private ArrayList<string> strings;
  private DisplayMetrics metrics_;

  private class Holder {
   public TextView textview;
  }

  public MainAdapter(Context context, ArrayList<string> strings,
    DisplayMetrics metrics) {
   super(context, 0, strings);
   this.context = context;
   this.mInflater = (LayoutInflater) this.context
     .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
   this.strings = strings;
   this.metrics_ = metrics;
  }

  @Override
  public View getView(final int position, View convertView,
    ViewGroup parent) {
   final String str = this.strings.get(position);
   final Holder holder;

   if (convertView == null) {
    convertView = mInflater.inflate(
      android.R.layout.simple_list_item_1, null);
    convertView.setBackgroundColor(0xFF202020);

    holder = new Holder();
    holder.textview = (TextView) convertView
      .findViewById(android.R.id.text1);
    holder.textview.setTextColor(0xFFFFFFFF);
    holder.textview.setBackgroundResource(R.drawable.background);

    convertView.setTag(holder);
   } else {
    holder = (Holder) convertView.getTag();
   }

   holder.textview.setText(str);

   Animation animation = null;

   switch (mode) {
   case 1:
    animation = new TranslateAnimation(metrics_.widthPixels / 2, 0,
      0, 0);
    break;

   case 2:
    animation = new TranslateAnimation(0, 0, metrics_.heightPixels,
      0);
    break;

   case 3:
    animation = new ScaleAnimation((float) 1.0, (float) 1.0,
      (float) 0, (float) 1.0);
    break;

   case 4:
     animation = AnimationUtils.loadAnimation(context, R.anim.fade_in);
    break;
   case 5:
    animation = AnimationUtils.loadAnimation(context, R.anim.hyperspace_in);
    break;
   case 6:
    animation = AnimationUtils.loadAnimation(context, R.anim.hyperspace_out);
    break;
   case 7:
    animation = AnimationUtils.loadAnimation(context, R.anim.wave_scale);
    break;
   case 8:
    animation = AnimationUtils.loadAnimation(context, R.anim.push_left_in);
    break;
   case 9:
    animation = AnimationUtils.loadAnimation(context, R.anim.push_left_out);
    break;
   case 10:
    animation = AnimationUtils.loadAnimation(context, R.anim.push_up_in);
    break;
   case 11:
    animation = AnimationUtils.loadAnimation(context, R.anim.push_up_out);
    break;
   case 12:
    animation = AnimationUtils.loadAnimation(context, R.anim.shake);
    break;
   }

   animation.setDuration(500);
   convertView.startAnimation(animation);
   animation = null;

   return convertView;
  }
 }
}


Download Source code : Listview Animation Demo
Sample Application on Play storeListview Animation Sample Application