{"id":1503,"date":"2022-10-14T13:12:26","date_gmt":"2022-10-14T13:12:26","guid":{"rendered":"https:\/\/infotheme.net\/blog\/?p=1503"},"modified":"2022-10-14T14:16:39","modified_gmt":"2022-10-14T14:16:39","slug":"android-working-with-camera-using-java","status":"publish","type":"post","link":"https:\/\/infotheme.net\/blog\/android-working-with-camera-using-java\/","title":{"rendered":"Android working with Camera Using Java"},"content":{"rendered":"\n<p>Nowadays camera become one the major features that lot of apps provides. You can see the camera feature excessively used in apps in the area of food, social networking, video sharing apps. Integrating camera in your app is very simple task if you are not expecting a custom UI.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/infotheme.net\/blog\/wp-content\/uploads\/2022\/10\/android-working-with-camera-using-camera-api-v2.png\"><img loading=\"lazy\" width=\"1024\" height=\"536\" src=\"https:\/\/infotheme.net\/blog\/wp-content\/uploads\/2022\/10\/android-working-with-camera-using-camera-api-v2-1024x536.png\" alt=\"android working with camera using camera api v2\" class=\"wp-image-1505\" srcset=\"https:\/\/infotheme.net\/blog\/wp-content\/uploads\/2022\/10\/android-working-with-camera-using-camera-api-v2-1024x536.png 1024w, https:\/\/infotheme.net\/blog\/wp-content\/uploads\/2022\/10\/android-working-with-camera-using-camera-api-v2-300x157.png 300w, https:\/\/infotheme.net\/blog\/wp-content\/uploads\/2022\/10\/android-working-with-camera-using-camera-api-v2-768x402.png 768w, https:\/\/infotheme.net\/blog\/wp-content\/uploads\/2022\/10\/android-working-with-camera-using-camera-api-v2.png 1200w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>In this article we are going to see how to integrate the basic camera feature that takes pictures or record video through your app.<\/p>\n\n\n\n<h2>1. Android Camera API<\/h2>\n\n\n\n<p>There are two ways to integrate the camera module.<\/p>\n\n\n\n<ul><li><strong>Using In-built Camera App:<\/strong><\/li><li><strong>Writing Custom Camera App:<\/strong><\/li><\/ul>\n\n\n\n<p>Below is the demo app that we gonna build in this article. The UI is very minimal with two buttons and an area to preview the captured image or video.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/infotheme.net\/blog\/wp-content\/uploads\/2022\/10\/Android-Camera-Api-Using-Java.webp\"><img loading=\"lazy\" width=\"640\" height=\"381\" src=\"https:\/\/infotheme.net\/blog\/wp-content\/uploads\/2022\/10\/Android-Camera-Api-Using-Java.webp\" alt=\"\" class=\"wp-image-1504\" srcset=\"https:\/\/infotheme.net\/blog\/wp-content\/uploads\/2022\/10\/Android-Camera-Api-Using-Java.webp 640w, https:\/\/infotheme.net\/blog\/wp-content\/uploads\/2022\/10\/Android-Camera-Api-Using-Java-300x179.webp 300w\" sizes=\"(max-width: 640px) 100vw, 640px\" \/><\/a><\/figure>\n\n\n\n<p>Now let\u2019s start by creating a new project in Android Studio.<\/p>\n\n\n\n<h2>2. Creating New Project<\/h2>\n\n\n\n<p><strong>1<\/strong>. Create a new project in Android Studio from&nbsp;<strong>File \u21d2 New Project<\/strong>&nbsp;and select&nbsp;<strong>Basic Activity<\/strong>&nbsp;from templates.<\/p>\n\n\n\n<p><strong>2<\/strong>. Open&nbsp;<strong>app\/build.gradle<\/strong>&nbsp;and add&nbsp;Dexter&nbsp;dependency to request the runtime permissions.<\/p>\n\n\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\napp\/build.gradle\ndependencies {\n    implementation fileTree(dir: &#039;libs&#039;, include: [&#039;*.jar&#039;])\n    \/\/ ...\n \n    \/\/ dexter runtime permissions\n    implementation &#039;com.karumi:dexter:4.2.0&#039;\n}\n<\/pre>\n\n\n<p><strong>3<\/strong>. Add the below resources to respective&nbsp;<strong>strings.xml<\/strong>,&nbsp;<strong>colors.xml<\/strong>&nbsp;and&nbsp;<strong>dimens.xml<\/strong><\/p>\n\n\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nstrings.xml\n&lt;resources&gt;\n    &lt;string name=&quot;app_name&quot;&gt;Android Camera&lt;\/string&gt;\n    &lt;string name=&quot;action_settings&quot;&gt;Settings&lt;\/string&gt;\n    &lt;string name=&quot;preview_description&quot;&gt;Image and Video preview will appear here&lt;\/string&gt;\n    &lt;string name=&quot;btn_take_picture&quot;&gt;Take Picture&lt;\/string&gt;\n    &lt;string name=&quot;btn_record_video&quot;&gt;Record Video&lt;\/string&gt;\n&lt;\/resources&gt;\n<\/pre>\n\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\ncolors.xml\n&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;\n&lt;resources&gt;\n    &lt;color name=&quot;colorPrimary&quot;&gt;#1fb49c&lt;\/color&gt;\n    &lt;color name=&quot;colorPrimaryDark&quot;&gt;#1fb49c&lt;\/color&gt;\n    &lt;color name=&quot;colorAccent&quot;&gt;#FF4081&lt;\/color&gt;\n&lt;\/resources&gt;\n<\/pre>\n\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\ndimens.xml\n&lt;resources&gt;\n    &lt;dimen name=&quot;activity_margin&quot;&gt;16dp&lt;\/dimen&gt;\n    &lt;dimen name=&quot;dimen_8&quot;&gt;8dp&lt;\/dimen&gt;\n&lt;\/resources&gt;\n<\/pre>\n\n\n<p><strong>4<\/strong>. Under&nbsp;<strong>res<\/strong>, create a new folder named&nbsp;<strong>xml<\/strong>. Inside xml folder, create a new xml file name&nbsp;<strong>file_paths.xml<\/strong><\/p>\n\n\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nfile_paths.xml\n&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;\n&lt;paths xmlns:android=&quot;http:\/\/schemas.android.com\/apk\/res\/android&quot;&gt;\n    &lt;external-path name=&quot;external_files&quot; path=&quot;.&quot;\/&gt;\n&lt;\/paths&gt;\n<\/pre>\n\n\n<p><strong>5<\/strong>. Open&nbsp;<strong>AndroidManifest.xml<\/strong>&nbsp;and add&nbsp;<em>CAMERA<\/em>,&nbsp;<em>WRITE_EXTERNAL_STORAGE<\/em>&nbsp;and&nbsp;<em>RECORD_AUDIO<\/em>&nbsp;permissions.<\/p>\n\n\n\n<p>Here we also added camera feature that defines the rules to list the app on Playstore. If we keep&nbsp;<strong>android:required=\u201dtrue\u201d<\/strong>, Google Playstore won\u2019t let the users to install the app on the devices that doesn\u2019t have camera feature. Incase of&nbsp;<strong>false<\/strong>, the app will be listed but camera feature is optional.<\/p>\n\n\n\n<p>We also need&nbsp;<strong>&lt;provider&gt;<\/strong>&nbsp;tag to prepare the file paths properly across all the android platforms.<\/p>\n\n\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n&lt;uses-feature\n        android:name=&quot;android.hardware.camera&quot;\n        android:required=&quot;false&quot; \/&gt;\n<\/pre>\n\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nAndroidManifest.xml\n&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;\n&lt;manifest xmlns:android=&quot;http:\/\/schemas.android.com\/apk\/res\/android&quot;\n    package=&quot;net.infotheme.androidcamera&quot;&gt;\n \n    &lt;uses-permission android:name=&quot;android.permission.CAMERA&quot; \/&gt;\n    &lt;uses-permission android:name=&quot;android.permission.WRITE_EXTERNAL_STORAGE&quot; \/&gt;\n    &lt;uses-permission android:name=&quot;android.permission.RECORD_AUDIO&quot; \/&gt;\n \n    &lt;uses-feature\n        android:name=&quot;android.hardware.camera&quot;\n        android:required=&quot;false&quot; \/&gt;\n \n    &lt;application\n        android:allowBackup=&quot;true&quot;\n        android:icon=&quot;@mipmap\/ic_launcher&quot;\n        android:label=&quot;@string\/app_name&quot;\n        android:roundIcon=&quot;@mipmap\/ic_launcher_round&quot;\n        android:supportsRtl=&quot;true&quot;\n        android:theme=&quot;@style\/AppTheme&quot;&gt;\n        &lt;activity\n            android:name=&quot;.MainActivity&quot;\n            android:label=&quot;@string\/app_name&quot;\n            android:theme=&quot;@style\/AppTheme.NoActionBar&quot;&gt;\n            &lt;intent-filter&gt;\n                &lt;action android:name=&quot;android.intent.action.MAIN&quot; \/&gt;\n \n                &lt;category android:name=&quot;android.intent.category.LAUNCHER&quot; \/&gt;\n            &lt;\/intent-filter&gt;\n        &lt;\/activity&gt;\n \n        &lt;provider\n            android:name=&quot;android.support.v4.content.FileProvider&quot;\n            android:authorities=&quot;${applicationId}.provider&quot;\n            android:exported=&quot;false&quot;\n            android:grantUriPermissions=&quot;true&quot;&gt;\n            &lt;meta-data\n                android:name=&quot;android.support.FILE_PROVIDER_PATHS&quot;\n                android:resource=&quot;@xml\/file_paths&quot; \/&gt;\n        &lt;\/provider&gt;\n    &lt;\/application&gt;\n&lt;\/manifest&gt;\n<\/pre>\n\n\n<p><strong>6<\/strong>. Create a class named&nbsp;<strong>CameraUtils.java<\/strong>&nbsp;and add the below methods. This is a helper class that provides necessary methods that we need in our camera module.<\/p>\n\n\n\n<ul><li><strong>refreshGallery()<\/strong>&nbsp;\u2013 Refreshes the image gallery after taking a new picture or video so that they will be instantly available in the gallery. In older android devices, gallery won\u2019t be refreshed until the device is rebooted.<\/li><li><strong>checkPermissions()<\/strong>&nbsp;\u2013 Checks whether all the permissions are granted or not. This would be called before requesting the camera.<\/li><li><strong>getOutputMediaFile()<\/strong>&nbsp;\u2013 Create a new file in gallery and returns the file. This reference will be passed to camera intent so that newly taken image \/ video will be stored in this location.<\/li><li><strong>optimizeBitmap()<\/strong>&nbsp;\u2013 Compresses the bitmap before displaying it on UI to avoid the OutOfMemory exceptions.<\/li><\/ul>\n\n\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nCameraUtils.java\npackage net.infotheme.androidcamera;\n \nimport android.Manifest;\nimport android.content.Context;\nimport android.content.Intent;\nimport android.content.pm.PackageManager;\nimport android.graphics.Bitmap;\nimport android.graphics.BitmapFactory;\nimport android.media.MediaScannerConnection;\nimport android.net.Uri;\nimport android.os.Environment;\nimport android.provider.Settings;\nimport android.support.v4.app.ActivityCompat;\nimport android.support.v4.content.FileProvider;\nimport android.util.Log;\n \nimport java.io.File;\nimport java.text.SimpleDateFormat;\nimport java.util.Date;\nimport java.util.Locale;\n \npublic class CameraUtils {\n \n    \/**\n     * Refreshes gallery on adding new image\/video. Gallery won&#039;t be refreshed\n     * on older devices until device is rebooted\n     *\/\n    public static void refreshGallery(Context context, String filePath) {\n        \/\/ ScanFile so it will be appeared on Gallery\n        MediaScannerConnection.scanFile(context,\n                new String[]{filePath}, null,\n                new MediaScannerConnection.OnScanCompletedListener() {\n                    public void onScanCompleted(String path, Uri uri) {\n                    }\n                });\n    }\n \n    public static boolean checkPermissions(Context context) {\n        return ActivityCompat.checkSelfPermission(context, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED\n                &amp;amp;&amp;amp; ActivityCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED\n                &amp;amp;&amp;amp; ActivityCompat.checkSelfPermission(context, Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED;\n    }\n \n    \/**\n     * Downsizing the bitmap to avoid OutOfMemory exceptions\n     *\/\n    public static Bitmap optimizeBitmap(int sampleSize, String filePath) {\n        \/\/ bitmap factory\n        BitmapFactory.Options options = new BitmapFactory.Options();\n \n        \/\/ downsizing image as it throws OutOfMemory Exception for larger\n        \/\/ images\n        options.inSampleSize = sampleSize;\n \n        return BitmapFactory.decodeFile(filePath, options);\n    }\n \n    \/**\n     * Checks whether device has camera or not. This method not necessary if\n     * android:required=&quot;true&quot; is used in manifest file\n     *\/\n    public static boolean isDeviceSupportCamera(Context context) {\n        if (context.getPackageManager().hasSystemFeature(\n                PackageManager.FEATURE_CAMERA)) {\n            \/\/ this device has a camera\n            return true;\n        } else {\n            \/\/ no camera on this device\n            return false;\n        }\n    }\n \n    \/**\n     * Open device app settings to allow user to enable permissions\n     *\/\n    public static void openSettings(Context context) {\n        Intent intent = new Intent();\n        intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);\n        intent.setData(Uri.fromParts(&quot;package&quot;, BuildConfig.APPLICATION_ID, null));\n        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);\n        context.startActivity(intent);\n    }\n \n    public static Uri getOutputMediaFileUri(Context context, File file) {\n        return FileProvider.getUriForFile(context, context.getPackageName() + &quot;.provider&quot;, file);\n    }\n \n    \/**\n     * Creates and returns the image or video file before opening the camera\n     *\/\n    public static File getOutputMediaFile(int type) {\n \n        \/\/ External sdcard location\n        File mediaStorageDir = new File(\n                Environment\n                        .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),\n                MainActivity.GALLERY_DIRECTORY_NAME);\n \n        \/\/ Create the storage directory if it does not exist\n        if (!mediaStorageDir.exists()) {\n            if (!mediaStorageDir.mkdirs()) {\n                Log.e(MainActivity.GALLERY_DIRECTORY_NAME, &quot;Oops! Failed create &quot;\n                        + MainActivity.GALLERY_DIRECTORY_NAME + &quot; directory&quot;);\n                return null;\n            }\n        }\n \n        \/\/ Preparing media file naming convention\n        \/\/ adds timestamp\n        String timeStamp = new SimpleDateFormat(&quot;yyyyMMdd_HHmmss&quot;,\n                Locale.getDefault()).format(new Date());\n        File mediaFile;\n        if (type == MainActivity.MEDIA_TYPE_IMAGE) {\n            mediaFile = new File(mediaStorageDir.getPath() + File.separator\n                    + &quot;IMG_&quot; + timeStamp + &quot;.&quot; + MainActivity.IMAGE_EXTENSION);\n        } else if (type == MainActivity.MEDIA_TYPE_VIDEO) {\n            mediaFile = new File(mediaStorageDir.getPath() + File.separator\n                    + &quot;VID_&quot; + timeStamp + &quot;.&quot; + MainActivity.VIDEO_EXTENSION);\n        } else {\n            return null;\n        }\n \n        return mediaFile;\n    }\n \n}\n<\/pre>\n\n\n<p><strong>7<\/strong>. Now open the layout files of main activity i.e&nbsp;<strong>activity_main.xml<\/strong>&nbsp;and&nbsp;<strong>content_main.xml<\/strong>&nbsp;and add the below layout code. Here we are defining couple of&nbsp;<strong>Buttons<\/strong>,&nbsp;<strong>ImageView<\/strong>&nbsp;and&nbsp;<strong>VideoView<\/strong>&nbsp;to preview the captured media.<\/p>\n\n\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nactivity_main.xml\n&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;\n&lt;android.support.design.widget.CoordinatorLayout xmlns:android=&quot;http:\/\/schemas.android.com\/apk\/res\/android&quot;\n    xmlns:app=&quot;http:\/\/schemas.android.com\/apk\/res-auto&quot;\n    xmlns:tools=&quot;http:\/\/schemas.android.com\/tools&quot;\n    android:layout_width=&quot;match_parent&quot;\n    android:layout_height=&quot;match_parent&quot;\n    tools:context=&quot;.MainActivity&quot;&gt;\n \n    &lt;android.support.design.widget.AppBarLayout\n        android:layout_width=&quot;match_parent&quot;\n        android:layout_height=&quot;wrap_content&quot;\n        android:theme=&quot;@style\/AppTheme.AppBarOverlay&quot;&gt;\n \n        &lt;android.support.v7.widget.Toolbar\n            android:id=&quot;@+id\/toolbar&quot;\n            android:layout_width=&quot;match_parent&quot;\n            android:layout_height=&quot;?attr\/actionBarSize&quot;\n            android:background=&quot;?attr\/colorPrimary&quot;\n            app:popupTheme=&quot;@style\/AppTheme.PopupOverlay&quot; \/&gt;\n \n    &lt;\/android.support.design.widget.AppBarLayout&gt;\n \n    &lt;include layout=&quot;@layout\/content_main&quot; \/&gt;\n \n&lt;\/android.support.design.widget.CoordinatorLayout&gt;\n<\/pre>\n\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\ncontent_main.xml\n&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;\n&lt;LinearLayout xmlns:android=&quot;http:\/\/schemas.android.com\/apk\/res\/android&quot;\n    xmlns:app=&quot;http:\/\/schemas.android.com\/apk\/res-auto&quot;\n    xmlns:tools=&quot;http:\/\/schemas.android.com\/tools&quot;\n    android:layout_width=&quot;match_parent&quot;\n    android:layout_height=&quot;match_parent&quot;\n    android:orientation=&quot;vertical&quot;\n    android:padding=&quot;@dimen\/activity_margin&quot;\n    app:layout_behavior=&quot;@string\/appbar_scrolling_view_behavior&quot;\n    tools:context=&quot;.MainActivity&quot;\n    tools:showIn=&quot;@layout\/activity_main&quot;&gt;\n \n    &lt;LinearLayout\n        android:layout_width=&quot;match_parent&quot;\n        android:layout_height=&quot;match_parent&quot;\n        android:layout_marginBottom=&quot;@dimen\/activity_margin&quot;\n        android:layout_weight=&quot;1&quot;\n        android:orientation=&quot;vertical&quot;&gt;\n \n        &lt;TextView\n            android:id=&quot;@+id\/txt_desc&quot;\n            android:layout_width=&quot;fill_parent&quot;\n            android:layout_height=&quot;match_parent&quot;\n            android:gravity=&quot;center&quot;\n            android:padding=&quot;10dp&quot;\n            android:text=&quot;@string\/preview_description&quot;\n            android:textSize=&quot;15dp&quot; \/&gt;\n \n        &lt;!-- To display picture taken --&gt;\n        &lt;ImageView\n            android:id=&quot;@+id\/imgPreview&quot;\n            android:layout_width=&quot;match_parent&quot;\n            android:layout_height=&quot;match_parent&quot;\n            android:scaleType=&quot;centerCrop&quot;\n            android:visibility=&quot;gone&quot; \/&gt;\n \n        &lt;!-- To preview video recorded --&gt;\n        &lt;VideoView\n            android:id=&quot;@+id\/videoPreview&quot;\n            android:layout_width=&quot;match_parent&quot;\n            android:layout_height=&quot;match_parent&quot;\n            android:layout_gravity=&quot;center_horizontal&quot;\n            android:visibility=&quot;gone&quot; \/&gt;\n    &lt;\/LinearLayout&gt;\n \n    &lt;LinearLayout\n        android:layout_width=&quot;match_parent&quot;\n        android:layout_height=&quot;wrap_content&quot;\n        android:orientation=&quot;horizontal&quot;\n        android:weightSum=&quot;2&quot;&gt;\n \n        &lt;!-- Capture picture button --&gt;\n        &lt;Button\n            android:id=&quot;@+id\/btnCapturePicture&quot;\n            android:layout_width=&quot;0dp&quot;\n            android:layout_height=&quot;wrap_content&quot;\n            android:layout_marginRight=&quot;@dimen\/dimen_8&quot;\n            android:layout_weight=&quot;1&quot;\n            android:background=&quot;@color\/colorPrimary&quot;\n            android:foreground=&quot;?attr\/selectableItemBackground&quot;\n            android:text=&quot;@string\/btn_take_picture&quot;\n            android:textColor=&quot;@android:color\/white&quot; \/&gt;\n \n        &lt;!-- Record video button --&gt;\n        &lt;Button\n            android:id=&quot;@+id\/btnRecordVideo&quot;\n            android:layout_width=&quot;0dp&quot;\n            android:layout_height=&quot;wrap_content&quot;\n            android:layout_marginLeft=&quot;@dimen\/dimen_8&quot;\n            android:layout_weight=&quot;1&quot;\n            android:background=&quot;@color\/colorPrimary&quot;\n            android:foreground=&quot;?attr\/selectableItemBackground&quot;\n            android:text=&quot;@string\/btn_record_video&quot;\n            android:textColor=&quot;@android:color\/white&quot; \/&gt;\n    &lt;\/LinearLayout&gt;\n&lt;\/LinearLayout&gt;\n<\/pre>\n\n\n<p><strong>8<\/strong>. Finally open&nbsp;<strong>MainActivity.java<\/strong>&nbsp;and modify the code as shown below.<\/p>\n\n\n\n<ul><li>In&nbsp;<strong>onCreate()<\/strong>, the availability of the camera is checked using&nbsp;<strong>isDeviceSupportCamera()<\/strong>&nbsp;method and activity is closed if the camera is absent on the device.<\/li><li>On button click,&nbsp;<strong>checkPermissions()<\/strong>&nbsp;method is used the check whether required permissions are granted or not. If not granted,&nbsp;<strong>requestCameraPermission()<\/strong>&nbsp;method shows the permissions dialog to user.<\/li><li><strong>captureImage()<\/strong>&nbsp;open the camera app to capture the image.<\/li><li><strong>captureVideo()<\/strong>&nbsp;opens the camera app to record the video.<\/li><li>Once the media is captured, the image or video will be saved to gallery.&nbsp;<strong>previewCapturedImage()<\/strong>&nbsp;and&nbsp;<strong>previewVideo()<\/strong>&nbsp;renders the captured image \/ video on the screen.<\/li><li><strong>showPermissionsAlert()<\/strong>&nbsp;\u2013 Shows an alert dialog propting user to enable the permissions in app settings incase they are denied permanently.<\/li><\/ul>\n\n\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nMainActivity.java\npackage net.infotheme.androidcamera;\n \nimport android.Manifest;\nimport android.content.DialogInterface;\nimport android.content.Intent;\nimport android.graphics.Bitmap;\nimport android.net.Uri;\nimport android.os.Bundle;\nimport android.provider.MediaStore;\nimport android.support.v7.app.AlertDialog;\nimport android.support.v7.app.AppCompatActivity;\nimport android.support.v7.widget.Toolbar;\nimport android.text.TextUtils;\nimport android.view.View;\nimport android.widget.Button;\nimport android.widget.ImageView;\nimport android.widget.TextView;\nimport android.widget.Toast;\nimport android.widget.VideoView;\n \nimport com.karumi.dexter.Dexter;\nimport com.karumi.dexter.MultiplePermissionsReport;\nimport com.karumi.dexter.PermissionToken;\nimport com.karumi.dexter.listener.PermissionRequest;\nimport com.karumi.dexter.listener.multi.MultiplePermissionsListener;\n \nimport java.io.File;\nimport java.util.List;\n \npublic class MainActivity extends AppCompatActivity {\n \n    \/\/ Activity request codes\n    private static final int CAMERA_CAPTURE_IMAGE_REQUEST_CODE = 100;\n    private static final int CAMERA_CAPTURE_VIDEO_REQUEST_CODE = 200;\n \n    \/\/ key to store image path in savedInstance state\n    public static final String KEY_IMAGE_STORAGE_PATH = &quot;image_path&quot;;\n \n    public static final int MEDIA_TYPE_IMAGE = 1;\n    public static final int MEDIA_TYPE_VIDEO = 2;\n \n    \/\/ Bitmap sampling size\n    public static final int BITMAP_SAMPLE_SIZE = 8;\n \n    \/\/ Gallery directory name to store the images or videos\n    public static final String GALLERY_DIRECTORY_NAME = &quot;Hello Camera&quot;;\n \n    \/\/ Image and Video file extensions\n    public static final String IMAGE_EXTENSION = &quot;jpg&quot;;\n    public static final String VIDEO_EXTENSION = &quot;mp4&quot;;\n \n    private static String imageStoragePath;\n \n    private TextView txtDescription;\n    private ImageView imgPreview;\n    private VideoView videoPreview;\n    private Button btnCapturePicture, btnRecordVideo;\n \n \n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_main);\n        Toolbar toolbar = findViewById(R.id.toolbar);\n        setSupportActionBar(toolbar);\n \n        \/\/ Checking availability of the camera\n        if (!CameraUtils.isDeviceSupportCamera(getApplicationContext())) {\n            Toast.makeText(getApplicationContext(),\n                    &quot;Sorry! Your device doesn&#039;t support camera&quot;,\n                    Toast.LENGTH_LONG).show();\n            \/\/ will close the app if the device doesn&#039;t have camera\n            finish();\n        }\n \n        txtDescription = findViewById(R.id.txt_desc);\n        imgPreview = findViewById(R.id.imgPreview);\n        videoPreview = findViewById(R.id.videoPreview);\n        btnCapturePicture = findViewById(R.id.btnCapturePicture);\n        btnRecordVideo = findViewById(R.id.btnRecordVideo);\n \n        \/**\n         * Capture image on button click\n         *\/\n        btnCapturePicture.setOnClickListener(new View.OnClickListener() {\n \n            @Override\n            public void onClick(View v) {\n                if (CameraUtils.checkPermissions(getApplicationContext())) {\n                    captureImage();\n                } else {\n                    requestCameraPermission(MEDIA_TYPE_IMAGE);\n                }\n            }\n        });\n \n        \/**\n         * Record video on button click\n         *\/\n        btnRecordVideo.setOnClickListener(new View.OnClickListener() {\n \n            @Override\n            public void onClick(View v) {\n                if (CameraUtils.checkPermissions(getApplicationContext())) {\n                    captureVideo();\n                } else {\n                    requestCameraPermission(MEDIA_TYPE_VIDEO);\n                }\n            }\n        });\n \n        \/\/ restoring storage image path from saved instance state\n        \/\/ otherwise the path will be null on device rotation\n        restoreFromBundle(savedInstanceState);\n    }\n \n    \/**\n     * Restoring store image path from saved instance state\n     *\/\n    private void restoreFromBundle(Bundle savedInstanceState) {\n        if (savedInstanceState != null) {\n            if (savedInstanceState.containsKey(KEY_IMAGE_STORAGE_PATH)) {\n                imageStoragePath = savedInstanceState.getString(KEY_IMAGE_STORAGE_PATH);\n                if (!TextUtils.isEmpty(imageStoragePath)) {\n                    if (imageStoragePath.substring(imageStoragePath.lastIndexOf(&quot;.&quot;)).equals(&quot;.&quot; + IMAGE_EXTENSION)) {\n                        previewCapturedImage();\n                    } else if (imageStoragePath.substring(imageStoragePath.lastIndexOf(&quot;.&quot;)).equals(&quot;.&quot; + VIDEO_EXTENSION)) {\n                        previewVideo();\n                    }\n                }\n            }\n        }\n    }\n \n    \/**\n     * Requesting permissions using Dexter library\n     *\/\n    private void requestCameraPermission(final int type) {\n        Dexter.withActivity(this)\n                .withPermissions(Manifest.permission.CAMERA,\n                        Manifest.permission.WRITE_EXTERNAL_STORAGE,\n                        Manifest.permission.RECORD_AUDIO)\n                .withListener(new MultiplePermissionsListener() {\n                    @Override\n                    public void onPermissionsChecked(MultiplePermissionsReport report) {\n                        if (report.areAllPermissionsGranted()) {\n \n                            if (type == MEDIA_TYPE_IMAGE) {\n                                \/\/ capture picture\n                                captureImage();\n                            } else {\n                                captureVideo();\n                            }\n \n                        } else if (report.isAnyPermissionPermanentlyDenied()) {\n                            showPermissionsAlert();\n                        }\n                    }\n \n                    @Override\n                    public void onPermissionRationaleShouldBeShown(List&lt;PermissionRequest&gt; permissions, PermissionToken token) {\n                        token.continuePermissionRequest();\n                    }\n                }).check();\n    }\n \n \n    \/**\n     * Capturing Camera Image will launch camera app requested image capture\n     *\/\n    private void captureImage() {\n        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);\n \n        File file = CameraUtils.getOutputMediaFile(MEDIA_TYPE_IMAGE);\n        if (file != null) {\n            imageStoragePath = file.getAbsolutePath();\n        }\n \n        Uri fileUri = CameraUtils.getOutputMediaFileUri(getApplicationContext(), file);\n \n        intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);\n \n        \/\/ start the image capture Intent\n        startActivityForResult(intent, CAMERA_CAPTURE_IMAGE_REQUEST_CODE);\n    }\n \n    \/**\n     * Saving stored image path to saved instance state\n     *\/\n    @Override\n    protected void onSaveInstanceState(Bundle outState) {\n        super.onSaveInstanceState(outState);\n \n        \/\/ save file url in bundle as it will be null on screen orientation\n        \/\/ changes\n        outState.putString(KEY_IMAGE_STORAGE_PATH, imageStoragePath);\n    }\n \n    \/**\n     * Restoring image path from saved instance state\n     *\/\n    @Override\n    protected void onRestoreInstanceState(Bundle savedInstanceState) {\n        super.onRestoreInstanceState(savedInstanceState);\n \n        \/\/ get the file url\n        imageStoragePath = savedInstanceState.getString(KEY_IMAGE_STORAGE_PATH);\n    }\n \n    \/**\n     * Launching camera app to record video\n     *\/\n    private void captureVideo() {\n        Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);\n \n        File file = CameraUtils.getOutputMediaFile(MEDIA_TYPE_VIDEO);\n        if (file != null) {\n            imageStoragePath = file.getAbsolutePath();\n        }\n \n        Uri fileUri = CameraUtils.getOutputMediaFileUri(getApplicationContext(), file);\n \n        \/\/ set video quality\n        intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);\n \n        intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); \/\/ set the image file\n \n        \/\/ start the video capture Intent\n        startActivityForResult(intent, CAMERA_CAPTURE_VIDEO_REQUEST_CODE);\n    }\n \n    \/**\n     * Activity result method will be called after closing the camera\n     *\/\n    @Override\n    protected void onActivityResult(int requestCode, int resultCode, Intent data) {\n        \/\/ if the result is capturing Image\n        if (requestCode == CAMERA_CAPTURE_IMAGE_REQUEST_CODE) {\n            if (resultCode == RESULT_OK) {\n                \/\/ Refreshing the gallery\n                CameraUtils.refreshGallery(getApplicationContext(), imageStoragePath);\n \n                \/\/ successfully captured the image\n                \/\/ display it in image view\n                previewCapturedImage();\n            } else if (resultCode == RESULT_CANCELED) {\n                \/\/ user cancelled Image capture\n                Toast.makeText(getApplicationContext(),\n                        &quot;User cancelled image capture&quot;, Toast.LENGTH_SHORT)\n                        .show();\n            } else {\n                \/\/ failed to capture image\n                Toast.makeText(getApplicationContext(),\n                        &quot;Sorry! Failed to capture image&quot;, Toast.LENGTH_SHORT)\n                        .show();\n            }\n        } else if (requestCode == CAMERA_CAPTURE_VIDEO_REQUEST_CODE) {\n            if (resultCode == RESULT_OK) {\n                \/\/ Refreshing the gallery\n                CameraUtils.refreshGallery(getApplicationContext(), imageStoragePath);\n \n                \/\/ video successfully recorded\n                \/\/ preview the recorded video\n                previewVideo();\n            } else if (resultCode == RESULT_CANCELED) {\n                \/\/ user cancelled recording\n                Toast.makeText(getApplicationContext(),\n                        &quot;User cancelled video recording&quot;, Toast.LENGTH_SHORT)\n                        .show();\n            } else {\n                \/\/ failed to record video\n                Toast.makeText(getApplicationContext(),\n                        &quot;Sorry! Failed to record video&quot;, Toast.LENGTH_SHORT)\n                        .show();\n            }\n        }\n    }\n \n    \/**\n     * Display image from gallery\n     *\/\n    private void previewCapturedImage() {\n        try {\n            \/\/ hide video preview\n            txtDescription.setVisibility(View.GONE);\n            videoPreview.setVisibility(View.GONE);\n \n            imgPreview.setVisibility(View.VISIBLE);\n \n            Bitmap bitmap = CameraUtils.optimizeBitmap(BITMAP_SAMPLE_SIZE, imageStoragePath);\n \n            imgPreview.setImageBitmap(bitmap);\n \n        } catch (NullPointerException e) {\n            e.printStackTrace();\n        }\n    }\n \n    \/**\n     * Displaying video in VideoView\n     *\/\n    private void previewVideo() {\n        try {\n            \/\/ hide image preview\n            txtDescription.setVisibility(View.GONE);\n            imgPreview.setVisibility(View.GONE);\n \n            videoPreview.setVisibility(View.VISIBLE);\n            videoPreview.setVideoPath(imageStoragePath);\n            \/\/ start playing\n            videoPreview.start();\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n    }\n \n    \/**\n     * Alert dialog to navigate to app settings\n     * to enable necessary permissions\n     *\/\n    private void showPermissionsAlert() {\n        AlertDialog.Builder builder = new AlertDialog.Builder(this);\n        builder.setTitle(&quot;Permissions required!&quot;)\n                .setMessage(&quot;Camera needs few permissions to work properly. Grant them in settings.&quot;)\n                .setPositiveButton(&quot;GOTO SETTINGS&quot;, new DialogInterface.OnClickListener() {\n                    public void onClick(DialogInterface dialog, int which) {\n                        CameraUtils.openSettings(MainActivity.this);\n                    }\n                })\n                .setNegativeButton(&quot;CANCEL&quot;, new DialogInterface.OnClickListener() {\n                    public void onClick(DialogInterface dialog, int which) {\n \n                    }\n                }).show();\n    }\n}\n<\/pre>\n\n\n<p>Run and test the app on a real device. You can see the app working as shown in the demo screenshots.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Nowadays camera become one the major features that lot of apps provides. You can see the camera feature excessively used in apps in the area [&hellip;] <span class=\"read-more-link\"><a class=\"read-more\" href=\"https:\/\/infotheme.net\/blog\/android-working-with-camera-using-java\/\">Read More<\/a><\/span><\/p>\n","protected":false},"author":1,"featured_media":1505,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[157,135,1],"tags":[],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/infotheme.net\/blog\/wp-json\/wp\/v2\/posts\/1503"}],"collection":[{"href":"https:\/\/infotheme.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/infotheme.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/infotheme.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/infotheme.net\/blog\/wp-json\/wp\/v2\/comments?post=1503"}],"version-history":[{"count":3,"href":"https:\/\/infotheme.net\/blog\/wp-json\/wp\/v2\/posts\/1503\/revisions"}],"predecessor-version":[{"id":1527,"href":"https:\/\/infotheme.net\/blog\/wp-json\/wp\/v2\/posts\/1503\/revisions\/1527"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/infotheme.net\/blog\/wp-json\/wp\/v2\/media\/1505"}],"wp:attachment":[{"href":"https:\/\/infotheme.net\/blog\/wp-json\/wp\/v2\/media?parent=1503"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/infotheme.net\/blog\/wp-json\/wp\/v2\/categories?post=1503"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/infotheme.net\/blog\/wp-json\/wp\/v2\/tags?post=1503"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}