Tuesday, 5 April 2011

Want to run Android on your Windows 7 Desktop?

Well you could install the Android SDK. Or you could get bluestacks.com's Android Virtual Machine. Here are the details.

BlueStacks offering Android virtualization within Windows, harmony for one and all -- Engadget



The web site doesn't seem to work yet, but the idea is very interesting. We needs a Beta!

Monday, 4 April 2011

CamcorderProfile: predefined camcorder profile settings for camcorder applications

How to "Start Video Recording using android.provider.MediaStore.ACTION_VIDEO_CAPTURE" have been described in last exercise. If you want to develope your own custom camcorder applications (will be introduced in coming post), you have to set many settings manually; such as
- file output format
- Video codec format
- Video bit rate in bits per second
- Video frame rate in frames per second
- Video frame width and height
- Audio codec format
- Audio bit rate in bits per second,
- Audio sample rate
- Number of audio channels for recording.

Starting with Android 2.2 (API Level 8), android.media.CamcorderProfile class provide a static method get(int quality) to retrieve the predefined camcorder profile settings, QUALITY_HIGH and QUALITY_LOW (More profiles for API Level 11). It's a exercise to list the predefined settings for each profile.

QUALITY_HIGH
QUALITY_LOW

First of all, create a /res/values/array.xml to define the profiles, it have to be matched with constCamcorderProfile[] in AndroidCamcorderProfile.java
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="profile">
<item>QUALITY_HIGH</item>
<item>QUALITY_LOW</item>
</string-array>
</resources>


AndroidCamcorderProfile.java
package com.exercise.AndroidCamcorderProfile;

import android.app.Activity;
import android.media.CamcorderProfile;
import android.media.MediaRecorder.AudioEncoder;
import android.media.MediaRecorder.OutputFormat;
import android.media.MediaRecorder.VideoEncoder;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;

public class AndroidCamcorderProfile extends Activity {

Spinner spProfileList;
TextView textProfile;

int[] constCamcorderProfile ={
CamcorderProfile.QUALITY_HIGH,
CamcorderProfile.QUALITY_LOW};

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

spProfileList = (Spinner)findViewById(R.id.profilelist);
textProfile = (TextView)findViewById(R.id.profile);

ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
R.array.profile, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spProfileList.setAdapter(adapter);
spProfileList.setOnItemSelectedListener(spProfileListOnItemSelectedListener);
}

private Spinner.OnItemSelectedListener spProfileListOnItemSelectedListener
= new Spinner.OnItemSelectedListener(){

@Override
public void onItemSelected(AdapterView<?> parent, View view, int position,
long id) {
// TODO Auto-generated method stub
String selectedProfile = parent.getAdapter().getItem(position).toString();
textProfile.setText(selectedProfile);
CamcorderProfile camcorderProfile
= CamcorderProfile.get(constCamcorderProfile[position]);

String profileInfo;
profileInfo = selectedProfile + " : \n"
+ camcorderProfile.toString() + "\n";
profileInfo += "\n" + "audioBitRate: "
+ String.valueOf(camcorderProfile.audioBitRate)
+ "\n" + "audioChannels: "
+ String.valueOf(camcorderProfile.audioChannels)
+ "\n" + "audioCodec: "
+ getAudioCodec(camcorderProfile.audioCodec)
+ "\n" + "audioSampleRate: "
+ String.valueOf(camcorderProfile.audioSampleRate)
+ "\n" + "duration: "
+ String.valueOf(camcorderProfile.duration)
+ "\n" + "fileFormat: "
+ getFileFormat(camcorderProfile.fileFormat)
+ "\n" + "quality: "
+ String.valueOf(camcorderProfile.quality)
+ "\n" + "videoBitRate: "
+ String.valueOf(camcorderProfile.videoBitRate)
+ "\n" + "videoCodec: "
+ getVideoCodec(camcorderProfile.videoCodec)
+ "\n" + "videoFrameRate: "
+ String.valueOf(camcorderProfile.videoFrameRate)
+ "\n" + "videoFrameWidth: "
+ String.valueOf(camcorderProfile.videoFrameWidth)
+ "\n" + "videoFrameHeight: "
+ String.valueOf(camcorderProfile.videoFrameHeight);

textProfile.setText(profileInfo);
}

@Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
textProfile.setText("");
}};

private String getAudioCodec(int audioCodec){
switch(audioCodec){
case AudioEncoder.AMR_NB:
return "AMR_NB";
case AudioEncoder.DEFAULT:
return "DEFAULT";
default:
return "unknown";
}
}

private String getFileFormat(int fileFormat){
switch(fileFormat){
case OutputFormat.MPEG_4:
return "MPEG_4";
case OutputFormat.RAW_AMR:
return "RAW_AMR";
case OutputFormat.THREE_GPP:
return "THREE_GPP";
case OutputFormat.DEFAULT:
return "DEFAULT";
default:
return "unknown";
}
}

private String getVideoCodec(int videoCodec){
switch(videoCodec){
case VideoEncoder.H263:
return "H263";
case VideoEncoder.H264:
return "H264";
case VideoEncoder.MPEG_4_SP:
return "MPEG_4_SP";
case VideoEncoder.DEFAULT:
return "DEFAULT";
default:
return "unknown";
}
}

}


