Showing posts with label Android. Show all posts
Showing posts with label Android. Show all posts

Monday, March 12, 2012

Fun Android camera gotcha

Android's camera object includes a method called takePicture which takes 3 callbacks as arguments:
1) shutter callback
2) raw callback
3) jpeg callback

The shutter callback occurs roughly when the shutter sound occurs in the stock camera.

Raw callback and jpeg callback occur when camera image data is available. Well, RAW > JPEG, right? So why not just implement RAW callback and skip JPEG callback? If you code up the RAW callback, you'll find that you can't get an image from the returned data. The object is non-null, but upon further inspection has zero length. What did I do wrong? you'll think. Actually, nothing, it just doesn't work. Never has. Yet it's still there in the libraries and in the documentation after years and years, without any note or anything that it doesn't freaking work. Huh? (typical Android).

Monday, March 05, 2012

Android ProgressDialog and Threads

Many tasks require an application to get or post data from/to some web service. Since internet communication can be quick or quite lengthy, it's necessary to notify the user that some work is occurring. Android's ProgressDialog gives you two options: a dialog with a bar (like a copy dialog on Windows) or a spinner dialog (typical for Ajax web apps).

Unfortunately, using the progress dialog can be painful. Frustratingly, many tutorials show you how to instantiate a ProgressDialog but not how to use it properly, failing to mention that if you make a blocking call on the UI thread (like an HTTP request), the ProgressDialog will never actually appear. After 2 seconds, the Android OS will think your app has frozen and kill it. Great.

Many forum posts suggest using Android's AsyncTask to execute the "work" in the background (AsyncTask is supposed to be easier to use than creating a new thread), but I've found AsyncTask to be more headache than help. Just create a thread. It's not hard.

FYI, ProgressDialog requires a context (the calling activity), a message to display, and a handler to do some work. Your handler can only receive ONE variable, so I tend to use a HashMap so I can pass multiple bits of data.

I've come up with a pattern that I've reused and works well. Here we go!

  1. Create a thread class.

  2. public class WorkerThread extends Thread {
    private ProgressDialog dialog;
    private Handler handler;
    private HashMap messageData = new HashMap();

    // .. put your constructor etc here ...
    public WorkerThread(ProgressDialog dialog, Handler handler) {
    this.dialog = dialog;
    this.handler = handler;
    }

    public void run() {
    // Var to keep track of whether the work succeeded or not
    Boolean status = true;
    // ... do some work here ...

    // If an error occurred...
    if(error) {
    status = false;
    messageData.put("message", "Error message goes here");
    }
    messageData.put("status", status);

    // Send a message back to calling activity
    handler.obtainMessage(0x2a, messageData).sendToTarget();

    // Dismiss dialog
    if (dialog != null && dialog.isShowing())
    dialog.dismiss();
    }

    // Clean up if the thread is cancelled
    public void cancel() {
    messageData.put("status", false);
    handler.obtainMessage(0x2a, messageData).sendToTarget();
    if (dialog != null && dialog.isShowing())
    dialog.dismiss();
    }
    }
  3. Add a thread and a null handler to your activity.
  4. WorkerThread WorkerThreadInstance = null;
    Handler handler = null;
  5. Create the ProgressDialog in your Activity's onCreate

  6. ProgressDialog workDialog = ProgressDialog.show(this, "", "Working...", true);
  7. Create a handler.

  8.   // Handle response from the worker thread
    handler = new Handler() {
    @SuppressWarnings("unchecked")
    @Override
    public void handleMessage(Message msg) {
    super.handleMessage(msg);
    HashMap data = (HashMap) msg.obj;
    Boolean status = (Boolean) data.get("status");

    if (status==true) {// if successful
    Toast.makeText(getApplicationContext(), "Work was successful",
    2000).show();
    // Process return data here
    // Uncomment the next line if your activity should end once processing is done
    //finish();
    } else {
    if(data.get("message")!=null) {
    Toast.makeText(getApplicationContext(), "Work failed!" + data.get("message") ,
    3000).show();
    }
    // Uncomment the next line if your activity should end after an error
    //finish();
    }
    }
    };
  9. Instantiate your worker thread

  10.   // Create an instance of the worker thread
    WorkerThreadInstance = new WorkerThread(workDialog, handler);
    WorkerThreadInstance.start();
  11. Implement onPause for your activity to stop the worker thread if the activity is paused(and possibly onResume-- though be aware that onResume will be called before onCreate)

  12.  @Override
    public void onPause() {
    super.onPause();

    if (WorkerThreadInstance != null) {
    WorkerThreadInstance.cancel();

    // Mark thread for deletion by GC or there will be a memory leak
    WorkerThreadInstance = null;
    }
    }

