How to compress a folder and send via email in android - java

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.

Related

Java - Getting specific folder and files from zip 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"/>

Transferring a File in android

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.

Zip files inside without including main folder In android java

im using this code it perfectly create zip files for example i have folder
sdcard/music and when i create xxx.zip file it creates .zip file includes music/songs and also some sub folders in it
but i want to exclude "music" the main Folder in the .zip file and want it to start directly including all songs and subfolders in it,how to do it
i use this way but it takes main folder name as well when zipping
public void unzipbutton(View v){ // button click
try {
FileOutputStream fos = new FileOutputStream("/mnt/sdcard/songs.zip");
ZipOutputStream zos = new ZipOutputStream(fos);
addDirToZipArchive(zos, new File("/mnt/sdcard/music"), null);
zos.flush();
fos.flush();
zos.close();
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void addDirToZipArchive(ZipOutputStream zos, File fileToZip, String parrentDirectoryName) throws Exception {
if (fileToZip == null || !fileToZip.exists()) {
return;
}
String zipEntryName = fileToZip.getName();
if (parrentDirectoryName!=null && !parrentDirectoryName.isEmpty()) {
zipEntryName = parrentDirectoryName + "/" + fileToZip.getName();
}
if (fileToZip.isDirectory()) {
System.out.println("+" + zipEntryName);
for (File file : fileToZip.listFiles()) {
addDirToZipArchive(zos, file, zipEntryName);
}
} else {
System.out.println(" " + zipEntryName);
byte[] buffer = new byte[1024];
FileInputStream fis = new FileInputStream(fileToZip);
zos.putNextEntry(new ZipEntry(zipEntryName));
int length;
while ((length = fis.read(buffer)) > 0) {
zos.write(buffer, 0, length);
}
zos.closeEntry();
fis.close();
}
}
anybody help on this,thanks
this has been so tricky till now no way works at the moments for me :/
In your ZipEntry check the full path of zipEntryName, it must be something like: "music/Pink/try.mp3" just invoke a substring in order to obtain as zipEntryName "Pink/try.mp3", your zip file will be the same "songs.zip" but inside of it you'll find the folder "Pink" instead the main folder "music/Pink..."
It worked for me.

I keep getting java.io.FileNotFoundException with my zip extractor

Could anybody help me with my java zip extractor as stated in the title I keep getting java.io.FileNotFoundException on the folders with files in them
public void UnZip() {
try {
byte[] data = new byte[1000];
int byteRead;
BufferedOutputStream bout = null;
ZipInputStream zin = new ZipInputStream(new BufferedInputStream(new FileInputStream(sourceFile)));
ZipEntry entry;
while ((entry = zin.getNextEntry()) != null) {
String filename = entry.getName();
File newfile = new File(Deobf2 + File.separator + filename);
System.out.println("file unzip : " + newfile.getAbsoluteFile());
new File(newfile.getParent()).mkdirs();
FileOutputStream fos = new FileOutputStream(newfile);
int len;
while ((len = zin.read(data)) > 0) {
fos.write(data, 0, len);
}
fos.close();
entry = zin.getNextEntry();
}
zin.closeEntry();
zin.close();
System.out.println("Done");
} catch (Exception e) {
e.printStackTrace();
}
}
error log
http://pastebin.com/crMKaa37
values
static String tempDir = System.getProperty("java.io.tmpdir");
public static File Deobf = new File(tempDir + "Deobf");
public static String Deobf2 = Deobf.toString();
entire code paste
http://pastebin.com/1vTfABR1
I have copy pasted same code and it is working fine. I think u dont have administrator permission on C drive. login As Administrator and run . it will work.
Access Denied Exception will come when u don have administrator level of permission on C drive.
The problem is Your doing
String Deobf2 = Deobf.toString();//this does not give the location of the file
use
file.getAbsolutePath();
in your case Deobf.getAbsolutePath();
instead. Check http://www.mkyong.com/java/how-to-get-the-filepath-of-a-file-in-java/
if you want to get the path only till the parent directory check this How to get absolute path of directory of a file?
Problem fixed changed some code
for anyone whos wants a copy of the working zip extraction code here you go http://pastebin.com/bXL8pUSg
The variable Deobf2 in the output of the zip

How to use java.util.zip to archive/deflate string in java for use in Google Earth?

Use Case
I need to package up our kml which is in a String into a kmz response for a network link in Google Earth. I would like to also wrap up icons and such while I'm at it.
Problem
Using the implementation below I receive errors from both WinZip and Google Earth that the archive is corrupted or that the file cannot be opened respectively. The part that deviates from other examples I'd built this from are the lines where the string is added:
ZipEntry kmlZipEntry = new ZipEntry("doc.kml");
out.putNextEntry(kmlZipEntry);
out.write(kml.getBytes("UTF-8"));
Please point me in the right direction to correctly write the string so that it is in doc.xml in the resulting kmz file. I know how to write the string to a temporary file, but I would very much like to keep the operation in memory for understandability and efficiency.
private static final int BUFFER = 2048;
private static void kmz(OutputStream os, String kml)
{
try{
BufferedInputStream origin = null;
ZipOutputStream out = new ZipOutputStream(os);
out.setMethod(ZipOutputStream.DEFLATED);
byte data[] = new byte[BUFFER];
File f = new File("./icons"); //folder containing icons and such
String files[] = f.list();
if(files != null)
{
for (String file: files) {
LOGGER.info("Adding to KMZ: "+ file);
FileInputStream fi = new FileInputStream(file);
origin = new BufferedInputStream(fi, BUFFER);
ZipEntry entry = new ZipEntry(file);
out.putNextEntry(entry);
int count;
while((count = origin.read(data, 0, BUFFER)) != -1) {
out.write(data, 0, count);
}
origin.close();
}
}
ZipEntry kmlZipEntry = new ZipEntry("doc.kml");
out.putNextEntry(kmlZipEntry);
out.write(kml.getBytes("UTF-8"));
}
catch(Exception e)
{
LOGGER.error("Problem creating kmz file", e);
}
}
Bonus points for showing me how to put the supplementary files from the icons folder into a similar folder within the archive as opposed to at the same layer as the doc.kml.
Update Even when saving the string to a temp file the errors occur. Ugh.
Use Case Note The use case is for use in a web app, but the code to get the list of files won't work there. For details see how-to-access-local-files-on-server-in-jboss-application
You forgot to call close() on ZipOutputStream. Best place to call it is the finally block of the try block where it's been created.
Update: To create a folder, just prepend its name in the entry name.
ZipEntry entry = new ZipEntry("icons/" + file);

Categories