<?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"
/>
<Spinner
android:id="@+id/profilelist"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView
android:id="@+id/profile"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>


Download the files.

Related Article:
- A simple exercise of Video Capture using MediaRecorder

iOS 4.3.1 + bb prevention + TU + you

First off I want to congratulate @i0n1c on his magic. Great job bud!


One question I've been getting quite often is "Will TinyUmbrella prevent iPhone 4 baseband updates for X version?" The simple answer to this question is: Yes. TinyUmbrella will, as far as I can tell, ALWAYS prevent iPhone baseband updates for the iPhone 4 GSM. This is due to a flaw in the way Apple tried preventing unauthorized baseband installs. They introduced a baseband shsh but unwittingly (or on purpose I don't know for sure) put into place a means for us to restore a firmware and prevent the bb update by merely ignoring the bb shsh request.


Now, that said, iOS 4.3.1 seems to have some kind of incompatibilities (the only notable one was mentioned by @musclenerd warning ultrasn0w unlockers to wait until a fix is pushed for 4.3.1 problems). This is likely why those of you that updated to 4.3.1 using TinyUmbrella are seeing oddities ie. One signal bar wherever you go. Hopefully, the incompatibility can be patched in the iOS layer allowing those of us that do not rely on unlocks to keep the old baseband as we all usually prefer :)

Sunday, 3 April 2011

Start Video Recording using android.provider.MediaStore.ACTION_VIDEO_CAPTURE

In this exercise, when user click on the "Recording Video using Intent" button, it will start activity with android.provider.MediaStore.ACTION_VIDEO_CAPTURE to ask Android system to start a app helping record video.
When user click on the "Playback" button, the video will be played on the VideoView if exist.

Start Video Recording using ACTION_VIDEO_CAPTURE

To ask video recording using android.provider.MediaStore.ACTION_VIDEO_CAPTURE, simple call startActivityForResult() method with Intent of android.provider.MediaStore.ACTION_VIDEO_CAPTURE.

In onActivityResult() call-back function, check resultCode and requestCode. If both valid and match, the uri of the recorded video file can be retrieved using data.getData().

package com.exercise.AndroidIntentVideoRecording;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import android.widget.VideoView;

public class AndroidIntentVideoRecording extends Activity {

final static int REQUEST_VIDEO_CAPTURED = 1;
Uri uriVideo = null;
VideoView videoviewPlay;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button buttonRecording = (Button)findViewById(R.id.recording);
Button buttonPlayback = (Button)findViewById(R.id.playback);
videoviewPlay = (VideoView)findViewById(R.id.videoview);

buttonRecording.setOnClickListener(new Button.OnClickListener(){

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Intent intent = new Intent(android.provider.MediaStore.ACTION_VIDEO_CAPTURE);
startActivityForResult(intent, REQUEST_VIDEO_CAPTURED);
}});

buttonPlayback.setOnClickListener(new Button.OnClickListener(){

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
if(uriVideo == null){
Toast.makeText(AndroidIntentVideoRecording.this,
"No Video",
Toast.LENGTH_LONG)
.show();
}else{
Toast.makeText(AndroidIntentVideoRecording.this,
"Playback: " + uriVideo.getPath(),
Toast.LENGTH_LONG)
.show();
videoviewPlay.setVideoURI(uriVideo);
videoviewPlay.start();
}
}});
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
if(resultCode == RESULT_OK){
if(requestCode == REQUEST_VIDEO_CAPTURED){
uriVideo = data.getData();
Toast.makeText(AndroidIntentVideoRecording.this,
uriVideo.getPath(),
Toast.LENGTH_LONG)
.show();
}
}else if(resultCode == RESULT_CANCELED){
uriVideo = null;
Toast.makeText(AndroidIntentVideoRecording.this,
"Cancelled!",
Toast.LENGTH_LONG)
.show();
}
}
}


main.xml
<?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"
/>
<Button
android:id="@+id/recording"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Recording Video using Intent"
/>
<Button
android:id="@+id/playback"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Playback"
/>
<VideoView
android:id="@+id/videoview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>


Download the files.

Related article:
- CamcorderProfile: predefined camcorder profile settings for camcorder applications
- A simple exercise of Video Capture using MediaRecorder
- Using MediaStore.EXTRA_OUTPUT specify target file for MediaStore.ACTION_VIDEO_CAPTURE

Saturday, 2 April 2011

Android Programming Tutorials, 3rd Edition



Product Description

Android Programming Tutorials show you what you can do with Android, through a series of 40 individual exercises. Android Programming Tutorials gives you hands-on instruction in how to build sophisticated Android applications, using many of the technologies outlined in CommonsWare's other Android books. These exercises lead you through the basics of creating Android applications, all the way through many fun Android features like Internet access, location tracking, maps, integrated WebKit browsers, cameras, accelerometers, home screen widgets, and much more. Full source code to all the exercise answers is available, to help you if you get stuck. Android Programming Tutorials makes an excellent companion volume to more traditional Android books that merely tell you what is possible.
From the Publisher Android Programming Tutorials is a collection of exercises that will have you build a pair of relatively sophisticated Android applications: a restaurant database and a microblogging client. The goal of the tutorials is to expose you to a wide range of Android capabilities in the context of a larger application, rather than standalone demonstrations like a programming guide might profile. Each exercise is a set of step-by-step instructions on how to add different features and functions. There is only a bit of theory presented, focusing instead of having you "learn by doing".