Android ListView

Android includes a ListView element designed to make it easy to create lists. But it's not as straightforward as adding a ListView element and then calling some add function. You will need to create an "ArrayAdapter" and a couple of layout XML files, unless you want to create a simple list of strings (change your activity from extending Activity to ListActivity and use the default array adapter).

Rather than explain the process, I refer you to a great tutorial which be found here.

Monday, March 08, 2010

Install Android 2.1 USB Device Driver on Windows 7 64 bit

Windows 7 64 bit has difficulty installing the current USB drivers for Android devices. You'll need these to actually test Android applications on a phone.

Feel free to poke around Control Panel for an hour trying to force it to recognize the drivers sitting on your hard drive. It simply won't comply.

Luckily there is an easy work around-- install PDANet. You can remove the program after installation-- it will leave the drivers behind.

See:
http://forum.xda-developers.com/showthread.php?t=502010&page=22
http://androidforums.com/motorola-droid/35877-cant-get-tether-work.html

Tuesday, December 01, 2009

Install and Uninstall Applications on an Android Device

Adding an application
  1. Change directory to the Android SDK directory/tools
  2. Make sure either the phone is connected or the emulator is running
  3. Double check the connection by typing
    android list
    Make sure your device is in the list (you can also type adb devices but this doesn't give as much information)
  4. Type adb install yourapkfile.apk
  5. You will see output such as:
    1227 KB/s (982154 bytes in 0.781s)
    pkg: /data/loca/tmp/yourapkfile.apk
    Success
Removing Applications
  1. Turn on the phone or run the emulator
  2. Open the tray
  3. Go to settings
  4. Click Applications
  5. Click "Manage Applications"
  6. Click the name of the application you wish to uninstall
  7. Click the button "Uninstall"
  8. You should get a message confirming the application was uninstalled

Friday, September 18, 2009

Get Started with the Android Emulator

  1. Install SDK (http://developer.android.com/sdk/1.6_r1/index.html)
  2. Open command prompt window
    Start>Run>cmd.exe
  3. Change directory to Android SDK folder
  4. List available Android Images from command line
    > android list targets
    With the SDK as of September 2009, 1.5 and 1.6 images are available.
  5. The emulator requires an Android Virtual Device to be created which simulates the firmware of an Android device. This is based off one of the images listed by the above command.
  6. Create an AVD by typing
    > android create avd -n -t X
    where -t X specifies the ID of the image to use during creation (replace X with the ID of the desired image to use)
    So if you want a version 1.5 AVD, you can create it by
    > android create avd -n myavd -t 1
    Android 1.5 is a basic Android platform.
    Do you wish to create a custom hardware profile [no]
    Created AVD 'myavd' based on Android 1.5
  7. If you should ever want to delete an AVD, type the following
    > android delete avd -n
  8. Start the emulator now with
    emulator -avd -sdcard C:\work\software\android\sdcard.img –verbose

Tuesday, September 08, 2009

Replace Android Browser Binary

Installation Instructions (you must have root access):

Download the updated Browser.apk
Run the following from the command prompt to back up your current Browser file to your sdcard and install the new one:
adb remount
adb pull /system/app/Browser.apk BrowserBackup.apk
adb push BrowserBackup.apk /sdcard
adb shell rm /system/app/Browser.odex
adb push Browser.apk /system/app

Labels

Blog Archive

Contributors