Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@nikartm
Last active March 9, 2024 11:29
Show Gist options
  • Star 15 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save nikartm/79932c0a4f0a644f7ce020143146db98 to your computer and use it in GitHub Desktop.
Save nikartm/79932c0a4f0a644f7ce020143146db98 to your computer and use it in GitHub Desktop.
Android. Example how to save an image file in the App cache and get Uri for it. The Image will not be saved in a device gallery, only in an internal App cache.
package com.github.example;
import android.content.Context;
import android.graphics.Bitmap;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;
import androidx.annotation.Nullable;
import androidx.core.content.FileProvider;
import com.github.example.App;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* Save a file in the App cache and get Uri for it
*
* @author Ivan V on 12.05.2019.
* @version 1.0
*/
public class Cache {
public static final String TAG = Cache.class.getSimpleName();
private static final String CHILD_DIR = "images";
private static final String TEMP_FILE_NAME = "img";
private static final String FILE_EXTENSION = ".png";
private static final int COMPRESS_QUALITY = 100;
/**
* Save image to the App cache
* @param bitmap to save to the cache
* @param name file name in the cache.
* If name is null file will be named by default {@link #TEMP_FILE_NAME}
* @return file dir when file was saved
*/
public File saveImgToCache(Bitmap bitmap, @Nullable String name) {
File cachePath = null;
String fileName = TEMP_FILE_NAME;
if (!TextUtils.isEmpty(name)) {
fileName = name;
}
try {
cachePath = new File(App.getAppContext().getCacheDir(), CHILD_DIR);
cachePath.mkdirs();
FileOutputStream stream = new FileOutputStream(cachePath + "/" + fileName + FILE_EXTENSION);
bitmap.compress(Bitmap.CompressFormat.PNG, COMPRESS_QUALITY, stream);
stream.close();
} catch (IOException e) {
Log.e(TAG, "saveImgToCache error: " + bitmap, e);
}
return cachePath;
}
/**
* Save an image to the App cache dir and return it {@link Uri}
* @param bitmap to save to the cache
*/
public Uri saveToCacheAndGetUri(Bitmap bitmap) {
return saveToCacheAndGetUri(bitmap, null);
}
/**
* Save an image to the App cache dir and return it {@link Uri}
* @param bitmap to save to the cache
* @param name file name in the cache.
* If name is null file will be named by default {@link #TEMP_FILE_NAME}
*/
public Uri saveToCacheAndGetUri(Bitmap bitmap, @Nullable String name) {
File file = saveImgToCache(bitmap, name);
return getImageUri(file, name);
}
/**
* Get a file {@link Uri}
* @param name of the file
* @return file Uri in the App cache or null if file wasn't found
*/
@Nullable public Uri getUriByFileName(String name) {
Context context = App.getAppContext();
String fileName;
if (!TextUtils.isEmpty(name)) {
fileName = name;
} else {
return null;
}
File imagePath = new File(context.getCacheDir(), CHILD_DIR);
File newFile = new File(imagePath, fileName + FILE_EXTENSION);
return FileProvider.getUriForFile(context, context.getPackageName() + ".provider", newFile);
}
// Get an image Uri by name without extension from a file dir
private Uri getImageUri(File fileDir, @Nullable String name) {
Context context = App.getAppContext();
String fileName = TEMP_FILE_NAME;
if (!TextUtils.isEmpty(name)) {
fileName = name;
}
File newFile = new File(fileDir, fileName + FILE_EXTENSION);
return FileProvider.getUriForFile(context, context.getPackageName() + ".provider", newFile);
}
/**
* Get Uri type by {@link Uri}
*/
public String getContentType(Uri uri) {
return App.getAppContext().getContentResolver().getType(uri);
}
}
@nikartm
Copy link
Author

nikartm commented May 12, 2019

Add the provider to manifest:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.github.example">

        .....

        <!-- Provider to cache images to the internal App cache -->
        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="${applicationId}.provider"
            android:grantUriPermissions="true"
            android:exported="false"
            tools:replace="android:authorities">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />
        </provider>

    </application>
</manifest>

Create file_paths.xml in /res/xml/ with content:

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <cache-path name="shared_images" path="images/"/>
</paths>

Example of using:

Cache cache = new Cache();
Uri uri = cache.saveToCacheAndGetUri(bitmap);

@fusion4github
Copy link

fusion4github commented Oct 15, 2020

How to access Context from App?, it shows that context is private when I access it in cache.java
---SOLVED, I created a constructor and accessed context from there!

@rishabh-smartlinks
Copy link

this is great stuff...!!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment