How to store images in Cache Memory - android

I am totally blank on this. I want to download the images from a Url and have to store it internally so that next time I need not connect to web and instead retrieve it from cache memory. But I am not sure how to do this. Can anyone help me with a code snippet.

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.StreamCorruptedException;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Environment;
import android.util.Log;
public class CacheStore {
private static CacheStore INSTANCE = null;
private HashMap<String, String> cacheMap;
private HashMap<String, Bitmap> bitmapMap;
private static final String cacheDir = "/Android/data/com.yourbusiness/cache/";
private static final String CACHE_FILENAME = ".cache";
#SuppressWarnings("unchecked")
private CacheStore() {
cacheMap = new HashMap<String, String>();
bitmapMap = new HashMap<String, Bitmap>();
File fullCacheDir = new File(Environment.getExternalStorageDirectory().toString(),cacheDir);
if(!fullCacheDir.exists()) {
Log.i("CACHE", "Directory doesn't exist");
cleanCacheStart();
return;
}
try {
ObjectInputStream is = new ObjectInputStream(new BufferedInputStream(new FileInputStream(new File(fullCacheDir.toString(), CACHE_FILENAME))));
cacheMap = (HashMap<String,String>)is.readObject();
is.close();
} catch (StreamCorruptedException e) {
Log.i("CACHE", "Corrupted stream");
cleanCacheStart();
} catch (FileNotFoundException e) {
Log.i("CACHE", "File not found");
cleanCacheStart();
} catch (IOException e) {
Log.i("CACHE", "Input/Output error");
cleanCacheStart();
} catch (ClassNotFoundException e) {
Log.i("CACHE", "Class not found");
cleanCacheStart();
}
}
private void cleanCacheStart() {
cacheMap = new HashMap<String, String>();
File fullCacheDir = new File(Environment.getExternalStorageDirectory().toString(),cacheDir);
fullCacheDir.mkdirs();
File noMedia = new File(fullCacheDir.toString(), ".nomedia");
try {
noMedia.createNewFile();
Log.i("CACHE", "Cache created");
} catch (IOException e) {
Log.i("CACHE", "Couldn't create .nomedia file");
e.printStackTrace();
}
}
private synchronized static void createInstance() {
if(INSTANCE == null) {
INSTANCE = new CacheStore();
}
}
public static CacheStore getInstance() {
if(INSTANCE == null) createInstance();
return INSTANCE;
}
public void saveCacheFile(String cacheUri, Bitmap image) {
File fullCacheDir = new File(Environment.getExternalStorageDirectory().toString(),cacheDir);
String fileLocalName = new SimpleDateFormat("ddMMyyhhmmssSSS").format(new java.util.Date())+".PNG";
File fileUri = new File(fullCacheDir.toString(), fileLocalName);
FileOutputStream outStream = null;
try {
outStream = new FileOutputStream(fileUri);
image.compress(Bitmap.CompressFormat.PNG, 100, outStream);
outStream.flush();
outStream.close();
cacheMap.put(cacheUri, fileLocalName);
Log.i("CACHE", "Saved file "+cacheUri+" (which is now "+fileUri.toString()+") correctly");
bitmapMap.put(cacheUri, image);
ObjectOutputStream os = new ObjectOutputStream(new BufferedOutputStream(
new FileOutputStream(new File(fullCacheDir.toString(), CACHE_FILENAME))));
os.writeObject(cacheMap);
os.close();
} catch (FileNotFoundException e) {
Log.i("CACHE", "Error: File "+cacheUri+" was not found!");
e.printStackTrace();
} catch (IOException e) {
Log.i("CACHE", "Error: File could not be stuffed!");
e.printStackTrace();
}
}
public Bitmap getCacheFile(String cacheUri) {
if(bitmapMap.containsKey(cacheUri)) return (Bitmap)bitmapMap.get(cacheUri);
if(!cacheMap.containsKey(cacheUri)) return null;
String fileLocalName = cacheMap.get(cacheUri).toString();
File fullCacheDir = new File(Environment.getExternalStorageDirectory().toString(),cacheDir);
File fileUri = new File(fullCacheDir.toString(), fileLocalName);
if(!fileUri.exists()) return null;
Log.i("CACHE", "File "+cacheUri+" has been found in the Cache");
Bitmap bm = BitmapFactory.decodeFile(fileUri.toString());
bitmapMap.put(cacheUri, bm);
return bm;
}
}

