I‘m new to Android programming and couldn‘t find a good solution for my problem yet. In my App users can select photos from their gallery which are then used in a Cardview Layout for different categorys in the App which the user can create on his own. By now I‘m able to get Uri of the selected photo and can display it. But how can I save the photo to my App to make sure it‘s always there even though it gets deleted from the gallery?
Ref: How to make a copy of a file in android?
To copy a file and save it to your destination path you can use the method below.
public static void copy(File src, File dst) throws IOException {
InputStream in = new FileInputStream(src);
try {
OutputStream out = new FileOutputStream(dst);
try {
// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
} finally {
out.close();
}
} finally {
in.close();
}
}
On API 19+ you can use Java Automatic Resource Management:
public static void copy(File src, File dst) throws IOException {
t
ry (InputStream in = new FileInputStream(src)) {
try (OutputStream out = new FileOutputStream(dst)) {
// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
}
}
}
Related
I'm new at android development and I'm creating simple bluetooth app that can receive xml file and save xml file values to database. But how can I receive xml file from bytes array? Is it possible? After searchinf I found this question and based ont that question I try to save byte array to file. But how I need to test it? I can't find my file in my phone.
case Constants.MESSAGE_READ:
byte[] readBuffer = (byte[]) msg.obj;
try {
String path = activity.getFilesDir() + "/myFile.xml";
Log.d("MuTestClass", path);
FileOutputStream stream = new FileOutputStream(path);
stream.write(readBuffer);
stream.close();
} catch (Exception e1) {
e1.printStackTrace();
}
break;
You can use:
class Utils{
public static InputStream openFile(String filename) throws IOException{
AssetManager assManager = getApplicationContext().getAssets();
InputStream is = null;
is = assManager.open(filename);
return new BufferedInputStream(is);
}
public static byte[] readBytes(InputStream inputStream) throws IOException {
ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
int len = 0;
while ((len = inputStream.read(buffer)) != -1) {
byteBuffer.write(buffer, 0, len);
}
return byteBuffer.toByteArray();
}
}
like this:
try {
Utils.readBytes(Utils.openFile("something.xml"));
} catch (IOException e) {
e.printStackTrace();
}
I have a method that takes an image's URL and attempts to save it in memory. I need to retrieve this saved file later, and want to do so by getting its file path. How do I get the file name from this save method?
InputStream input;
try {
URL url = new URL (strURL);
input = url.openStream();
byte[] buffer = new byte[1500];
OutputStream output = new FileOutputStream ("/sdcard/"+pos+".png");
try {
int bytesRead = 0;
while ((bytesRead = input.read(buffer, 0, buffer.length)) >= 0) {
output.write(buffer, 0, bytesRead);
}
}
finally {
output.close();
buffer = null;
}
}
I am using Android Studio.
I'm using a content provider with an overridden openFile method:
#Override
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
ParcelFileDescriptor[] pipe = null;
InputStream in = null;
try {
pipe = ParcelFileDescriptor.createPipe();
String path = uri.getPath();
in = new FileInputStream(new File(path));
PipeFeederThread p = new PipeFeederThread(in, new AutoCloseOutputStream(pipe[1]));
p.start();
/*catches.... */
return (pipe[0]);
}
PipeFeederThread contains the usual block-write procedure:
byte[] buf = new byte[8192];
int len;
try {
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
Log.i("WRITE","Writing...");
}
Log.i("WRITE","Finished");
in.close();
out.flush();
out.close();
} catch (Exception e) {
}
But when I try to use my provider with an ACTION_VIEW intent like the gallery, the provider only writes 65535 bytes to "out" (the log shows only 8 times) and then nothing happens.
I've made a counter int to break the while loop when we reach the 65535 "limit" but then it'll transfer a corrupted file.
You should use the ParcelFileDescriptor.open() method. Something like this:
private val File.assetFileDescriptor get() = AssetFileDescriptor(ParcelFileDescriptor.open(this, MODE_READ_ONLY), 0, length())
And then in your code simply do:
return in.assetFileDescriptor
Please, suggest me the best way of copying a folder from assets to /data/data/my_app_pkg/files.
The folder from assets (www) contains files and subfolders. which I want to completely copy to the files/ of my internal app path mentioned.
I am successfully able to copy a file from assets to internal app files/ path, but unable to do the same in case of copying folder, even assetmanager.list isn't helping me out, as it is copying only the files, but not the directories / subfolders.
Please kindly suggest me the better way to do what I want
Hope use full to you below code:-
Copy files from a folder of SD card into another folder of SD card
Assets
AssetManager am = con.getAssets("folder/file_name.xml");
public static void copyDirectoryOneLocationToAnotherLocation(File sourceLocation, File targetLocation)
throws IOException {
if (sourceLocation.isDirectory()) {
if (!targetLocation.exists()) {
targetLocation.mkdir();
}
String[] children = sourceLocation.list();
for (int i = 0; i < sourceLocation.listFiles().length; i++) {
copyDirectoryOneLocationToAnotherLocation(new File(sourceLocation, children[i]),
new File(targetLocation, children[i]));
}
} else {
InputStream in = new FileInputStream(sourceLocation);
OutputStream out = new FileOutputStream(targetLocation);
// Copy the bits from instream to outstream
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
}
}
Hope this will help
private void getAssetAppFolder(String dir) throws Exception{
{
File f = new File(sdcardlocation + "/" + dir);
if (!f.exists() || !f.isDirectory())
f.mkdirs();
}
AssetManager am=getAssets();
String [] aplist=am.list(dir);
for(String strf:aplist){
try{
InputStream is=am.open(dir+"/"+strf);
copyToDisk(dir,strf,is);
}catch(Exception ex){
getAssetAppFolder(dir+"/"+strf);
}
}
}
public void copyToDisk(String dir,String name,InputStream is) throws IOException{
int size;
byte[] buffer = new byte[2048];
FileOutputStream fout = new FileOutputStream(sdcardlocation +"/"+dir+"/" +name);
BufferedOutputStream bufferOut = new BufferedOutputStream(fout, buffer.length);
while ((size = is.read(buffer, 0, buffer.length)) != -1) {
bufferOut.write(buffer, 0, size);
}
bufferOut.flush();
bufferOut.close();
is.close();
fout.close();
}
AssetManager defination and use:
...
AssetManager mngr = getAssets();
try{
encrypter.decrypt(mngr.open("sample.txt"),output_file);
}...(continued)
decrypt function:
public void decrypt(InputStream in, OutputStream out)
{
try
{
// Bytes read from in will be decrypted
in = new CipherInputStream(in, dcipher);
// Read in the decrypted bytes and write the cleartext to out
int numRead = 0;
while ((numRead = in.read(buf)) >= 0)
{
out.write(buf, 0, numRead);
}
out.close();
...(continued)
Its giving error for line out.write(buf, 0, numRead); as java.lang.NullPointerException.
This call was working fine when used as:
*encrypter.decrypt(new FileInputStream("sample.txt"),output_file)* (i.e. when reading file from local than assets directory of android);
Any reasons why?
Any help is appreciated! Thanks!
Your OutputStream is not initialized.So you are getting null pointer exception.you may want
something like this
public void decrypt(InputStream in,String file)
{
try
{
OutputStream out = new FileOutputStream(file);
// Bytes read from in will be decrypted
in = new CipherInputStream(in, dcipher);
// Read in the decrypted bytes and write the cleartext to out
int numRead = 0;
while ((numRead = in.read(buf)) >= 0)
{
out.write(buf, 0, numRead);
}
out.close();