Location, Camera & Sensors

GPS, camera capture, and device motion sensors in Android apps

GPS Fused Location CameraX Sensors

Table of Contents

Hardware Overview

Modern Android devices include GPS chips, cameras, and motion sensors. Apps access them through Android APIs with appropriate runtime permissions and battery-conscious patterns.

Location: GPS / Network / Fused Location Provider → Lat/Lng Camera: CameraX → Preview + ImageCapture → File / Bitmap Sensors: SensorManager → Accelerometer, Gyroscope → Float arrays
FeatureRecommended APIKey Permission
LocationFused Location Provider (Play Services)ACCESS_FINE_LOCATION
CameraCameraXCAMERA
Motion sensorsSensorManagerNone (normal permission)

1GPS Location

GPS (Global Positioning System) uses satellite signals to determine latitude, longitude, altitude, and accuracy. Android exposes location through the LocationManager and the higher-level Fused Location Provider.

Manifest permissions

XML — AndroidManifest.xml<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <!-- Background location (only if needed — requires extra approval) --> <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />

LocationManager (legacy approach)

Kotlin — Basic GPS via LocationManager@SuppressLint("MissingPermission") fun getLastKnownGpsLocation(context: Context): Location? { val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager val isGpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) if (!isGpsEnabled) { Log.w("GPS", "GPS provider is disabled") return null } return locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER) } @SuppressLint("MissingPermission") fun requestGpsUpdates(context: Context, callback: (Location) -> Unit) { val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager val listener = LocationListener { location -> callback(location) } locationManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, 5000L, // min time ms 10f, // min distance meters listener ) }

Location object properties

PropertyDescription
latitude / longitudeCoordinates in decimal degrees
accuracyRadius of uncertainty in meters
altitudeHeight above sea level (if available)
speedGround speed in m/s
timeUTC timestamp of fix

2Fused Location Provider

The Fused Location Provider (Google Play Services) intelligently combines GPS, Wi-Fi, and cell towers for accurate, battery-efficient location. It is the recommended approach for most apps.

Gradle dependency

Kotlin — app/build.gradle.ktsdependencies { implementation("com.google.android.gms:play-services-location:21.1.0") }

Get last known location

Kotlin — FusedLocationProviderClient@SuppressLint("MissingPermission") fun fetchLastLocation(activity: ComponentActivity, onResult: (Location?) -> Unit) { val fusedClient = LocationServices.getFusedLocationProviderClient(activity) fusedClient.lastLocation.addOnSuccessListener { location -> if (location != null) { Log.d("Location", "Lat: ${location.latitude}, Lng: ${location.longitude}") Log.d("Location", "Accuracy: ${location.accuracy}m") } onResult(location) }.addOnFailureListener { e -> Log.e("Location", "Failed to get location", e) onResult(null) } }

Request location updates

Kotlin — Continuous location updatesclass MapActivity : AppCompatActivity() { private lateinit var fusedClient: FusedLocationProviderClient private lateinit var locationCallback: LocationCallback override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) fusedClient = LocationServices.getFusedLocationProviderClient(this) locationCallback = object : LocationCallback() { override fun onLocationResult(result: LocationResult) { result.lastLocation?.let { location -> binding.tvCoords.text = "Lat: ${location.latitude}, Lng: ${location.longitude}" } } } } @SuppressLint("MissingPermission") fun startLocationUpdates() { val request = LocationRequest.Builder( Priority.PRIORITY_HIGH_ACCURACY, 5000L ) .setMinUpdateIntervalMillis(2000L) .build() fusedClient.requestLocationUpdates(request, locationCallback, mainLooper) } override fun onPause() { super.onPause() fusedClient.removeLocationUpdates(locationCallback) } }

Priority options

PriorityBehavior
PRIORITY_HIGH_ACCURACYGPS when possible — maps, navigation
PRIORITY_BALANCED_POWER_ACCURACYWi-Fi + cell — city-level accuracy
PRIORITY_LOW_POWERCell towers only — minimal battery
PRIORITY_PASSIVEOnly when other apps request location

