In this video it shows the steps to create your own Car DashCam Android App. DashCam, also called as Dashboard Camera, can be used to record video and audio from the camera of your mobile phone while driving the car.
Excerpt about DashCam App:
Building a car dashcam app for Android involves leveraging your phone’s camera and microphone to continuously record video and audio while driving. The core functionalities include loop recording to manage storage, background recording for seamless use with other apps, and GPS and G-sensor integration to capture location data and potential accident events. With a user-friendly interface and features like cloud backup and video customization, one can create a valuable tool for drivers seeking to document their journeys and enhance their on-road safety.
I hope you like this video. For any questions, suggestions or appreciation please contact us at: https://programmerworld.co/contact/ or email at: contact@programmerworld.co / programmerworld1990@gmail.com
Complete source code and other details/ steps of this video are posted in the below link:
package com.programmerworld.cardashcamapp;
import static android.Manifest.permission.CAMERA;
import static android.Manifest.permission.READ_MEDIA_AUDIO;
import static android.Manifest.permission.READ_MEDIA_IMAGES;
import static android.Manifest.permission.READ_MEDIA_VIDEO;
import static android.Manifest.permission.READ_MEDIA_VISUAL_USER_SELECTED;
import static android.Manifest.permission.RECORD_AUDIO;
import android.content.pm.PackageManager;
import android.graphics.SurfaceTexture;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.storage.StorageManager;
import android.os.storage.StorageVolume;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import java.io.File;
import java.io.IOException;
import java.util.Objects;
public class MainActivity extends AppCompatActivity {
private TextureView textureView;
private MediaRecorder mediaRecorder;
private StorageManager storageManager;
private StorageVolume storageVolume;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EdgeToEdge.enable(this);
setContentView(R.layout.activity_main);
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
ActivityCompat.requestPermissions(this,
new String[]{READ_MEDIA_IMAGES,
READ_MEDIA_VISUAL_USER_SELECTED,
READ_MEDIA_VIDEO,
READ_MEDIA_AUDIO,
RECORD_AUDIO,
CAMERA},
PackageManager.PERMISSION_GRANTED);
textureView = findViewById(R.id.textureView);
textureView.setRotation(90);// to change to portrait form
storageManager = (StorageManager) getSystemService(STORAGE_SERVICE);
storageVolume = storageManager.getStorageVolumes().get(0); // 0 for internal storage
return insets;
});
}
private void startVideoRecording(){
File fileVideo = new File(Objects.requireNonNull(storageVolume.getDirectory()).getPath()
+ "/Download/" + System.currentTimeMillis() + ".mp4");
mediaRecorder = new MediaRecorder(this);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
mediaRecorder.setOutputFile(fileVideo.getPath());
mediaRecorder.setMaxDuration(20000); // 20 seconds for demonstration. But can be used for larger duration such as 10 mins also.
mediaRecorder.setMaxFileSize(1000000); // Again the file size can be larger. 1MB considered in this demo
mediaRecorder.setOrientationHint(90); // to change to portrait form
SurfaceTexture surfaceTexture = textureView.getSurfaceTexture();
Surface surface = new Surface(surfaceTexture);
mediaRecorder.setPreviewDisplay(surface);
try {
mediaRecorder.prepare();
} catch (IOException e) {
throw new RuntimeException(e);
}
mediaRecorder.start();
mediaRecorder.setOnInfoListener(new MediaRecorder.OnInfoListener() {
@Override
public void onInfo(MediaRecorder mr, int what, int extra) {
if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED){
mediaRecorder.stop();
mediaRecorder.release();
startVideoRecording();
}
}
});
}
public void buttonStartRecording(View view){
startVideoRecording();
}
public void buttonStopRecording(View view){
mediaRecorder.stop();
mediaRecorder.release();
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-feature
android:name="android.hardware.camera"
android:required="false" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>
<uses-permission android:name="android.permission.READ_MEDIA_VISUAL_USER_SELECTED"/>
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.CAMERA"/>
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.CarDashCamApp"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
No change in the following gradle file was done:
plugins {
alias(libs.plugins.androidApplication)
}
android {
namespace = "com.programmerworld.cardashcamapp"
compileSdk = 34
defaultConfig {
applicationId = "com.programmerworld.cardashcamapp"
minSdk = 33
targetSdk = 34
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
}
dependencies {
implementation(libs.appcompat)
implementation(libs.material)
implementation(libs.activity)
implementation(libs.constraintlayout)
testImplementation(libs.junit)
androidTestImplementation(libs.ext.junit)
androidTestImplementation(libs.espresso.core)
}
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="39dp"
android:layout_marginTop="56dp"
android:onClick="buttonStartRecording"
android:text="Start Recording"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="11dp"
android:layout_marginTop="53dp"
android:onClick="buttonStopRecording"
android:text="Stop Recording"
app:layout_constraintStart_toEndOf="@+id/button"
app:layout_constraintTop_toTopOf="parent" />
<TextureView
android:id="@+id/textureView"
android:layout_width="620dp"
android:layout_height="369dp"
android:layout_marginTop="195dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button" />
</androidx.constraintlayout.widget.ConstraintLayout>
Screenshots:
Initial Layout of Android App:
Video Recording in Android App in progress
Recorded Videos in Download folder:
Playing one of the recorded Videos:
Project Access:
Complete project files shown in this demo can be accessed through the following link by paying USD 9 only:
https://drive.google.com/file/d/1aIhvQznOGnGRxBzXyuiIP8DX5fdUWZZR/view?usp=drive_link
Please I would If you do a tuto for Integration DialogFlow on android App voice speecher