Sunday, September 25, 2011

Sending Multiple file attached email in android

Sending Multiple file attached email in android  ,

public boolean sendEmailWithMultipleAttachments(Context context,
	String[] emailTo, String[] emailCC, String[] emailBCC,
	String subject, String emailBody, List filePaths) throws ActivityNotFoundException {
		
final Intent emailIntent = 
            new Intent(android.content.Intent.ACTION_SEND_MULTIPLE);
emailIntent.setType("message/rfc822");
emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, emailTo);
emailIntent.putExtra(android.content.Intent.EXTRA_CC, emailCC);
emailIntent.putExtra(android.content.Intent.EXTRA_BCC, emailBCC);
emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
emailIntent.putExtra(Intent.EXTRA_TEXT, emailBody);

if (filePaths != null) {
         // has to be an ArrayList
	ArrayList uris = new ArrayList();
	// convert from paths to Android friendly Parcelable Uri's
	for (String file : filePaths) {
		File fileIn = new File(file);
			if (fileIn.exists()) {
				Uri u = Uri.fromFile(fileIn);
			        uris.add(u);
			}
		}
		emailIntent.putParcelableArrayListExtra
                                         (Intent.EXTRA_STREAM, uris);
	}
	context.startActivity(Intent.createChooser(emailIntent, "Sent mail"));
	return true;
	}

filePaths is list, which store the local path of file which we need to attach
eg
filePaths.add("/sdcard/test.pdf");

Get mime type of a file


In android to get mime type is very easy...

To find the mime type of a file, path

String extention =  path.substring(path.lastIndexOf(.) );
String mimeTypeMap =MimeTypeMap.getFileExtensionFromUrl(extention);
String mimeType = MimeTypeMap.getSingleton()
                        .getMimeTypeFromExtension(mimeTypeMap);

Wednesday, April 27, 2011

Create war file in grails

The war command will create a Web Application Archive (WAR) file which can be deployed on any Java EE compliant application server

grails war
grails test war
grails -Dgrails.env=foo war

Usage: 

grails [environment]* war [arguments]*
Arguments:
  • nojars - Packages the WAR with no jar files. Used for shared deployment
Fired Events:
  • StatusFinal - When the WAR file has been created