3Camera API

CameraX is the modern Jetpack camera library — simpler than the legacy Camera2 API, with lifecycle-aware binding, preview, and capture use cases.

Gradle dependencies

Kotlin — app/build.gradle.ktsval cameraxVersion = "1.3.1" dependencies { implementation("androidx.camera:camera-core:$cameraxVersion") implementation("androidx.camera:camera-camera2:$cameraxVersion") implementation("androidx.camera:camera-lifecycle:$cameraxVersion") implementation("androidx.camera:camera-view:$cameraxVersion") }

Layout with PreviewView

XML — activity_camera.xml<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> <androidx.camera.view.PreviewView android:id="@+id/previewView" android:layout_width="0dp" android:layout_height="0dp" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toTopOf="@id/btnCapture" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" /> <Button android:id="@+id/btnCapture" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/capture" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" android:layout_marginBottom="32dp" /> </androidx.constraintlayout.widget.ConstraintLayout>

Start camera preview

Kotlin — CameraActivity.kt (preview setup)class CameraActivity : AppCompatActivity() { private lateinit var cameraProvider: ProcessCameraProvider private var imageCapture: ImageCapture? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_camera) val cameraProviderFuture = ProcessCameraProvider.getInstance(this) cameraProviderFuture.addListener({ cameraProvider = cameraProviderFuture.get() startCamera() }, ContextCompat.getMainExecutor(this)) } private fun startCamera() { val preview = Preview.Builder().build().also { it.setSurfaceProvider(binding.previewView.surfaceProvider) } imageCapture = ImageCapture.Builder() .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY) .build() val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA try { cameraProvider.unbindAll() cameraProvider.bindToLifecycle( this, cameraSelector, preview, imageCapture ) } catch (e: Exception) { Log.e("CameraX", "Use case binding failed", e) } } }

4Capturing Images

Capture photos to a file or memory buffer with CameraX ImageCapture, or use the system camera intent for a simpler delegate approach.

Capture to file with CameraX

Kotlin — takePhoto() to fileprivate fun capturePhoto() { val capture = imageCapture ?: return val photoFile = File( getExternalFilesDir(Environment.DIRECTORY_PICTURES), "IMG_${System.currentTimeMillis()}.jpg" ) val outputOptions = ImageCapture.OutputFileOptions.Builder(photoFile).build() capture.takePicture( outputOptions, ContextCompat.getMainExecutor(this), object : ImageCapture.OnImageSavedCallback { override fun onImageSaved(output: ImageCapture.OutputFileResults) { Toast.makeText( this@CameraActivity, "Saved: ${photoFile.absolutePath}", Toast.LENGTH_SHORT ).show() binding.ivThumbnail.setImageURI(Uri.fromFile(photoFile)) } override fun onError(exception: ImageCaptureException) { Log.e("CameraX", "Capture failed", exception) } } ) }

System camera intent (simple approach)

Kotlin — Take picture via system cameraclass ProfileActivity : AppCompatActivity() { private var photoUri: Uri? = null private val takePictureLauncher = registerForActivityResult( ActivityResultContracts.TakePicture() ) { success -> if (success && photoUri != null) { binding.ivProfile.setImageURI(photoUri) } } fun launchCamera() { val photoFile = File.createTempFile( "profile_", ".jpg", getExternalFilesDir(Environment.DIRECTORY_PICTURES) ) photoUri = FileProvider.getUriForFile( this, "${packageName}.fileprovider", photoFile ) takePictureLauncher.launch(photoUri) } }

FileProvider setup

XML — res/xml/file_paths.xml + manifest<paths> <external-files-path name="photos" path="Pictures/" /> </paths> <!-- AndroidManifest.xml --> <provider android:name="androidx.core.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider>

Pick from gallery

