Amazon Gift Cards

Saturday, October 30, 2010

Take Picture in Android with MediaStore.ACTION_IMAGE_CAPTURE

Previously in Android when you want to capture an Image, you have to use SurfaceView and SurfaceHolder to preview the camera. MediaStore.ACTION_IMAGE_CAPTURE was introduced in Cupcake, Android 1.5, and has been the default way to capture images captured in Android.

What Do I Need
In Manafiest.xml
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

In your activity
private static final int TAKE_PHOTO_CODE = 1;

private void takePhoto(){
  final Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
  intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(getTempFile(this)) ); 
  startActivityForResult(intent, TAKE_PHOTO_CODE);
}

private File getTempFile(Context context){
  //it will return /sdcard/image.tmp
  final File path = new File( Environment.getExternalStorageDirectory(), context.getPackageName() );
  if(!path.exists()){
    path.mkdir();
  }
  return new File(path, "image.tmp");
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  if (resultCode == RESULT_OK) {
    switch(requestCode){
      case TAKE_PHOTO_CODE:
        final File file = getTempFile(this);
        try {
          Bitmap captureBmp = Media.getBitmap(getContentResolver(), Uri.fromFile(file) );
          // do whatever you want with the bitmap (Resize, Rename, Add To Gallery, etc)
        } catch (FileNotFoundException e) {
          e.printStackTrace();
        } catch (IOException e) {
          e.printStackTrace();
        }
      break;
    }
  }
}


Ads from Amazon:
Explanation
final Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, getTempFile(this) );
startActivityForResult(intent, TAKE_PHOTO_CODE);

This is the core of the code, here we call an intent from the MediaStore which would open up the camera app, then we pass the output path of the captured image to a temporary location (Always use a safe location to store the image). Here we use the Environment.getExternalStorageDirectory() which is our SDCard, again for safety reason check if the SDCard is present or not. Then we start the activity, expecting a result with code TAKE_PHOTO_CODE

final File file = getTempFile(this);
try {
Bitmap captureBmp = Media.getBitmap(getContentResolver(), Uri.fromFile(file) );
}...{}

Knowing where the output of the file will be, we would open that file and place it on a bitmap where we would do our magic

Conclusion
ACTION_IMAGE_CAPTURE has done a great job so that we wont implement our own implementation of the camera app, so use it.

Update History
   Jan 17, 2012 - Visual Update

Thursday, October 28, 2010

How to restart your own app in Android Tutorial

After launching (now refactoring) Shoot and Learn [ Market Link | AndroidPit.com Link ] , its time to write what i have learn.

Senario
You want to restart your app because of some preference/setting changed, or you just want to restart your app.

Notes
This might not be the best solution thus if you have a better one kindly comment below :)

Introduction
First we need our main activity to be a routing activity (if you came from the web, most framework do this where you have an index page where it routes other calls to its right controller). This main activity we shall call PreMainActivity, in this tutorial we would only put the restart logic on this activity, you can put things like preloader, first run activity, etc.


What Do I Need
In Manafiest.xml
<activity 
 android:name=".PreMainActivity"
 android:label="@string/app_name"
 android:launchMode="singleTop"
 android:configChanges="locale"
>
 <intent-filter>
  <action android:name="android.intent.action.MAIN" />
  <category android:name="android.intent.category.LAUNCHER" />
 </intent-filter>
</activity>
<activity android:name=".Main"
 android:configChanges="locale"
/>



In PreMainActivity.java
public class PreMainActivity extends Activity {
 public static Boolean ENABLE_RESTART = false;
 
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  ENABLE_RESTART = true;
  restartMain();
 }
 
 @Override
 public void onRestart() {
  super.onRestart();
  restartMain();
 }
   
 public void restartMain(){
  if(ENABLE_RESTART == true){
   Intent mainIntent = new Intent(this, Main.class);
   mainIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP  );
   startActivity(mainIntent);
   finish();
  }else{
   finish();
  }
  ENABLE_RESTART   = false;
 }    
}


In your activity where you want to trigger the restart
PreMainActivity.ENABLE_RESTART = true;
Intent i = new Intent(this,PreMainActivity.class);
i.addFlags( Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(i);



Explanation
<activity

android:name=".PreMainActivity"

.... />

As stated in our introduction we would use a PreMainActivity as the receiver of our main action.

public static Boolean ENABLE_RESTART = false;
In our activity we would have a static variable to check if the activity should restart or not.

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ENABLE_RESTART = true;
restartMain();
}

When our app is first launched we would need to turn the flag to true in order for our next activity to restart/start.

Intent mainIntent = new Intent(this, Main.class);
mainIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP );
startActivity(mainIntent);
finish();

With this code, i assumed that main is on the top of the activity stack therefore we could just relaunch it as clear the whole stack. See (http://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_CLEAR_TOP).

PreMainActivity.ENABLE_RESTART = true;
Intent i = new Intent(this,PreMainActivity.class);
i.addFlags( Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(i);

Combined with android:launchMode="singleTop" in our manifest file, we make sure that when we launch PreMainActivity we get a clear top, single top activity. Note I might be doing some redundancy on singletop flag.

Conclusion
This how you can restart your app but this is not the best solution, as stated above im in a refactoring mode, in where instead of having a static variable, i would pass data i.putExtra("RESTART", true); on the intent. Which is a better solution, but if you have any better idea please do comment below and ill try to be more active with this blog :)

Saturday, October 16, 2010

Shoot and Learn

After few months of developing an android app for fun, finally got to release one on the market :)
Firstly thanks to SK Lam (his daugher's blog), to my parents for letting me stay late, to my friends for their suppor, to all who tested the app and to everyone that would download it.

The app is an application for kids to learn objects around them by capturing it and learning it like flash cards. From the sound of that there shouldn't be anything special with the app right?
Yes and no, yes its a flash card app like other but no, it has a better UI and UX (i hope) and its colorful with different themes (Signs of being a frontend guy, ahah).

Another interesting aspect is the Language feature (which i would like to open source it later when its ready), in here users can crowd source the language translation so that the translation of the app would be from its user base and thats the fun part of it :)

There is still a lot of improvements on the app and on the codes level, so brace yourself for bugs.

Head over the market place and search for "shoottolearn" <-- easier to find it with this way

Next blogs would be sharing the how to do on the apps. Any features on my app that you guys want me to blog? Comment down below. Thanks