Skip to content

Using Hardware, Sensors and Device data

Nathan Esquenazi edited this page Aug 19, 2013 · 9 revisions

Overview

With Android, there is a lot of access to hardware features using built-in Android libraries and the Google Play SDK. A few examples of things you might need to access:

  • Taking a photo/video with the camera.
  • Accessing and playing photo/video/audio.
  • Accessing hardware sensors like accelerometers, light sensors, etc.
  • Using the Locations API.
  • Using the Maps API.

Using the Camera

The camera implementation depends on the level of customization required:

  • The easy way - launch the camera with an intent, designating a file path, and handle the onActivityResult.
  • The hard way - use the Camera API to embed the camera preview within your app, adding your own custom controls.

Easy way works in most cases, using the intent to launch the camera:

public void getPhotoFileUri(fileName) {
  File mediaStorageDir = new File(
        Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
        "MyCameraApp");

    // Create the storage directory if it does not exist
    if (!mediaStorageDir.exists() && !mediaStorageDir.mkdirs()){
        Log.d("MyCameraApp", "failed to create directory");
    }
    // Specify the file target for the photo
    fileUri = Uri.fromFile(new File(mediaStorageDir.getPath() + File.separator +
		        fileName));
}

public void onLaunchCamera(View view) {
    // create Intent to take a picture and return control to the calling application
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    intent.putExtra(MediaStore.EXTRA_OUTPUT, getPhotoFileUri("photo.jpg")); // set the image file name
    // start the image capture Intent
    startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
       Uri takenPhotoUri = getPhotoFileUri("photo.jpg");
       // by this point we have the camera photo on disk
       // Bitmap takenImage = BitmapFactory.decodeFile(filePath);
    }
}

Accessing Stored Media

Similar to the camera, the media picker implementation depends on the level of customization required:

  • The easy way - launch the Gallery with an intent, and get the media URI in onActivityResult.
  • The hard way - fetch thumbnail and full-size URIs from the MediaStore ContentProvider.

Easy way is to use an intent to launch the gallery:

// PICK_PHOTO_CODE is a constant integer
public void onPickPhoto(View view) {
    Intent intent = new Intent(Intent.ACTION_PICK,
        MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    startActivityForResult(intent, PICK_PHOTO_CODE);
}

// Used to retrieve the actual filesystem URI based on the media store result
private String getFileUri(Uri mediaStoreUri) {
		String[] filePathColumn = { MediaStore.Images.Media.DATA };
    Cursor cursor = getActivity().getContentResolver().query(mediaStoreUri,
            filePathColumn, null, null, null);
    cursor.moveToFirst();
    int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
    String fileUri = cursor.getString(columnIndex);
    cursor.close();
    
    return fileUri;
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
   if (requestCode == PICK_PHOTO_CODE) {
      photoUri = getFileUri(data.getData());
      // do something to the photo
      // Bitmap selectedImage = BitmapFactory.decodeFile(filePath);
   }
}

Playing Videos

VideoView is the default wrapper for MediaPlayer for playing videos:

public void playUrl(String url) {
    // videoview defined in the layout XML
    videoView.setVideoPath(url);
    videoView.setMediaController(new MediaController(this));       
    videoView.requestFocus();   
    videoView.start();
}

Accessing Sensors

Different devices have a variety of sensors that can be accessed via the Sensor framework. Possible tasks include:

  • List available sensors
  • Determine sensor capabilities (range, resolution, etc)
  • Acquire raw sensor data
  • Register sensor event listeners

You can register for sensor events:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    mSensorManager = 
        (SensorManager)getSystemService(Context.SENSOR_SERVICE);
    mLight = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
    mSensorManager.registerListener(this, mLight,    
        SensorManager.SENSOR_DELAY_NORMAL);
}

public void onSensorChanged(SensorEvent event) {
    ...
}

Location

Location requires the use of the Google Play SDK. The Location API is a higher-level API that wraps the underlying location sensor. You can accomplish tasks like:

  • Connect to the location sensor
  • Register for updates or accuracy changes
  • Get last location
  • Register for sensor connection events
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
		
    mLocationClient = new LocationClient(this, this, this);
    mLocationClient.connect();
}

public void onConnected(Bundle arg0) {
    Location mCurrentLocation = mLocationClient.getLastLocation();
    Log.d("DEBUG", "current location: " + mCurrentLocation.toString());
}

and register for location updates:

public void onLocationChanged(Location location) {
    // Report to the UI that the location was updated
    String msg = "Updated Location: " +
        Double.toString(location.getLatitude()) + "," +
        Double.toString(location.getLongitude());
    Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
}

For using maps check out the Android Maps Tutorial.

References

Clone this wiki locally