Kotlin — Pick image from galleryprivate val pickImageLauncher = registerForActivityResult( ActivityResultContracts.GetContent() ) { uri: Uri? -> uri?.let { binding.ivProfile.setImageURI(it) } } binding.btnGallery.setOnClickListener { pickImageLauncher.launch("image/*") }

5SensorManager

SensorManager gives access to device hardware sensors — accelerometer, gyroscope, light, proximity, and more. Register listeners in onResume and unregister in onPause to save battery.

Basic sensor setup

Kotlin — SensorActivity.ktclass SensorActivity : AppCompatActivity(), SensorEventListener { private lateinit var sensorManager: SensorManager private var accelerometer: Sensor? = null private var gyroscope: Sensor? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_sensor) sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) gyroscope = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE) if (accelerometer == null) { Toast.makeText(this, "No accelerometer on this device", Toast.LENGTH_SHORT).show() } } override fun onResume() { super.onResume() accelerometer?.let { sensorManager.registerListener(this, it, SensorManager.SENSOR_DELAY_UI) } gyroscope?.let { sensorManager.registerListener(this, it, SensorManager.SENSOR_DELAY_UI) } } override fun onPause() { super.onPause() sensorManager.unregisterListener(this) } override fun onSensorChanged(event: SensorEvent?) { event ?: return when (event.sensor.type) { Sensor.TYPE_ACCELEROMETER -> handleAccelerometer(event.values) Sensor.TYPE_GYROSCOPE -> handleGyroscope(event.values) } } override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {} }

Sensor delay constants

ConstantRateUse Case
SENSOR_DELAY_FASTEST~0 ms (max rate)Games, high-frequency apps
SENSOR_DELAY_GAME~20 msInteractive games
SENSOR_DELAY_UI~60 msUI animations, shake detection
SENSOR_DELAY_NORMAL~200 msScreen rotation, step counter

6Accelerometer

The accelerometer measures acceleration forces on the device across three axes (X, Y, Z) in m/s². Uses include shake detection, step counting, tilt controls, and screen orientation.

Read accelerometer values

Kotlin — Display X, Y, Z valuesprivate fun handleAccelerometer(values: FloatArray) { val x = values[0] val y = values[1] val z = values[2] binding.tvAccel.text = String.format( Locale.getDefault(), "Accel — X: %.2f Y: %.2f Z: %.2f m/s²", x, y, z ) }

Shake detection

Kotlin — Detect device shakeclass ShakeDetector(private val onShake: () -> Unit) : SensorEventListener { private var lastUpdate = 0L private var lastX = 0f private var lastY = 0f private var lastZ = 0f private val shakeThreshold = 800f override fun onSensorChanged(event: SensorEvent) { if (event.sensor.type != Sensor.TYPE_ACCELEROMETER) return val currentTime = System.currentTimeMillis() if (currentTime - lastUpdate > 100) { val diffTime = currentTime - lastUpdate lastUpdate = currentTime val x = event.values[0] val y = event.values[1] val z = event.values[2] val speed = Math.abs(x + y + z - lastX - lastY - lastZ) / diffTime * 10000 if (speed > shakeThreshold) onShake() lastX = x; lastY = y; lastZ = z } } override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {} }

Axis orientation

Phone held upright (portrait): X → right edge Y → top edge Z → out of screen (toward user) Flat on table: Z ≈ 9.8 m/s² (gravity) Free fall: all axes ≈ 0

7Gyroscope

The gyroscope measures angular rotation rate around X, Y, and Z axes in radians per second. It detects how fast the device is spinning — essential for AR, games, and camera stabilization.

Read gyroscope values

