One of the major drawbacks of Android development is in the missing sources of the framework. At least in my opinion. Attaching the sources seemed like a logical step to me. Easy enough I found Google's step-by-step instructions on how to download the source files from the repo (http://source.android.com/download). This took a huge amount of time and produced some 8 GBs of data on disk. Pretty huge for just some source, huh?
So I kept on searching. Luckily, I found this post, providing zipped pure sources for SDK 1.5, 1.6, and 2.1. Zip files are just around 22 MB. You just create a folder named 'sources' for the related platform and extract the files/folders from the zip into that folder. Once you refresh your projects in Eclipse your sources are there. Awesome!
25 January 2010
15 January 2010
Adding Multitouch support
Since Android now supports multitouch, I wanted to find a code snippet illustrating its usage. Sounds like a piece of cake but actually isn't.
Once you get the job done, implementing multitouch on Android is really simple. See the snippet which will write out the x- and y-coordinates for each finger on the screen (this made me realize the Motorola Milestone can only identify 2 fingers at once) to LogCat:
Once you get the job done, implementing multitouch on Android is really simple. See the snippet which will write out the x- and y-coordinates for each finger on the screen (this made me realize the Motorola Milestone can only identify 2 fingers at once) to LogCat:
@Override public boolean onTouch(View v, MotionEvent event) { for (int i=0; i<event.getPointerCount(); i++) { (...) Log.d("Pointer", "Pointer "+(i+1)+": x="+event.getX(i)+", y="+event.getY(i)); } (...) }
I found a topic about this on the Android Google group: http://groups.google.com/group/android-developers/browse_thread/thread/232ed8c380da7b64.
The provided (and simplified) snippet is based on this example app.
08 January 2010
Need to format the source code
Alright, this just looks dumb. I'll look for a way to better integrate (i.e. format) the code snippets which seem plain unusable right now.
Taking photos from the handset's camera via Intents
Taking a photo via the camera is actually a really easy task in Android if using Intents. I provide a little code snippet which illustrates its usage.
Fire up an intent to start the 'photo-taking' activity:
mTakePhoto = (ImageButton)findViewById(R.id.takePhoto); mTakePhoto.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // fire off an intent for the camera
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(intent, REQUEST_CAMERA); } });
This will launch the 'photo-taking' activity which lets you take a picture. To get (and handle) the result you will need a listener to respond when the image capture is finished:
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data); // if Activity was canceled, display a Toast message for 1 second
if (resultCode == RESULT_CANCELED) { Toast toast = Toast.makeText(this,"Activity cancelled", 1000); toast.show(); return; } // lets check if we are really dealing with a picture
if (requestCode == REQUEST_CAMERA && resultCode == RESULT_OK) { String timestamp = Long.toString(System.currentTimeMillis()); // get the picture
mPicture = (Bitmap) data.getExtras().get("data"); // save image to gallery MediaStore.Images.Media.insertImage(getContentResolver(), mPicture, timestamp, timestamp); Uri uri=MediaStore.Images.Thumbnails.getContentUri("external"); Cursor cursor=MediaStore.Images.Thumbnails.queryMiniThumbnails (getContentResolver(), uri, MediaStore.Images.Thumbnails.MICRO_KIND, null); Long _imageId = null; cursor.moveToFirst(); while(true){ for(int i=0;i<cursor.getColumnCount();i++){ if(cursor.getColumnName(i).equals("image_id")) { _imageId = Long.parseLong(cursor.getString(i)); } } if(cursor.isLast()){ break; } else { cursor.moveToNext(); } } // Get Bitmap and scale to default icon size Bitmap tmp = MediaStore.Images.Thumbnails.getThumbnail(getContentResolver(), _imageId, MediaStore.Images.Thumbnails.MICRO_KIND, null); tmp = Bitmap.createScaledBitmap(tmp, 48, 48, true); // Update ImageButton icon mTakePhoto.setImageBitmap(tmp); // save image to SD card try { File directory = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/SOME_DIR/"); if(!directory.exists()) directory.mkdir(); FileOutputStream fos = new FileOutputStream(directory+"/"+timestamp+".jpg"); Environment.getExternalStorageDirectory().mkdir(); mPicture.compress(Bitmap.CompressFormat.JPEG, 90, fos); } catch (Exception e) { e.printStackTrace(); } } }
The listener responds when an photo was taken and lets you access the data. What I am doing with the data is this:
- add it to the device's media gallery
- create a bitmap thumbnail to update to button's icon with the just taken picture
- additionally store the image on the sd-card on an arbitrary location
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); // if Activity was canceled, display a Toast message for 1 second if (resultCode == RESULT_CANCELED) { Toast toast = Toast.makeText(this,"Activity cancelled", 1000); toast.show(); return; } // lets check if we are really dealing with a picture if (requestCode == REQUEST_CAMERA && resultCode == RESULT_OK) { // get the picture mPicture = (Bitmap) data.getExtras().get("data"); // save image to gallery MediaStore.Images.Media.insertImage(getContentResolver(), mPicture, timestamp, timestamp); } }
Coming clean
So this is it. I decided to post my experiences with Android. Actually, this is my 1st blog ever. Well, okay, I created a couple but never for myself. 'So why do you start this just on Android?' one might ask. Pretty simple: it documents the progress a make. Maybe it's (weird) sort of a diary 2.0. And maybe it's going to help some others, preventing them from running into the exact same time consuming pitfalls I ran into.
Let's get my hands dirty. What I am going to need (and will be using):
Let's get my hands dirty. What I am going to need (and will be using):
- MacBook Pro, OS 10.6.2
- Motorola Milestone (Droid in the US) running Android 2.0
- Eclipse Classic 3.5.1 for Mac Cocoa 64bit
- Android SDK r04
- Eclipse ADT plugin 0.9.4 0.9.5
- SDK components (available via terminal or Eclipse plugin)
Installation and configuration worked out pretty straightforward.
But when the ADT plugin was updated from 0.9.4 to 0.9.5 Eclipse refused to start at all. I created a thread over at anddev.org to get some help. Since I didn't find any I had to reinstall Eclipse and Android SDK. This turned out to be a much quicker thing than messing around with the old one, combing through various configuration files on different locations.
Having 'fixed' the issue I just created a backup copy of my entire Eclipse folder, granting a working version at all times.
The next post will provide some first code snippets.
Subscribe to:
Posts (Atom)