In this tutorial, i would be putting you through how you can save files like mp3, png, jpeg and other android files using the Android scoped storage api for android 10+ and below.
In this guide, we would be taking the screenshot of the current screen and saving the image in the default anndroid image folder.
we would also be using viewBinding as a way of binding the ui components to our java code.
To save Images in Android 10 above and below, you use the below method. In this method, we are saving a bitmap as an image file to the default Android image folder
private void saveImageToStorage(Bitmap bitmap) throws IOException { OutputStream imageOutStream; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { ContentValues values = new ContentValues(); values.put(MediaStore.Images.Media.DISPLAY_NAME, "image_screenshot.jpg"); values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg"); values.put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_PICTURES); Uri uri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values); imageOutStream = getContentResolver().openOutputStream(uri); } else { String imagesDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).toString(); File image = new File(imagesDir, "image_screenshotjpg"); imageOutStream = new FileOutputStream(image); } bitmap.compress(Bitmap.CompressFormat.JPEG, 100, imageOutStream); imageOutStream.close(); }
Lets start.
- Enable View Binding
Open build.gradle file and add the following to enable View binding.
buildFeatures { viewBinding true }
2. your build.gradle file should look like this
apply plugin: 'com.android.application' android { compileSdkVersion 29 buildToolsVersion "29.0.3" defaultConfig { applicationId "ringtone.mp3.song.savefileinandroid10" minSdkVersion 17 targetSdkVersion 29 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } buildFeatures { viewBinding true } } dependencies { implementation fileTree(dir: "libs", include: ["*.jar"]) implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test.ext:junit:1.1.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' }
3. Add the below Code to your MainActivity.java
import androidx.appcompat.app.AppCompatActivity; import android.content.ContentValues; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.provider.MediaStore; import android.view.View; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import ringtone.mp3.song.savefileinandroid10.databinding.ActivityMainBinding; public class MainActivity extends AppCompatActivity { ActivityMainBinding binding; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = ActivityMainBinding.inflate(getLayoutInflater()); View view = binding.getRoot(); setContentView(view); binding.btnSaveScreenshot.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { try { saveImageToStorage(); } catch (IOException e) { e.printStackTrace(); } } }); } private void saveImageToStorage() throws IOException { OutputStream imageOutStream; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { ContentValues values = new ContentValues(); values.put(MediaStore.Images.Media.DISPLAY_NAME, "image_screenshot.jpg"); values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg"); values.put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_PICTURES); Uri uri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values); imageOutStream = getContentResolver().openOutputStream(uri); } else { String imagesDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).toString(); File image = new File(imagesDir, "image_screenshotjpg"); imageOutStream = new FileOutputStream(image); } try { getViewScreenshot(binding.linearLayout).compress(Bitmap.CompressFormat.JPEG, 100, imageOutStream); } finally { imageOutStream.close(); } } private Bitmap getViewScreenshot(View view) { //Define a bitmap with the same size as the view Bitmap returnedBitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888); //Bind a canvas to it Canvas canvas = new Canvas(returnedBitmap); //Get the view's background Drawable bgDrawable = view.getBackground(); if (bgDrawable != null) { //has background drawable, then draw it on the canvas bgDrawable.draw(canvas); } else { //does not have background drawable, then draw white background on the canvas canvas.drawColor(Color.WHITE); } // draw the view on the canvas view.draw(canvas); //return the bitmap return returnedBitmap; } }
4. Then open your activity_main.xml and add the below code.
<?xml version="1.0" encoding="utf-8"?> <LinearLayout 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:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <LinearLayout android:id="@+id/linear_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:background="#000000" android:orientation="vertical"> <Button android:id="@+id/btn_save_screenshot" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Save Screenshot"/> </LinearLayout> </LinearLayout>