I would like to move a file from the download folder to a folder in my app, I have seen that you can use the Files.move (source, destination) function, but I don't know how to get the source and destination path.
When y try
String sdCard = Environment.getExternalStorageDirectory().toString();
File ficheroPrueba = new File(sdCard + "/pau_alem18je_compressed.pdf");
if(ficheroPrueba.exists())
Log.v(TAG, "Hola")
}
Despite having downloaded the file (it is seen in the android emulator in downloads) it does not print the log.v
Use Environment.getExternalStorageDirectory() to get to the root of external storage (which, on some devices, is an SD card).
String sdCard = Environment.getExternalStorageDirectory().toString();
// the file to be moved or copied
File sourceLocation = new File (sdCard + "/sample.txt");
// make sure your target location folder exists!
File targetLocation = new File (sdCard + "/MyNewFolder/sample.txt");
// just to take note of the location sources
Log.v(TAG, "sourceLocation: " + sourceLocation);
Log.v(TAG, "targetLocation: " + targetLocation);
try {
// 1 = move the file, 2 = copy the file
int actionChoice = 2;
// moving the file to another directory
if(actionChoice==1){
if(sourceLocation.renameTo(targetLocation)){
Log.v(TAG, "Move file successful.");
}else{
Log.v(TAG, "Move file failed.");
}
}
// we will copy the file
else{
// make sure the target file exists
if(sourceLocation.exists()){
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();
Log.v(TAG, "Copy file successful.");
}else{
Log.v(TAG, "Copy file failed. Source file missing.");
}
}
} catch (NullPointerException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
Related
Everyone: I am trying to send a folder (there are many files inside this folder) via email in Android Development.
First, I tried send the whole folder directly by using a click event and intent event.
My first attempt code shows the following:
My first part of code is onclicklistener event:
listView.setOnMenuItemClickListener(new SwipeMenuListView.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(int position, SwipeMenu menu,int index) {
switch (index) {
case 0:
sendEmail(list.get(position).getName());
break;
case 1:
list.remove(position);
adapter.notifyDataSetChanged();
}
return false;
}
});
My second code to send Email is as follows:
public void sendEmail(String data_path){
Intent email = new Intent(Intent.ACTION_SEND);
File file_location = new File(SDCard, data_path);
email.setType("vnd.android.cursor.dir/email");
email.putExtra(Intent.EXTRA_EMAIL, new String[]{"example#gmail.com"}); //set up email
email.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file_location)); //add attachment
email.putExtra(Intent.EXTRA_SUBJECT, "Subject");
startActivity(Intent.createChooser(email, "pick an Email provider"));
}
When I run this code, it works fine to jump into email sender, but without any folder implement, the email implement is empty.
I am wondering if it is impossible to send a folder directly via email.
Now I am trying to another way to solve this: I am planning to compress folder(.zip) first and then send the zip file to email in just one click event, But I can not find any solutions showing how to compress the folder and send zip file in just one click event, What I mean is that I want a solution which:
Clicks the file that needs to be sent (click event has finished)
After it triggers the click event, the app will compress the clicked file to a zip file.
The zip file will automatically add as mail implements that waits to be sent
I was trapped there for many days and still failed to find any answers, I also search on StackOverflow, but most questions are about how to compress a file or send file by email. I am looking for a way to compress a folder and send a zip file in one click event.
If you have any ideas, I would quite appreciate them!
Here is a workaround to transform your folder into zip.
First, grant permissions:
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
And then use this to transform your folder:
/*
*
* Zips a file at a location and places the resulting zip file at the toLocation
* Example: zipFileAtPath("downloads/myfolder", "downloads/myFolder.zip");
*/
public boolean zipFileAtPath(String sourcePath, String toLocation) {
final int BUFFER = 2048;
File sourceFile = new File(sourcePath);
try {
BufferedInputStream origin = null;
FileOutputStream dest = new FileOutputStream(toLocation);
ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(
dest));
if (sourceFile.isDirectory()) {
zipSubFolder(out, sourceFile, sourceFile.getParent().length());
} else {
byte data[] = new byte[BUFFER];
FileInputStream fi = new FileInputStream(sourcePath);
origin = new BufferedInputStream(fi, BUFFER);
ZipEntry entry = new ZipEntry(getLastPathComponent(sourcePath));
out.putNextEntry(entry);
int count;
while ((count = origin.read(data, 0, BUFFER)) != -1) {
out.write(data, 0, count);
}
}
out.close();
} catch (Exception e) {
e.printStackTrace();
return false;
}
Here is another example:
private static void zipFolder(String inputFolderPath, String outZipPath) {
try {
FileOutputStream fos = new FileOutputStream(outZipPath);
ZipOutputStream zos = new ZipOutputStream(fos);
File srcFile = new File(inputFolderPath);
File[] files = srcFile.listFiles();
Log.d("", "Zip directory: " + srcFile.getName());
for (int i = 0; i < files.length; i++) {
Log.d("", "Adding file: " + files[i].getName());
byte[] buffer = new byte[1024];
FileInputStream fis = new FileInputStream(files[i]);
zos.putNextEntry(new ZipEntry(files[i].getName()));
int length;
while ((length = fis.read(buffer)) > 0) {
zos.write(buffer, 0, length);
}
zos.closeEntry();
fis.close();
}
zos.close();
} catch (IOException ioe) {
Log.e("", ioe.getMessage());
}
}
Also you can use this library to zip a folder or file.
Import the .jar into your project and then you can do this to transform what you need:
try {
File input = new File("path/to/your/input/fileOrFolder");
String destinationPath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "zippedItem.zip";
ZipParameters parameters = new ZipParameters();
parameters.setCompressionMethod(Zip4jConstants.COMP_STORE);
parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
File output = new File(destinationPath);
ZipFile zipFile = new ZipFile(output);
// .addFolder or .addFile depending on your input
if (sourceFile.isDirectory())
zipFile.addFolder(input, parameters);
else
zipFile.addFile(input, parameters);
// Your input file/directory has been zipped at this point and you
// can access it as a normal file using the following line of code
File zippedFile = zipFile.getFile();
} catch (ZipException e) {
Log.e(TAG, Log.getStackTraceString(e));
}
This should do the trick.
I know with Kit Kat you can only write to your applications package specific directory on SD Cards. I was however under the impression you could still copy files from an SD card to local storage with the:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
I am simply testing if I can copy one file. If I am able to do that I will add the code to search the entire SD card DCIM folder. For now I have the following code (please forgive the messiness of the code, I have written C# and vb.net but java is still very new to me):
String dirPath = getFilesDir().getAbsolutePath() + File.separator + "TCM";
File projDir = new File(dirPath);
if (!projDir.exists())
projDir.mkdirs();
String CamPath = projDir + File.separator + tv2.getText();
File projDir2 = new File(CamPath);
if (!projDir2.exists())
projDir2.mkdirs();
File LocalBuck = new File(projDir2 + File.separator );
String imageInSD = Environment.getExternalStorageDirectory().getAbsolutePath();
File directory1 = new File (sdCard.getAbsolutePath() + "/DCIM");
File directory = new File(directory1 + "/100SDCIM");
File Buckfile = new File(directory, "/BigBuck.jpg");
try {
exportFile(Buckfile, LocalBuck);
} catch (IOException e) {
e.printStackTrace();
}
Here is my code for the export function/application:
private File exportFile(File src, File dst) throws IOException {
//if folder does not exist
if (!dst.exists()) {
if (!dst.mkdir()) {
return null;
}
}
String timeStamp = new SimpleDateFormat("yyyy_MM_dd_HHmmss").format(new Date());
File expFile = new File(dst.getPath() + File.separator + "IMG_" + timeStamp + ".jpg");
FileChannel inChannel = null;
FileChannel outChannel = null;
try {
//Straight to Error Handler
inChannel = new FileInputStream(src).getChannel();
outChannel = new FileOutputStream(expFile).getChannel();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
inChannel.transferTo(0, inChannel.size(), outChannel);
} finally {
if (inChannel != null)
inChannel.close();
if (outChannel != null)
outChannel.close();
}
return expFile;
}
Here is what my emulator looks like:
Looking for: Debug of SD Location
Should Find It?: EmulatorShowingSd
Question: Am I even able to copy a file from the SD card to local storage after KitKat; if so what is wrong in the code causing the exception to be thrown when it tries to access the SD card file?
So I am working on an Android app and what I am trying to do is make it so a user selects a zip file, it extracts the contents of it into an apk and installs the modified APK for the user. Right now all the files in the zip file have to be in the root of the zip file for it to work, if there is a directory and than the files I need it will not work. I am trying to make it scan for, for example the 'assets' folder and than get the directory its located in and copy all the files from that directory. I've tried extracting the files first and scanning using a loop, and for some reason had no success doing that, and it was time consuming anyways. If you know any libraries or could point me in the right direction that would be great! Thanks!
BTW you can extract all the files from zip folder like below. i.e
private String unpackZip(String path, String zipname) {
String apkfilename = "";
InputStream is;
ZipInputStream zis;
try {
String filename;
is = new FileInputStream(path + "/" + zipname);
zis = new ZipInputStream(new BufferedInputStream(is));
ZipEntry ze;
byte[] buffer = new byte[1024];
int count;
while ((ze = zis.getNextEntry()) != null) {
filename = ze.getName();
// Need to create directories if not exists, or
// it will generate an Exception...
if (ze.isDirectory()) {
File fmd = new File(path + "/" + filename);
fmd.mkdirs();
continue;
}
// This condition is to only extract the apk file
if (filename.endsWith(".apk")) {
apkfilename = filename;
FileOutputStream fout = new FileOutputStream(path + "/"
+ filename);
while ((count = zis.read(buffer)) != -1) {
fout.write(buffer, 0, count);
}
fout.close();
zis.closeEntry();
}
}
zis.close();
} catch (IOException e) {
e.printStackTrace();
return apkfilename;
}
return apkfilename;
}
//To install the apk file call the method
String apkfilename=unpackZip(Environment.getExternalStorageDirectory()
.getPath(), "temp.zip");
try {
File file = new File(Environment.getExternalStorageDirectory()
.getPath(), apkfilename);
Intent promptInstall = new Intent(Intent.ACTION_VIEW).setDataAndType(
Uri.fromFile(file), "application/vnd.android.package-archive");
startActivity(promptInstall);
} catch (Exception e) {
e.printStackTrace();
}
//Also add the read write permission
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
I have been struggling for two days to try and understand the process of copying a file to the SD card in Android. None of the methods I tried thus far seem to work.
My application has a Profile Picture setting. I need to launch an Intent to pick an Image, then I need to copy the Image to a new Path on the SD Card and then return the Uri of the new Image at which point I check the Images Orientation (Samsung Pics seem to be rotated 90 degrees sometimes). I then rotate the Image correctly and then save the Uri to a SharedPreferences File for use in the Application.
This is my Intent Call:
case R.id.ib_userImage:
i = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.INTERNAL_CONTENT_URI);
startActivityForResult(i, 1);
break;
This is my current horrific attempt at the copy function, I have changed it so much I am not very lost.
public static void copyImage(Context context, Uri uri) {
Log.i("ATTENTION", "Inside the Copy Function");
Log.i("ATTENTION", "Trying to copy file: " + uri.toString());
try {
String outputPath = Environment.getExternalStorageDirectory() + "/appname/images/";
File dir = new File(outputPath);
if(!dir.exists()) {
dir.mkdirs();
}
Log.i("ATTENTION", "Destination File Created at: " + dir.toURI().toString());
InputStream in = context.getContentResolver().openInputStream(uri);
OutputStream out = new FileOutputStream(dir);
byte[] buffer = new byte[1024];
while(in.read(buffer) > 0) {
out.write(buffer);
}
out.flush();
out.close();
in.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Log.i("ATTENTION", "File Copied");
}
Thank you for the help, I will provide any other information you might need.
Update:
I am now getting the Following Exception During the Write Process
java.io.FileNotFoundException: /storage/emulated/0/appname/images: open failed: EISDIR (Is a Directory);
My Understaing is that I specified a Directory with the following code:
String outputPath = Environment.getExternalStorageDirectory() + "/medinfo/images/";
File dir = new File(outputPath);
if(!dir.exists()) {
dir.mkdirs();
}
and then passed it to the OutputStream:
OutputStream out = new FileOutputStream(dir);
and the OutputStream would create the file for me within that Directory.
I didn't think that was actually trying to open the Directory.
Usual problem. Don't ignore the count returned by read().
while ((count = in,read(buffer)) > 0)
{
out.write(buffer, 0, count);
}
EDIT Your directory problem is cured by:
dir.getParentFile().mkdirs();
and removing the redundant existence check. At present you are creating the file itself as a directory.
I'm trying to copy some preloaded content stored in the assets folder of my app to the sdk card. Problem is I cant seem to get hold of the file path to the directory I want to copy. I want to loop through the preloadedcontent folder stored in my assets folder in the project, then copy each folder inside it across to the sdk card. I can loop through the preloaded content file names ok, but get a filenotfound exception when i try to copy the directory across:
- Assets/
-- preloadedcontent/
--- 112/
--- 113/
--- 114/
private void copyAssets() {
AssetManager assetManager = getAssets();
String[] files = null;
try {
files = assetManager.list("preloadedcontent");
} catch (IOException e) {
Log.e("tag", "Failed to get asset file list.", e);
}
for(String filename : files) {
Log.d("file: ",filename);
InputStream in = null;
OutputStream out = null;
try {
in = assetManager.open("preloadedcontent/" + filename + "/");
File outFile = new File(_DirectoryName, filename);
out = new FileOutputStream(outFile);
//copyFile(in, out);
File f = stream2file(in,filename);
copyDirectory(f,outFile);
in.close();
in = null;
out.flush();
out.close();
out = null;
} catch(IOException e) {
Log.e("tag", "Failed to copy asset file: " + filename, e);
}
}
}
error is on this line assetManager.open("preloadedcontent/" + filename + "/");
That's because "preloadedcontent/" + filename + "/" is not a valid file name (due to the trailing slash).
AssetManager#open() requires the name of a single file to open.
if(id.equals("AABA / ABO")){
AssetManager assetManager = activity.getAssets();
String[] files;
try {
files = assetManager.list("aaba");
List<String> it = Arrays.asList(files);
for (String string : it) {
InputStream ims = assetManager.open("aaba/" + string);
// create drawable from stream
Drawable d = Drawable.createFromStream(ims, null);
drawable.add(d);
}
} catch (IOException e) {
e.printStackTrace();
}
}