Kotlin — Display rotation ratesprivate fun handleGyroscope(values: FloatArray) { val x = values[0] // pitch rate val y = values[1] // yaw rate val z = values[2] // roll rate binding.tvGyro.text = String.format( Locale.getDefault(), "Gyro — X: %.3f Y: %.3f Z: %.3f rad/s", x, y, z ) }

Rotation threshold alert

Kotlin — Detect fast rotationprivate var lastGyroAlert = 0L private fun handleGyroscope(values: FloatArray) { val magnitude = sqrt(values[0] * values[0] + values[1] * values[1] + values[2] * values[2]) binding.tvGyro.text = "Rotation rate: ${"%.3f".format(magnitude)} rad/s" if (magnitude > 2.0f && System.currentTimeMillis() - lastGyroAlert > 2000) { lastGyroAlert = System.currentTimeMillis() Toast.makeText(this, "Fast rotation detected!", Toast.LENGTH_SHORT).show() } }

Accelerometer vs Gyroscope

SensorMeasuresUnitExample Use
AccelerometerLinear acceleration + gravitym/s²Shake, tilt, steps
GyroscopeAngular rotation speedrad/sAR, spin detection, games
Rotation VectorDevice orientation (fused)quaternionCompass, 3D UI

Best practice: Always unregister sensor listeners in onPause(). Use the lowest sensor delay that meets your needs. Combine accelerometer + gyroscope with a sensor fusion algorithm (or Sensor.TYPE_ROTATION_VECTOR) for smooth orientation tracking.

8Hands-On Exercises

1

Request location permission and display the device's last known GPS coordinates in a TextView using LocationManager.

2

Refactor to the Fused Location Provider with continuous updates. Show latitude, longitude, and accuracy updating every 5 seconds.

3

Build a CameraX preview screen with a live camera feed using PreviewView.

4

Add a capture button that saves a photo to app-specific external storage and shows a thumbnail.

5

Implement profile photo pick using the system TakePicture contract with FileProvider.

6

Register SensorManager listeners and display live accelerometer X/Y/Z values on screen.

7

Implement shake detection with the accelerometer — show a Toast when the user shakes the device.

8

Bonus: Display gyroscope rotation rates and alert when rotation exceeds a threshold.

Location, Camera & Sensors MCQ Practice

10 Basic MCQs 10 Advanced MCQs

10 Basic Location, Camera & Sensors MCQs

1

Fused Location Provider from?

ASQLite
BGoogle Play services Location API
CRoom only
DGradle
Explanation: FusedLocationProviderClient combines GPS, WiFi, cell for best fix.
2

GPS permission is?

AINTERNET only
BCAMERA only
CACCESS_FINE_LOCATION
DVIBRATE
Explanation: COARSE for approximate; FINE for precise GPS.
3

CameraX is?

ABluetooth stack
BSQL ORM
CNotification API
DJetpack camera library abstracting device cameras
Explanation: CameraX simplifies preview, capture, and lifecycle binding.
4

SensorManager provides access to?

ADevice sensors (accelerometer, gyroscope)
BSQLite only
CPlay Store
DGradle daemon
Explanation: Register SensorEventListener for sensor updates.
5

Accelerometer measures?

AOnly temperature
BLinear acceleration including gravity
CBattery level
DNetwork speed
Explanation: Used for shake detection, orientation helpers.
6

Gyroscope measures?

ASound level
BGPS latitude
CRotational rate around axes
DLight color only
Explanation: Angular velocity for rotation-aware features.
7

takePicture in CameraX uses?

ABroadcastReceiver
BMediaPlayer
CRoom DAO
DImageCapture use case
Explanation: ImageCapture.takePicture saves photo to file or MediaStore.
8

Location updates need?

ARuntime location permission + fused client request
BManifest only
CRoot
DEmulator only
Explanation: Also consider background location separate permission.
9

PreviewView in CameraX?

AShows notifications
BDisplays camera preview stream
CSQL table view
DMap widget
Explanation: Preview use case bound to lifecycle and PreviewView.
10

Sensor.TYPE_ACCELEROMETER constant identifies?

ACamera lens
BGPS provider
CAccelerometer hardware sensor
DWiFi radio
Explanation: Use getDefaultSensor(Sensor.TYPE_ACCELEROMETER).

10 Advanced Location, Camera & Sensors MCQs

11

ProcessCameraProvider.bindToLifecycle?

AStarts foreground service always
BBinds use cases to LifecycleOwner
CSQL migration
DGradle sync
Explanation: Auto unbinds when lifecycle destroyed — avoids camera leak.
12

Last location fast fetch?

ARequires root
BAlways blocks 30 sec
CgetLastLocation may return cached quick fix
DIllegal on API 34
Explanation: Useful for approximate start before continuous updates.
13

LocationRequest PRIORITY_HIGH_ACCURACY?

ANetwork banned
BNo GPS used
CBattery save only
DGPS preferred for best accuracy
Explanation: BALANCED_POWER_ACCURACY trades accuracy for battery.
14

Camera permission CAMERA is?

ADangerous runtime permission
BNormal automatic
CSignature only
DNot required
Explanation: Request before opening camera; handle denial gracefully.
15

Sensor delay SENSOR_DELAY_GAME?

AOnce per hour
BFastest reasonable rate for games
CMain thread only
DGPS interval
Explanation: UI, NORMAL, GAME, FASTEST rates for different use cases.
16

Geofencing uses?

ARoom database
BAccelerometer only
CLocation APIs + GeofencingClient
DToast
Explanation: Trigger events when entering/leaving geographic regions.
17

ImageAnalysis use case?

AGradle
BOnly storage
COnly audio
DFrame-by-frame analysis (ML, barcode)
Explanation: Analyzer receives ImageProxy for each frame.
18

Rotation vector sensor fuses?

AAccelerometer + magnetometer + gyro
BGPS only
CCamera only
DWiFi only
Explanation: Provides device orientation in space.
19

Background location on Android 10+?

ASame permission
BSeparate ACCESS_BACKGROUND_LOCATION after foreground
CAutomatic
DBanned entirely
Explanation: Strict Play Store review for background location justification.
20

Exif orientation on captured image?

ACameraX never sets
BAlways upright
CMay need rotation when displaying saved JPEG
DIllegal
Explanation: Read ExifInterface orientation and rotate bitmap if needed.
Click an option to select, then check answers.

Location, Camera & Sensors Interview Q&A

15 topic-focused questions for interviews and revision.

1Get current location with Fused Location Provider.medium
Answer: Check permission, fusedClient.getLastLocation or requestLocationUpdates with LocationCallback.
2CameraX basic setup.medium
Answer: ProcessCameraProvider.getInstance, bind Preview + ImageCapture to lifecycle, set PreviewView.
3Request location permission flow.easy
Answer: Declare in manifest, check ContextCompat.checkSelfPermission, request via ActivityResultContracts.
4Accelerometer shake detection idea.medium
Answer: Listen SENSOR_DELAY_UI, compute acceleration magnitude change threshold over time.
5Difference GPS vs Network location.easy
Answer: GPS satellite precise outdoors; network uses WiFi/cell faster indoors less precise.
6Why bind camera to lifecycle.medium
Answer: Automatically releases camera when Activity/Fragment destroyed — prevents lock and battery drain.
7Save photo to gallery.medium
Answer: ImageCapture OutputFileOptions with MediaStore content URI on Android 10+ scoped storage.
8Sensor registration and unregister.easy
Answer: sensorManager.registerListener in onResume, unregisterListener in onPause to save battery.
9Gyroscope use cases.medium
Answer: VR-like rotation, image stabilization hints, game controls.
10Location updates battery tips.hard
Answer: Use smallest interval needed, remove updates in onPause, use geofencing over constant polling.
11Handle permission denial for camera.easy
Answer: Show explanation, disable capture button, link to settings if permanent.
12CameraX vs old Camera API.medium
Answer: CameraX lifecycle-aware, device-agnostic, easier; Camera2 low-level control.
13Test sensors on emulator.easy
Answer: Extended controls send simulated location and sensor data.
14Foreground service for navigation.hard
Answer: Ongoing location in background often requires foreground service with location type.
15Privacy best practices for location.medium
Answer: Collect minimum needed, disclose in privacy policy, stop updates when not needed.