The war command will create a web application archive (WAR) file using the application name and version number. By default a war file deployable to the production environment will be created, but the environment can be specified using Grails standard convention
    
    grails test war
    grails dev war
    grails prod war
    grails war /foo/bar/mywar.war
    grails war --nojars
    

    Always better to call
    
    grails clean
    
    The clean command will delete all compiled resources from the current Grails application. Since Groovy is a compiled language, as with Java, this is sometimes useful to clear old instances of classes out and ensure correct compilation

    Refer war

    Saturday, April 16, 2011

    Using Fragment of Android Compatibility Package

    The Android 3.0 introduce a awesome feature Fragment.
    It really helpful when we design for tablet. You can refer The Android 3.0 Fragment API   for more details
    Here I'm going to explain how to use Fragment for lower version.
    Now android had released a static library that exposes the same Fragments API, so that applications compatible with Android 1.6 or later can use fragments to create tablet-compatible user interfaces.

    For this you need to do follow these steps
    • Add android-support-v4.jar to you project
      • You can found this jar at yoursdkpath/extras/android/compatibility/v4/
      • Copy this into your libs folder in the root of your project 
      • add this jar to your project build path
    • In order to use this you need to use FragmentActivity instead of Activity 
      • public class Home extends FragmentActivity
    • To get FragmentManager 
      • Need to use getSupportFragmentManager instead of getFragmentManage
    The complete code will look like this
    
    import android.os.Bundle;
    import android.support.v4.app.Fragment;
    import android.support.v4.app.FragmentActivity;
    import android.support.v4.app.FragmentTransaction;
    public class Home extends FragmentActivity{
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
      Fragment productDetails = new MyFragment();
      fragmentTransaction.replace(R.id.mainFragement, productDetails);
      fragmentTransaction.commit();
        }
    }
    
    MyFragment.java
    
    import android.os.Bundle;
    import android.support.v4.app.Fragment;
    import android.util.Log;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.TextView;
    
    public class MyFragment extends Fragment{
     public MyFragment(){
      Log.i("MYEXPENSETRACKER","MyFragment ()");
     }
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
      TextView t = new TextView(getActivity());
      t.setText("From Fragement");
      return t;
     }
    }
    
    
    The main.xml I used
    
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        >
    <TextView  
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:text="@string/hello"
        />
        
     <FrameLayout
      android:id="@+id/mainFragement"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content">
     </FrameLayout>
    </LinearLayout>
    
    
    Hope it helped you..:)

    Wednesday, April 13, 2011

    Go back to previous activity

    Its every common query how to go back to previous activity.
    Most of us will finish activity or keep track of the activity stack and all.
    But no need of this type of complex logic if you need just the same effect of user's back key press
    You can use the android onBackPressed() method explicitly .

    super.onBackPressed();

    The default implementation simply finishes the current activity, but you can override this to do whatever you want.
    The android implicitly call this method when the activity has detected the user's press of the back key.
    So calling this explicitly will give the same effect 

    Monday, March 28, 2011

    In Android import xml into another xml

    Its very common in the UI design that some common element appear many time.
    Just like some common signature in all the activities (pages) and all.
    Its common that we need to set some component as reusable component.

    In this case we can use the <include /> tag. This element does exactly what its name suggest.
    To use this is very simple
    Declare the reusable component as one layout in the /res/layout, let say commonlayout.xml
    Then where ever you need to refer this you can use the following code
    <include android:id="@+id/id" layout="@layout/commonlayout"/>
    
    Note that:
    • Here you can override all the layout parameters. This means that any android:layout_* attribute can be used with the <include /> tag
    •  If you want to override the layout dimensions, you must override both android:layout_height and android:layout_width you cannot override only the height or only the width. If you override only one, it will not take effect. (Other layout properties, such as weight, are still inherited from the source layout.)
    Refer Creating Reusable UI Components



    Monday, March 21, 2011

    Pinch Zoom to view completely

    Hope you have gone through my previous post Zooming a view completely 
    Now to apply pinch zoom we need to override the OnTouchListener.
    There are many blogs and code to do pinch zoom in image view me used that logic here
    So my main activity class will be like this
    
    public class PinchZoomLayout extends Activity {
     View mainView = null;
    
     // Remember some things for zooming
     PointF start = new PointF();
     PointF mid = new PointF();
    
     float oldDist = 1f;
     PointF oldDistPoint = new PointF();
    
     public static String TAG = "ZOOM";
    
     static final int NONE = 0;
     static final int DRAG = 1;
     static final int ZOOM = 2;
     int mode = NONE;
    
     @Override
     public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.main);
      mainView = (LinearLayout) findViewById(R.id.linearLayout);
    
      Button buttonZoomOut = (Button) findViewById(R.id.buttonZoomOut);
      Button buttonNormal = (Button) findViewById(R.id.buttonNormal);
      Button buttonZoomIn = (Button) findViewById(R.id.buttonZoomIn);
    
      buttonZoomOut.setOnClickListener(new OnClickListener() {
       @Override
       public void onClick(View v) {
        zoom(0.5f, 0.5f, new PointF(0, 0));
       }
      });
      buttonNormal.setOnClickListener(new OnClickListener() {
       @Override
       public void onClick(View v) {
        zoom(1f, 1f, new PointF(0, 0));
       }
      });
      buttonZoomIn.setOnClickListener(new OnClickListener() {
       @Override
       public void onClick(View v) {
        zoom(2f, 2f, new PointF(0, 0));
       }
      });
    
      mainView.setOnTouchListener(new OnTouchListener() {
       @Override
       public boolean onTouch(View v, MotionEvent event) {
        Log.d(TAG, "mode=DRAG");
        switch (event.getAction() & MotionEvent.ACTION_MASK) {
        case MotionEvent.ACTION_DOWN:
         start.set(event.getX(), event.getY());
         Log.d(TAG, "mode=DRAG");
         mode = DRAG;
    
         break;
        case MotionEvent.ACTION_POINTER_DOWN:
         oldDist = spacing(event);
         oldDistPoint = spacingPoint(event);
         Log.d(TAG, "oldDist=" + oldDist);
         if (oldDist > 10f) {
          midPoint(mid, event);
          mode = ZOOM;
          Log.d(TAG, "mode=ZOOM");
         }
         System.out.println("current time :" + System.currentTimeMillis());
         break;// return !gestureDetector.onTouchEvent(event);
        case MotionEvent.ACTION_UP:
        case MotionEvent.ACTION_POINTER_UP:
         Log.d(TAG, "mode=NONE");
         mode = NONE;
         break;
        case MotionEvent.ACTION_MOVE:
         if (mode == DRAG) {
    
         } else if (mode == ZOOM) {
          PointF newDist = spacingPoint(event);
          float newD = spacing(event);
          Log.e(TAG, "newDist=" + newDist);
          float[] old = new float[9];
          float[] newm = new float[9];
          Log.e(TAG, "x=" + old[0] + ":&:" + old[2]);
          Log.e(TAG, "y=" + old[4] + ":&:" + old[5]);
          float scale = newD / oldDist;
          float scalex = newDist.x / oldDistPoint.x;
          float scaley = newDist.y / oldDistPoint.y;
          zoom(scale, scale, start);
         }
         break;
        }
        return true;
       }
      });
     }
    
     /** 
      * zooming is done from here 
      */
     public void zoom(Float scaleX, Float scaleY, PointF pivot) {
      mainView.setPivotX(pivot.x);
      mainView.setPivotY(pivot.y);
      mainView.setScaleX(scaleX);
      mainView.setScaleY(scaleY);
     }
    
     /**
      * space between the first two fingers
      */
     private float spacing(MotionEvent event) {
      // ...
      float x = event.getX(0) - event.getX(1);
      float y = event.getY(0) - event.getY(1);
      return FloatMath.sqrt(x * x + y * y);
     }
    
     private PointF spacingPoint(MotionEvent event) {
      PointF f = new PointF();
      f.x = event.getX(0) - event.getX(1);
      f.y = event.getY(0) - event.getY(1);
      return f;
     }
    
     /**
      * the mid point of the first two fingers
      */
     private void midPoint(PointF point, MotionEvent event) {
      // ...
      float x = event.getX(0) + event.getX(1);
      float y = event.getY(0) + event.getY(1);
      point.set(x / 2, y / 2);
     }
    }
     
    But this zoom is not much smooth :(.