Each exercise contains pointers for further reading, along with "extra credit" tasks you might wish to try, to experiment in areas beyond what the step-by-step instructions supply. Hence, this book is geared for people who like working through code, but want guidance along the way.

These tutorials cover many major areas of Android application development, including:

Setting up basic user interfaces, with fields, buttons, lists, tabs, and radio buttons
Adding option menus
Supporting both portrait and landscape orientations, with custom user interfaces for each
Storing data in local databases
Collecting preferences from the user and applying those preferences
Working with background threads
Having multiple screens ("activities") in a single application, linked to each other
Accessing Web services via your own HTTP client code or via existing third-party JARs that somebody else wrote to access a service's API
Setting up Android components decoupled from their user interfaces ("services"), including allowing a service in one application to serve clients in other applications
Putting icons in the status bar ("notifications")
Integrating location tracking and Google Maps
Embedding a WebKit Web browser (e.g., for online help)
Incorporating video playback (e.g., for a screencast to accompany the online help)
Animating our user interface, to allow portions of it to fade in or out based on user request
Creating "app widgets" - bits of our UI that can go on the user's home screen
Integrating with the camera and accelerometer

The source code for this book is available from the CommonsWare Web site and is open source, so you can do with it whatever you wish within the license terms.

And, if you have any questions about the book or the exercises, join the [cw-android] Google Group, and we will be happy to help!

The CommonsWare Combo

These tutorials are used as part of the author's live training, so hundreds of students in dozens of classes have gone through these as part of those events. Their feedback, plus the feedback of the readers of the print and digital editions of the book, have helped refine and shape the tutorials. This 3rd Edition reflects those changes...at least, those changes that have been made by the time this book went to print.

That's the problem with print books: they're static. While Android Programming Tutorials is updated every few months in digital form, the print edition remains fixed for much longer. Usually, you have to make a decision when buying a book - do you want the print edition or the digital edition?

With this book, you do not have to make that choice.

Purchasers of this book may qualify for free digital editions of this book, as part of a "CommonsWare Combo". This gives you the benefit of the print copy, plus you get access to the latest digital edition and all of its updates, such as to take into account new Android SDK releases.

This "combo" not only gives you access to the digital edition of this book, but access to digital editions of every CommonsWare book, including The Busy Coder's Guide to Android Development and The Busy Coder's Guide to Advanced Android Development. What you really get is a one-month Warescription and all the benefits of that program, albeit for a short period of time.

To see how you may qualify for the CommonsWare Combo, visit the CommonsWare Web site and click on the Warescription link.

Bing Maps Android SDK: create mapping applications using Microsoft's Bing Maps

The Bing Maps Android SDK is a base project that can be used to help developers create mapping applications using Microsoft's Bing Maps. This is written in Java and built using the Bing Maps AJAX v7 control.

This SDK consists of a set of libraries and assets that can be used to create Bing Maps applications. These libraries are put together into a sample application which you can either use as a base for your application or as a guide to create your own from scratch.



Features
- Built on top of Bing Maps AJAX V7
- Touch controls added to support pinch to zoom, and double tap to zoom
- Majority of map functionalities are wrapped with Java code so that there is no need to write JavaScript code. This should make things easier for Android developers.
- Requires Bing Maps Key
- Supports Pushpins, Polylines, Polygons, EntityCollections, and TileLayers.
- Libraries for accessing Bing Maps REST service supports Geocoding (Address and query searches), Reverse Geocoding, Routing with support for all route options.
- Libraries for accessing Bing Spatial Data service supports FindByArea, FindByID, and FindByProperty.
- All service calls have an Asynchronous task which make requests to Bing Servers and parses the response on a background tread.
- Works in any orientation.
- Infobox support.
- Location Details view.
- Support for GeoRSS files.

Here are some additional features that are planned to be added in the near future:

- Support for localization.
- Documentation of code, and articles on how to use the SDK to create an application.
- UI controls for rotating Birdseye view.
- Clustering.

Source: - Bing Maps Android SDK

Friday, 1 April 2011

Asus EEE Pad Transformer: First Android Tablet you should buy?

Maybe. With all the buzz around Motorola and Samsung tablets, the Asus EEE Pad Transformer has been kind of lost in the shuffle. Basically, the EEE pad is a tablet with a keyboard dock that allows your to use it as a laptop or tablet. SlashGear has all the details.



SlashGear: ASUS Eee Pad Transformer first-impressions [Video]



The review is very positive. Honeycomb 3, a beautiful screen, and great battery life. Plus Asus is known for being very aggressive with price. My experience with their netbooks and laptops has been mostly very good.



According to a London Telegraph story, it should be released in the UK next week. One story hinted at an April release in the US. I guess we will see.