Although the selected answer is correct, but it's a bit lengthy as its downloading image from the server first. Those who are just looking at how to save bitmap into cache for them we can use Android's native LruCache library. Here I have written a detailed article on the topic LruCache in Java & LruCache in Kotlin.
Java Class to save Bitmap in Cache:
import android.graphics.Bitmap;
import androidx.collection.LruCache;
public class MyCache {
private static MyCache instance;
private LruCache<Object, Object> lru;
private MyCache() {
lru = new LruCache<Object, Object>(1024);
}
public static MyCache getInstance() {
if (instance == null) {
instance = new MyCache();
}
return instance;
}
public LruCache<Object, Object> getLru() {
return lru;
}
public void saveBitmapToCahche(String key, Bitmap bitmap){
try {
MyCache.getInstance().getLru().put(key, bitmap);
}catch (Exception e){}
}
public Bitmap retrieveBitmapFromCache(String key){
try {
Bitmap bitmap = (Bitmap) MyCache.getInstance().getLru().get(key);
return bitmap;
}catch (Exception e){}
return null;
}
}

Related

How to merge the two audio files into a single audio file in android?

I want to get two audio files as input, then merge them byte wise and save it as a single file.
In this code I have tried to do it in Java and it's working fine, but I don't know how to do it in android.
How to do it in android?
import java.io.File;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.Path;
import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
public class FileMixer {
public static void main(String[] args)
{
try
{
Path path1 = Paths.get("C:\\Srini\\Wav\\welcome.wav");
Path path2 = Paths.get("C:\\Srini\\Wav\\goodbye.wav");
String path3 ="C:\\Srini\\Wav\\srini12.wav";
File Newfilepath=new File(path3);
byte[] byte1 = Files.readAllBytes(path1);
byte[] byte2 = Files.readAllBytes(path2);
byte[] out = new byte[byte1.length];
for (int i=0; i<byte1.length; i++)
{
out[i] = (byte) ((byte1[i] + byte2[i]) >> 1);
}
InputStream byteArray = new ByteArrayInputStream(out);
AudioInputStream ais = AudioSystem.getAudioInputStream(byteArray);
AudioSystem.write(ais, AudioFileFormat.Type.WAVE,Newfilepath);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
private void mergeSongs(File mergedFile,File...mp3Files){
FileInputStream fisToFinal = null;
FileOutputStream fos = null;
try {
fos = new FileOutputStream(mergedFile);
fisToFinal = new FileInputStream(mergedFile);
for(File mp3File:mp3Files){
if(!mp3File.exists())
continue;
FileInputStream fisSong = new FileInputStream(mp3File);
SequenceInputStream sis = new SequenceInputStream(fisToFinal, fisSong);
byte[] buf = new byte[1024];
try {
for (int readNum; (readNum = fisSong.read(buf)) != -1;)
fos.write(buf, 0, readNum);
} finally {
if(fisSong!=null){
fisSong.close();
}
if(sis!=null){
sis.close();
}
}
}
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(fos!=null){
fos.flush();
fos.close();
}
if(fisToFinal!=null){
fisToFinal.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
For combining two wav files use this code,
import java.io.File;
import java.io.IOException;
import java.io.SequenceInputStream;
import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
public class WavAppender {
public static void main(String[] args) {
String wavFile1 = "D:\\wavOne.wav";
String wavFile2 = "D:\\wavTwo.wav";
try {
AudioInputStream clip1 = AudioSystem.getAudioInputStream(new File(wavFile1));
AudioInputStream clip2 = AudioSystem.getAudioInputStream(new File(wavFile2));
AudioInputStream appendedFiles =
new AudioInputStream(
new SequenceInputStream(clip1, clip2),
clip1.getFormat(),
clip1.getFrameLength() + clip2.getFrameLength());
AudioSystem.write(appendedFiles,
AudioFileFormat.Type.WAVE,
new File("D:\\wavAppended.wav"));
} catch (Exception e) {
e.printStackTrace();
}
}
}
It is too late. But still, someone might need a proper solution. That is why I am suggesting using AudioMixer-android library. You can also perform a lot of audio processing things.

Android Deleting File From Storage OutputStream

I am trying to delete a file from storage however when I do it returns true as it's been deleted yet on next boot up reads out the file as if it still exists :/
package com.example.Mazer.Utilities;
import android.app.Activity;
import android.content.Context;
import android.util.Log;
import java.io.*;
public class ObjectSaver {
public static void writeObjectToFile(Context c, Object object, String filename) {
ObjectOutputStream objectOut = null;
try {
FileOutputStream fileOut = c.getApplicationContext().openFileOutput(filename, Activity.MODE_WORLD_READABLE);
objectOut = new ObjectOutputStream(fileOut);
objectOut.writeObject(object);
fileOut.getFD().sync();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (objectOut != null) {
try {
objectOut.close();
} catch (IOException e) {
Log.d("GameActivity", "Can't close objectOut ObjectOutputStream");
}
}
}
}
public static void deleteObjectFromFile(Context c, String filename) {
c.deleteFile( filename);
//NOPE
c.getApplicationContext().deleteFile(filename);
//NOPE
String s = c.getFilesDir().getAbsolutePath() + "/" + filename;
c.deleteFile(s);
//NOPE
}
public static Object readObjectFromFile(Context c, String filename) {
ObjectInputStream objectIn = null;
Object object = null;
try {
FileInputStream fileIn = c.getApplicationContext().openFileInput(filename);
objectIn = new ObjectInputStream(fileIn);
object = objectIn.readObject();
} catch (FileNotFoundException e) {
return null;
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
if (objectIn != null) {
try {
objectIn.close();
} catch (IOException e) {
// do nowt
}
}
}
return object;
}
}
As you can see I have added a few out of the million approaches I have tried, I have even tried over-writing the file.
I read from the file like so:
maze = (Maze) ObjectSaver.readObjectFromFile(Splash.this, "currentMaze");
and... I save to the file like so..
ObjectSaver.writeObjectToFile(context, new Maze(this), "currentMaze");
This might help:
import java.io.File;
public static void deleteObjectFromFile(Context c, String filename) {
File file = new File(fileName);
if (file.exists()) {
file.delete();
}
}
boolean deleted = false;
File file = new File(selectedFilePath);
if (file.exists())
deleted = file.delete();
where selectedFilePath is the path of the file you want to delete - for example:
/sdcard/MyFolder/example.mp3

image is not saving to android device in Sd card

package com.lociiapp;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.util.Log;
import android.widget.ImageView;
import android.widget.Toast;
import com.androidquery.AQuery;
import com.example.imageslideshow.R;
public class recciverfullimageActivty extends Activity {
String reccvierid;
Context context;
ImageView recciverimage;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
Intent myintent = getIntent();
reccvierid = myintent.getStringExtra("reccvierid");
recciverimage = (ImageView) findViewById(R.id.recciverImage);
String myfinalpathare = reccvierid;
Toast.makeText(getApplicationContext(), reccvierid, 10000).show();
String imagepathe = "http://api.lociiapp.com/TransientStorage/"
+ myfinalpathare + ".jpg";
try {
saveImage(imagepathe);
Log.e("****************************", "Sucess");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void saveImage(String urlPath) throws Exception {
String fileName = "test.jpg";
File folder = new File("/sdcard/LociiImages/");
// have the object build the directory structure, if needed.
folder.mkdirs();
final File output = new File(folder, fileName);
if (output.exists()) {
output.delete();
}
InputStream stream = null;
FileOutputStream fos = null;
try {
URL url = new URL(urlPath);
stream = url.openConnection().getInputStream();
// InputStreamReader reader = new InputStreamReader(stream);
DataInputStream dis = new DataInputStream(url.openConnection()
.getInputStream());
byte[] fileData = new byte[url.openConnection().getContentLength()];
for (int x = 0; x < fileData.length; x++) { // fill byte array with
// bytes from the data
// input stream
fileData[x] = dis.readByte();
}
dis.close();
fos = new FileOutputStream(output.getPath());
fos.write(fileData);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
This is My code I am trying to save Image which is coming from server we have Image Url . when i Run this Code then Folder is creating in Sd card But image is not downloading on Save in Sd care please help and tell where i am doing wrong .
Your checklist should be as follows:
A. Make sure you have the right permissions:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
B. Move networking and file IO logic to non-UI thread:
new AsyncTask<Params, Progress, Result>() {
#Override protected Result doInBackground() {
saveImage(imagepathe);
}
#Override protected void onPostExecute(String result) {
// update UI here
}
}.execute(params);
C. Do not read one byte at the time. It is probably not the source of your problem but it
does make your solution much slower than it can be:
Instead of:
for(;;) {
fileData[x] = dis.readByte();
}
Do this:
URL u = new URL(url);
URLConnection connection = u.openConnection();
byte[] buffer = new byte[connection.getContentLength()];
stream.readFully(buffer); // <------------- read all at once
stream.close();
D. And , finally, consider using Picasso for the job:
Picasso.with(context)
.load(url)
.resize(50, 50)
.centerCrop()
.into(imageView)
Nowadays you just no not need to write that much code to get were you're going..
Try this..
Call like below instead of saveImage(imagepathe);
myAsyncTask myWebFetch = new myAsyncTask();
myWebFetch.execute();
and myAsyncTask.class
class myAsyncTask extends AsyncTask<Void, Void, Void> {
public ProgressDialog dialog;
myAsyncTask()
{
dialog = new ProgressDialog(webview.this);
dialog.setMessage("Loading image...");
dialog.setCancelable(true);
dialog.setIndeterminate(true);
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
dialog.dismiss();
}
#Override
protected void onPreExecute() {
super.onPreExecute();
dialog.show();
}
protected Void doInBackground(Void... arg0) {
try {
InputStream stream = null;
URL url = new URL("http://api.lociiapp.com/TransientStorage/286.jpg");
URLConnection connection = url.openConnection();
try {
HttpURLConnection httpConnection = (HttpURLConnection) connection;
httpConnection.setRequestMethod("GET");
httpConnection.connect();
File SDCardRoot = Environment.getExternalStorageDirectory();
File myDir = new File(SDCardRoot + "/LociiImages");
myDir.mkdirs();
File file = new File(myDir,"test.jpg");
FileOutputStream fileOutput = new FileOutputStream(file);
if (httpConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
stream = httpConnection.getInputStream();
}
byte[] buffer = new byte[1024];
int bufferLength = 0;
while ( (bufferLength = stream.read(buffer)) > 0 ) {
fileOutput.write(buffer, 0, bufferLength);
}
fileOutput.close();
} catch (Exception ex) {
ex.printStackTrace();
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
EDIT
String imagePath = Environment.getExternalStorageDirectory().toString() + "/LociiImages/test.jpg";
Bitmap bitmap = BitmapFactory.decodeFile(imagePath);
imageview.setImageBitmap(bitmap);

Can't write an Object. Read-only file system

I'm trying to save this Object, Inventory, to the internal storage. I have the saving and getting methods in the class itself. When I try and call the save method, I end up with the exception. I had the Exception message write to the Logcat, and here's what I got:
08-04 02:32:23.690: VERBOSE/alex(278): /test (Read-only file system)
The file /test is "Read-only file system", but I had allowed writing external storage in the Manifest file:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
Here's the Inventory class. The last two methods are the save and read methods.
package com.androidbook.inventoryproject;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import android.util.Log;
public class Inventory implements Serializable {
private static final long serialVersionUID = 1L;
int numIngred;;
Ingredient[] ingredients;
ArrayList ingred = new ArrayList<Ingredient>();
public Inventory() {
numIngred = 0;
ingredients = new Ingredient[numIngred];
}
public int getNumIngred() {
return numIngred;
}
public String getIngredientName(int n) {
return ((Ingredient)ingred.get(n)).getName();
}
public Ingredient[] getIngredients() {
return ingredients;
}
public Ingredient getIngredient(int n) {
return (Ingredient)ingred.get(n);
}
public void addIngredient(String iname) {
numIngred++;
ingred.add(new Ingredient(iname));
}
public boolean saveInventory( Inventory inv) {
File suspend_f = new File("test");
FileOutputStream fos = null;
ObjectOutputStream oos = null;
boolean keep = true;
try {
fos = new FileOutputStream(suspend_f);
oos = new ObjectOutputStream(fos);
oos.writeObject(inv);
}
catch (Exception e) {
keep = false;
Log.v("alex", "" + e.getMessage());
}
finally {
try {
if (oos != null) oos.close();
if (fos != null) fos.close();
if (keep == false) suspend_f.delete();
}
catch (Exception e) { /* do nothing */ }
}
return keep;
}
public Inventory getInventory() {
File suspend_f = new File("test");
Inventory inven = null;
FileInputStream fis = null;
ObjectInputStream ois = null;
try{
fis = new FileInputStream(suspend_f);
ois = new ObjectInputStream(fis);
inven = (Inventory)ois.readObject();
}
catch (Exception e) {
String mess = e.getMessage();
}
finally {
try {
if (fis != null)
fis.close();
if (ois != null)
ois.close();
}
catch (Exception e) { }
}
return inven;
}
}
WRITE_EXTERNAL_STORAGE lets you write to the SD card, not to the filesystem root. You should try this:
File suspend_f = new File(Environment.getExternalStorageDirectory(), "test");
This verifies that the file you are using goes into a writable external folder.
EDIT: there is a bunch of other work you should do to verify that the SD card is available and writable. Read the specs to see how to make your file access robust by checking availability.

Need Sample Program on "saving Cache Files " in Android

I need a Sample application that demonstrates saving cache files in Android and also how to use getCacheDir() method?
Can Anyone help me in sorting out this issue?I need to save file in an absolute directory and need to parse that file.
Thank in Advance.
Use (in an Activity):
String textToCache = "Some text";
boolean success = GetCacheDirExample.writeAllCachedText(this, "myCacheFile.txt", textToCache);
String readText = GetCacheDirExample.readAllCachedText(this, "myCacheFile.txt");
GetCacheDirExample.java
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import android.content.Context;
public class GetCacheDirExample {
public static String readAllCachedText(Context context, String filename) {
File file = new File(context.getCacheDir(), filename);
return readAllText(file);
}
public static String readAllResourceText(Context context, int resourceId) {
InputStream inputStream = context.getResources().openRawResource(resourceId);
return readAllText(inputStream);
}
public static String readAllFileText(String file) {
try {
FileInputStream inputStream = new FileInputStream(file);
return readAllText(inputStream);
} catch(Exception ex) {
return null;
}
}
public static String readAllText(File file) {
try {
FileInputStream inputStream = new FileInputStream(file);
return readAllText(inputStream);
} catch(Exception ex) {
return null;
}
}
public static String readAllText(InputStream inputStream) {
InputStreamReader inputreader = new InputStreamReader(inputStream);
BufferedReader buffreader = new BufferedReader(inputreader);
String line;
StringBuilder text = new StringBuilder();
try {
while (( line = buffreader.readLine()) != null) {
text.append(line);
text.append('\n');
}
} catch (IOException e) {
return null;
}
return text.toString();
}
public static boolean writeAllCachedText(Context context, String filename, String text) {
File file = new File(context.getCacheDir(), filename);
return writeAllText(file, text);
}
public static boolean writeAllFileText(String filename, String text) {
try {
FileOutputStream outputStream = new FileOutputStream(filename);
return writeAllText(outputStream, text);
} catch(Exception ex) {
ex.printStackTrace();
return false;
}
}
public static boolean writeAllText(File file, String text) {
try {
FileOutputStream outputStream = new FileOutputStream(file);
return writeAllText(outputStream, text);
} catch(Exception ex) {
ex.printStackTrace();
return false;
}
}
public static boolean writeAllText(OutputStream outputStream, String text) {
OutputStreamWriter outputWriter = new OutputStreamWriter(outputStream);
BufferedWriter bufferedWriter = new BufferedWriter(outputWriter);
boolean success = false;
try {
bufferedWriter.write(text);
success = true;
} catch(Exception ex) {
ex.printStackTrace();
} finally {
try {
bufferedWriter.close();
} catch(Exception ex) {
ex.printStackTrace();
}
}
return success;
}
}
/** Getting Cache Directory */
File tempFile;
File cDir = getBaseContext().getCacheDir();
/* Makes a textfile in the absolute cache directory */
tempFile = new File(cDir.getPath() + "/" + "textFile.txt") ;
/* Writing into the created textfile */
FileWriter writer=null;
try {
writer = new FileWriter(tempFile);
writer.write("hello workd!");
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
/* Reading from the Created File */
String strLine="";
StringBuilder text = new StringBuilder();
try {
FileReader fReader = new FileReader(tempFile);
BufferedReader bReader = new BufferedReader(fReader);
while( (strLine=bReader.readLine()) != null ){
text.append(strLine+"\n");
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}
Unless you really need it to be cache, you should look at storing the files more persistently:
http://developer.android.com/guide/topics/data/data-storage.html#filesInternal
I haven't tried working with the cache, but it seems that once you get the handle, it should work with the same commands used for persistent files.

Categories

Resources