Anyone knows how to detect uris from moved files programmatically in Java/Android?When I start the app I detect all images in my phone (with their uris, path....), if I move the images with a media manager, next time I start the app I can get the whole uris again, with the new path. But, if I move these images programmatically (copying the image and deleting the image from the original path) next time I start the app the uris will be the previous path a not the new one. I'm trying to fix deleting the app cache, but doesn't work. Anyone knows what can be happen?
I tried to move the files with two functions and I have same problem:
public static void moveFile(ArrayList<ImagesData> images) throws IOException {
for (int i = 0; i < images.size(); i++) {
File file_Source = new File(images.get(i).imagePath);
File file_Destination = new File(Environment.getExternalStorageDirectory() + "/PrivateGallery/" + new File(images.get(i).imagePath).getName());
FileChannel source = null;
FileChannel destination = null;
try {
source = new FileInputStream(file_Source).getChannel();
destination = new FileOutputStream(file_Destination).getChannel();
Log.i(TAG, "Source " + source + " destination " + destination);
long count = 0;
long size = source.size();
while((count += destination.transferFrom(source, count, size-count)) < size);
//destination.transferFrom(source, 0, source.size());
file_Source.delete();
}
finally {
if(source != null) {
source.close();
}
if(destination != null) {
destination.close();
}
}
}
}
public void changeToNewPath(ArrayList<ImagesData> images) {
String outputPath = Environment.getExternalStorageDirectory() + "/PrivateGallery/";
//TODO COMPROBAR SI EXISTE YA UN ARCHIVO CON SU NOMBRE
InputStream in = null;
OutputStream out = null;
for(int i = 0; i < images.size(); i++) {
try { //TODO revisar lod el cambio de directorio
//create output directory if it doesn't exist
//File dir = new File(outputPath);
File f = new File(images.get(i).imagePath);
String a = f.getName();
Log.e(TAG, a);
in = new FileInputStream(images.get(i).imagePath);
out = new FileOutputStream(outputPath + new File(images.get(i).imagePath).getName());
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
in.close();
in = null;
// write the output file
out.flush();
out.close();
out = null;
// delete the original file
new File(images.get(i).imagePath).delete();
} catch (FileNotFoundException fnfe1) {
Log.e("tag", fnfe1.getMessage());
} catch (Exception e) {
Log.e("tag", e.getMessage());
}
}
}
I have converted the db file into csv file and worked perfectly in android. But I manually deleted the csv file from storage location and try to run the same code. but I am unable to write the file into the same location. No exception noticed.
The code used is as follows:
public void exportTopic() {
int rowCount, colCount;
int i, j;
Cursor c=null;
SQLHelper helperr=null;
try {
helperr=new SQLHelper(getActivity());
c = helperr.getAllTopics();
Log.d("exportPath", sdCardDir.getPath());
String filename = "MyBackUp.csv";
File CsvFile = new File(sdCardDir, filename);
FileWriter fw = new FileWriter(CsvFile);
BufferedWriter bw = new BufferedWriter(fw);
rowCount = c.getCount();
colCount = c.getColumnCount();
if (rowCount > 0) {
c.moveToFirst();
for (i = 0; i < rowCount; i++) {
c.moveToPosition(i);
for (j = 0; j < colCount; j++) {
if (j != colCount - 1)
bw.write(c.getString(j) + ",");
else
bw.write(c.getString(j));
}
bw.newLine();
}
bw.flush();
}
} catch (Exception ex) {
Log.d("Exception","at export topic");
helperr.close();
ex.printStackTrace();
}
helperr.close();
c.close();
}
I am calling the function from here:
private View.OnClickListener clickHandler = new View.OnClickListener() {
#Override
public void onClick(View v) {
if (v.getId() == R.id.exportToDropBtn) {
try {
exportTopic();
}catch (Exception e){
Log.d("Exception","at export button");
e.printStackTrace();
}
}
Add code to create a file if it does not exist:
File dir = new File(Environment.getExternalStorageDirectory() + "/yourAppName");
// make them in case they're not there
dir.mkdirs();
File wbfile = new File(dir, fileName);
try {
if (!wbfile.exists()) {
wbfile.createNewFile();
}
// BufferedWriter for performance, true to set append to file flag
BufferedWriter buf = new BufferedWriter(
new FileWriter(wbfile, true));
buf.append(strBuilder.toString());
buf.newLine();
buf.close();
} catch(Exception e){
e.printStackTrace();
}
Hello i am trying to manipulate a file(copying temp to orig.) but it seems that there is a problem (access is denied) whenever i try to open transaction_sales.dat file for the second time. What should I do? :(((
public static void writeFile() {
Path file = null;
Path file2 = null;
OutputStream output = null;
BufferedWriter writer = null;
InputStream input = null;
BufferedReader reader = null;
String[] strReaderAssign = new String[10000]; // for reading files
String strReader = null;
int strike = 0; // counter
try { // UNFINISHED
file = Paths.get("transaction_sales.dat");
output = new BufferedOutputStream(Files.newOutputStream(file, CREATE));
writer = new BufferedWriter(new OutputStreamWriter(output));
input = new BufferedInputStream(Files.newInputStream(file));
reader = new BufferedReader(new InputStreamReader(input));
if(reader.readLine() == null) { // if file is empty
writer.write(strHolder, 0, strHolder.length()); // writes to file
writer.close(); // closes file
reader.close(); // closes read file
}
else { // write to temporary file
file = Paths.get("transaction_sales.dat");
file2 = Paths.get("transaction_sales_temp.dat"); // temporary file
output = new BufferedOutputStream(Files.newOutputStream(file2));
writer = new BufferedWriter(new OutputStreamWriter(output));
writer.write((strHolder), 0, strHolder.length()); // writes to temp file
for(int i = 0; i < 10; i++) {
writer.newLine(); // writes new line to file 10x
}
writer.close(); // closes file
try {
file = Paths.get("transaction_sales.dat"); // re-reads updated data in a file
input = new BufferedInputStream(Files.newInputStream(file));
reader = new BufferedReader(new InputStreamReader(input));
while((strReader = reader.readLine()) != null) {
strReaderAssign[strike] = strReader; // assigns to array
strike++; // increment
}
strike = 0; // resets value
reader.close(); // closes file
// appends file
output = new BufferedOutputStream(Files.newOutputStream(file2, APPEND));
writer = new BufferedWriter(new OutputStreamWriter(output));
for(int j = 0; (strReaderAssign[j] != null); j++) {
writer.write(strReaderAssign[j]);
writer.newLine();
}
// resets value
for(int j = 0; j < strReaderAssign.length; j++) {
strReaderAssign[j] = null;
}
writer.close(); // closes file
file = Paths.get("transaction_sales.dat");
file2 = Paths.get("transaction_sales_temp.dat");
Files.copy(file2, file, REPLACE_EXISTING);
Files.delete(file);
}
catch(IOException d) {
System.out.println(d.getMessage());
}
}
}
catch(Exception e) {
System.out.println(e.getMessage());
}
}
Unzipping files on android seems to be dreadfully slow. At first I thought this was just the emulator but it appears to be the same on the phone. I've tried different compression levels, and eventually dropped down to storage mode but it still takes ages.
Anyway, there must be a reason! Does anyone else have this problem? My unzip method looks like this:
public void unzip()
{
try{
FileInputStream fin = new FileInputStream(zipFile);
ZipInputStream zin = new ZipInputStream(fin);
File rootfolder = new File(directory);
rootfolder.mkdirs();
ZipEntry ze = null;
while ((ze = zin.getNextEntry())!=null){
if(ze.isDirectory()){
dirChecker(ze.getName());
}
else{
FileOutputStream fout = new FileOutputStream(directory+ze.getName());
for(int c = zin.read();c!=-1;c=zin.read()){
fout.write(c);
}
//Debug.out("Closing streams");
zin.closeEntry();
fout.close();
}
}
zin.close();
}
catch(Exception e){
//Debug.out("Error trying to unzip file " + zipFile);
}
}
I don't know if unzipping on Android is slow, but copying byte for byte in a loop is surely slowing it down even more. Try using BufferedInputStream and BufferedOutputStream - it might be a bit more complicated, but in my experience it is worth it in the end.
BufferedInputStream in = new BufferedInputStream(zin);
BufferedOutputStream out = new BufferedOutputStream(fout);
And then you can write with something like that:
byte b[] = new byte[1024];
int n;
while ((n = in.read(b,0,1024)) >= 0) {
out.write(b,0,n);
}
Thanks for the solution Robert.
I modified my unzip method and now it takes only a few seconds instead of 2 minutes.
Maybe someone's interested in my solution. So here you go:
public void unzip() {
try {
FileInputStream inputStream = new FileInputStream(filePath);
ZipInputStream zipStream = new ZipInputStream(inputStream);
ZipEntry zEntry = null;
while ((zEntry = zipStream.getNextEntry()) != null) {
Log.d("Unzip", "Unzipping " + zEntry.getName() + " at "
+ destination);
if (zEntry.isDirectory()) {
hanldeDirectory(zEntry.getName());
} else {
FileOutputStream fout = new FileOutputStream(
this.destination + "/" + zEntry.getName());
BufferedOutputStream bufout = new BufferedOutputStream(fout);
byte[] buffer = new byte[1024];
int read = 0;
while ((read = zipStream.read(buffer)) != -1) {
bufout.write(buffer, 0, read);
}
zipStream.closeEntry();
bufout.close();
fout.close();
}
}
zipStream.close();
Log.d("Unzip", "Unzipping complete. path : " + destination);
} catch (Exception e) {
Log.d("Unzip", "Unzipping failed");
e.printStackTrace();
}
}
public void hanldeDirectory(String dir) {
File f = new File(this.destination + dir);
if (!f.isDirectory()) {
f.mkdirs();
}
}
Using above ideas and ideas from some other sources I have created this class
Create this new class
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import android.util.Log;
public class DecompressFast {
private String _zipFile;
private String _location;
public DecompressFast(String zipFile, String location) {
_zipFile = zipFile;
_location = location;
_dirChecker("");
}
public void unzip() {
try {
FileInputStream fin = new FileInputStream(_zipFile);
ZipInputStream zin = new ZipInputStream(fin);
ZipEntry ze = null;
while ((ze = zin.getNextEntry()) != null) {
Log.v("Decompress", "Unzipping " + ze.getName());
if(ze.isDirectory()) {
_dirChecker(ze.getName());
} else {
FileOutputStream fout = new FileOutputStream(_location + ze.getName());
BufferedOutputStream bufout = new BufferedOutputStream(fout);
byte[] buffer = new byte[1024];
int read = 0;
while ((read = zin.read(buffer)) != -1) {
bufout.write(buffer, 0, read);
}
bufout.close();
zin.closeEntry();
fout.close();
}
}
zin.close();
Log.d("Unzip", "Unzipping complete. path : " +_location );
} catch(Exception e) {
Log.e("Decompress", "unzip", e);
Log.d("Unzip", "Unzipping failed");
}
}
private void _dirChecker(String dir) {
File f = new File(_location + dir);
if(!f.isDirectory()) {
f.mkdirs();
}
}
}
USAGE
just pass your file location of zip file and your destination Location to this class
example
String zipFile = Environment.getExternalStorageDirectory() + "/the_raven.zip"; //your zip file location
String unzipLocation = Environment.getExternalStorageDirectory() + "/unzippedtestNew/"; // unzip location
DecompressFast df= new DecompressFast(zipFile, unzipLocation);
df.unzip();
Dont Forget to add following permissions in manifest(also Run time permission if version higher than marshmellow)
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
hope this helps
The URL that helped me learn how to zip and unzip can be found here.
I used that URL in conjuction with user3203118's answer above for unzipping. This is for future references for people who run in to this issue and need help solving it.
Below is the ZipManager code I am using:
public class ZipManager {
private static final int BUFFER = 80000;
public void zip(String[] _files, String zipFileName) {
try {
BufferedInputStream origin = null;
FileOutputStream dest = new FileOutputStream(zipFileName);
ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(
dest));
byte data[] = new byte[BUFFER];
for (int i = 0; i < _files.length; i++) {
Log.v("Compress", "Adding: " + _files[i]);
FileInputStream fi = new FileInputStream(_files[i]);
origin = new BufferedInputStream(fi, BUFFER);
ZipEntry entry = new ZipEntry(_files[i].substring(_files[i]
.lastIndexOf("/") + 1));
out.putNextEntry(entry);
int count;
while ((count = origin.read(data, 0, BUFFER)) != -1) {
out.write(data, 0, count);
}
origin.close();
}
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public void unzip(String _zipFile, String _targetLocation) {
// create target location folder if not exist
dirChecker(_targetLocation);
try {
FileInputStream fin = new FileInputStream(_zipFile);
ZipInputStream zin = new ZipInputStream(fin);
ZipEntry ze = null;
while ((ze = zin.getNextEntry()) != null) {
// create dir if required while unzipping
if (ze.isDirectory()) {
dirChecker(ze.getName());
} else {
FileOutputStream fout = new FileOutputStream(
_targetLocation + "/" + ze.getName());
BufferedOutputStream bufout = new BufferedOutputStream(fout);
byte[] buffer = new byte[1024];
int read = 0;
while ((read = zin.read(buffer)) != -1) {
bufout.write(buffer, 0, read);
}
zin.closeEntry();
bufout.close();
fout.close();
}
}
zin.close();
} catch (Exception e) {
System.out.println(e);
}
}
private void dirChecker(String dir) {
File f = new File(dir);
if (!f.isDirectory()) {
f.mkdirs();
}
}
}
Just call this method and it will give you much better performance..
public boolean unzip(Context context) {
try {
FileInputStream fin = new FileInputStream(_zipFile);
ZipInputStream zin = new ZipInputStream(fin);
BufferedInputStream in = new BufferedInputStream(zin);
ZipEntry ze = null;
while ((ze = zin.getNextEntry()) != null) {
Log.v("Decompress", "Unzipping " + ze.getName());
if (ze.isDirectory()) {
_dirChecker(ze.getName());
} else {
FileOutputStream fout = new FileOutputStream(_location
+ ze.getName());
BufferedOutputStream out = new BufferedOutputStream(fout);
byte b[] = new byte[1024];
for (int c = in.read(b,0,1024); c != -1; c = in.read()) {
out.write(b,0,c);
}
zin.closeEntry();
fout.close();
}
}
zin.close();
return true;
} catch (Exception e) {
Log.e("Decompress", "unzip", e);
return false;
}
}
private void _dirChecker(String dir) {
File f = new File(_location + dir);
if (!f.isDirectory()) {
f.mkdirs();
}
}
In case of using BufferedOutputStream be sure to flush it. If you do not do it, size smaller than buffer will not be unzipped properly
if (ze.isDirectory()) {
_dirChecker(ze.getName());
} else {
FileOutputStream fout = new FileOutputStream(_location
+ ze.getName());
BufferedOutputStream out = new BufferedOutputStream(fout);
byte buffer[] = new byte[1024];
for (int c = in.read(buffer,0,1024); c != -1; c = in.read()) {
out.write(buffer,0,c);
}
out.flush();//flush it......
zin.closeEntry();
fout.close();
}
I have a dialog using JFileChooser. When I save a file by FileOutputStream, I want to save it as file.txt in the path which the user want. But it always saves in c:/user/Document.
Here is the code:
DownLoadDialog downloadDialog = new DownLoadDialog();
int result = downloadDialog.showSaveDialog(queryPanel);
if (result == downloadDialog.APPROVE_OPTION) {
File file = downloadDialog.getSelectedFile();
//String parth =file.getPath();
//System.out.println(parth);
//if(file.exists()) {
//int response = JOptionPane.showConfirmDialog (null,
// "Overwrite existing file?","Confirm Overwrite",
// JOptionPane.OK_CANCEL_OPTION,JOptionPane.QUESTION_MESSAGE);
//if(response == JOptionPane.OK_OPTION) {}
//} else {
if (resultGoogleSearch > 0) {
{
String parth = new File(downloadDialog.getSelectedFile().
getAbsolutePath().concat(".txt")).toString();
System.out.println(parth);
for (int i = 0; i < resultGoogleSearch; i++) {
String[] temp = googleSearchResult.get(i).split("<br>");
//String resultURL = temp[0];
//File dir = downloadDialog.getCurrentDirectory();
try {
FileOutputStream googleReuslt = new FileOutputStream(
downloadDialog.getSelectedFile().getAbsolutePath()
+ ".txt");
OutputStreamWriter writer = new
OutputStreamWriter(googleReuslt);
BufferedWriter buffer = new BufferedWriter(writer);
writer.write(temp[0]);
writer.close();
buffer.close();
} catch (FileNotFoundException fEx) {
} catch (IOException ioEx) {
}
}
}
JOptionPane.showMessageDialog(IDRSApplication.idrsJFrame,
IDRSResourceBundle.res.getString("successful"));
}
The problem is here: why can't I set path for new file?
FileOutputStream googleReuslt = new FileOutputStream(
downloadDialog.getSelectedFile().getAbsolutePath() + ".txt");
OutputStreamWriter writer = new OutputStreamWriter(googleReuslt);
BufferedWriter buffer = new BufferedWriter(writer);
writer.write(temp[0]);
writer.close();
buffer.close();
The code you provided works as you would expect. (At least under linux.)
I suggest you do a SSCCE and update your question.