package org.openintents.filemanager;
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.InputStream;
import java.io.OutputStream;
import org.openintents.filemanager.util.UIUtils;
import org.openintents.intents.FileManagerIntents;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.widget.RelativeLayout;
import android.widget.Toast;
public class SaveAsActivity extends Activity {
protected static final int REQUEST_CODE_PICK_FILE_OR_DIRECTORY = 1;
private Uri source;
// Whether the scheme is file: (otherwise it's content:)
private boolean fileScheme = false;
@Override
public void onCreate(Bundle savedInstanceState) {
UIUtils.setThemeFor(this);
super.onCreate(savedInstanceState);
//This activity is never shown to the user.
setContentView(new RelativeLayout(this));
Intent receivedIntent = getIntent();
if(receivedIntent != null){
Uri uri = receivedIntent.getData();
source = uri;
if(uri.getScheme().equals("file"))
processFile(uri);
else if(uri.getScheme().equals("content"))
processContent(uri);
}
else{
Toast.makeText(this, R.string.saveas_no_file_picked, Toast.LENGTH_SHORT).show();
}
}
private void startPickActivity(Intent intent){
try {
startActivityForResult(intent, REQUEST_CODE_PICK_FILE_OR_DIRECTORY);
} catch (ActivityNotFoundException e) {
//Should never happen, but Java requires this catch
Toast.makeText(this, R.string.saveas_error, Toast.LENGTH_SHORT).show();
}
}
private Intent createPickIntent(){
return new Intent(FileManagerIntents.ACTION_PICK_FILE);
}
private void processFile(Uri uri){
fileScheme = true;
Intent intent = createPickIntent();
intent.setData(uri);
startPickActivity(intent);
}
private void processContent(Uri uri){
fileScheme = false;
String name = getPath(uri);
Intent intent = createPickIntent();
intent.setData(Uri.parse(name));
startPickActivity(intent);
}
/*
* Get the default path and filename for the saved file from content: scheme.
* As the directory is always used the SD storage.
* For GMail, the filename is the _display_name in its ContentProvider. Otherwise the file has
* no name.
* !IMPORTANT! When you add another "special" intent-filter like the one for GMail, consider,
* if you could add also the code for finding out the filename.
*/
private String getPath(Uri uri){
Uri sd = Uri.fromFile(Environment.getExternalStorageDirectory());
if(uri.getHost().equals("gmail-ls")){
Cursor cur = managedQuery(uri, new String[]{"_display_name"}, null, null, null);
int nameColumn = cur.getColumnIndex("_display_name");
if(cur.moveToFirst()){
return sd.buildUpon().appendPath(cur.getString(nameColumn)).toString();
}
}
return sd.getPath();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case REQUEST_CODE_PICK_FILE_OR_DIRECTORY:
if (resultCode == RESULT_OK && data != null) {
Uri destinationUri = data.getData();
if (destinationUri != null && source != null) {
String destinationPath = destinationUri.getPath();
saveFile(new File(destinationPath));
}
}
break;
}
finish(); //End the activity
}
private void saveFile(File destination){
InputStream in = null;
OutputStream out = null;
try {
if(fileScheme)
in = new BufferedInputStream(new FileInputStream(source.getPath()));
else
in = new BufferedInputStream(getContentResolver().openInputStream(source));
out = new BufferedOutputStream(new FileOutputStream(destination));
byte[] buffer = new byte[1024];
while(in.read(buffer) != -1)
out.write(buffer);
Toast.makeText(this, R.string.saveas_file_saved, Toast.LENGTH_SHORT).show();
} catch(FileNotFoundException e){
//Should never get here
Toast.makeText(this, R.string.saveas_error, Toast.LENGTH_SHORT).show();
} catch(IOException e){
Toast.makeText(this, R.string.saveas_error, Toast.LENGTH_SHORT).show();
}
finally{
if (in != null) {
try {
in.close();
} catch (IOException e) {}
}
if (out != null) {
try {
out.close();
} catch (IOException e) {}
}
}
}
}