I am working on an app that allows user to select a file from external storage and send it using Android Beam.
Here is the FileBrowser Activity to select a file from a directory and return the file name and directory path back to main activity:
public class FileBrowser extends Activity {
private String root;
private String currentPath;
private ArrayList<String> targets;
private ArrayList<String> paths;
private File targetFile;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_file_browser);
getActionBar().setDisplayHomeAsUpEnabled(true);
root = "/";
currentPath = root;
targets = null;
paths = null;
targetFile = null;
showDir(currentPath);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_file_browser, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
public void selectDirectory(View view) {
File f = new File(currentPath);
targetFile = f;
//Return target File to activity
returnTarget();
}
public void setCurrentPathText(String message)
{
TextView fileTransferStatusText = (TextView) findViewById(R.id.current_path);
fileTransferStatusText.setText(message);
}
private void showDir(String targetDirectory){
setCurrentPathText("Current Directory: " + currentPath);
targets = new ArrayList<String>();
paths = new ArrayList<String>();
File f = new File(targetDirectory);
File[] directoryContents = f.listFiles();
if (!targetDirectory.equals(root))
{
targets.add(root);
paths.add(root);
targets.add("../");
paths.add(f.getParent());
}
for(File target: directoryContents)
{
paths.add(target.getPath());
if(target.isDirectory())
{
targets.add(target.getName() + "/");
}
else
{
targets.add(target.getName());
}
}
ListView fileBrowserListView = (ListView) findViewById(R.id.file_browser_listview);
ArrayAdapter<String> directoryData = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, targets);
fileBrowserListView.setAdapter(directoryData);
fileBrowserListView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View view, int pos,long id) {
File f = new File(paths.get(pos));
if(f.isFile())
{
targetFile = f;
returnTarget();
//Return target File to activity
}
else
{
//f must be a dir
if(f.canRead())
{
currentPath = paths.get(pos);
showDir(paths.get(pos));
}
}
}
});
}
public void returnTarget()
{
Intent returnIntent = new Intent();
returnIntent.putExtra("file", targetFile);
returnIntent.putExtra("path", currentPath);
setResult(RESULT_OK, returnIntent);
finish();
}
}
Here is the code for MainActivity where the file returned by FileBrowser Activity is send using android beam:
public class MainActivity extends Activity {
private NfcAdapter nfcAdapter;
public final int fileRequestID = 98;
String name;
String[] extension={".png",".docx",".jpeg",".pdf",".doc"};
ArrayList <String>supportedExtension=new ArrayList<String>(Arrays.asList(extension));
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
PackageManager pm = this.getPackageManager();
// Check whether NFC is available on device
if (!pm.hasSystemFeature(PackageManager.FEATURE_NFC)) {
// NFC is not available on the device.
Toast.makeText(this, "The device does not has NFC hardware.",
Toast.LENGTH_SHORT).show();
}
// Check whether device is running Android 4.1 or higher
else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
// Android Beam feature is not supported.
Toast.makeText(this, "Android Beam is not supported.",
Toast.LENGTH_SHORT).show();
}
else {
// NFC and Android Beam file transfer is supported.
Toast.makeText(this, "Android Beam is supported on your device.",
Toast.LENGTH_SHORT).show();
}
}
public void browseForFile(View view) {
Intent clientStartIntent = new Intent(this, FileBrowser.class);
startActivityForResult(clientStartIntent, fileRequestID);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
//fileToSend
boolean filePathProvided;
File fileToSend;
if (resultCode == Activity.RESULT_OK && requestCode == fileRequestID) {
//Fetch result
File targetDir = (File) data.getExtras().get("file");
String path = (String)data.getExtras().get("path");
Log.i("Path=",path);
if(targetDir.isFile())
{
if(targetDir.canRead()) {
try{
String ext=targetDir.getName().substring(targetDir.getName().lastIndexOf("."));
if (supportedExtension.contains(ext)) {
fileToSend = targetDir;
filePathProvided = true;
setTargetFileStatus(targetDir.getName() + " selected for file transfer");
Button btn = (Button) findViewById(R.id.send);
btn.setVisibility(View.VISIBLE);
name = targetDir.getName();
}
else{
Toast.makeText(getApplicationContext(), "File with this extension cannot be printed",
Toast.LENGTH_LONG).show();
}
}catch (Exception e){e.printStackTrace();}
}
else
{
filePathProvided = false;
setTargetFileStatus("You do not have permission to read the file " + targetDir.getName());
}
}
else
{
filePathProvided = false;
setTargetFileStatus("You may not transfer a directory, please select a single file");
}
}
}
public void setTargetFileStatus(String message)
{
TextView targetFileStatus = (TextView) findViewById(R.id.selected_filename);
targetFileStatus.setText(message);
}
public void sendFile(View view) {
nfcAdapter = NfcAdapter.getDefaultAdapter(this);
// Check whether NFC is enabled on device
if(!nfcAdapter.isEnabled()){
Toast.makeText(this, "Please enable NFC.", Toast.LENGTH_SHORT).show();
startActivity(new Intent(Settings.ACTION_NFC_SETTINGS));
}
else if(!nfcAdapter.isNdefPushEnabled()) {
Toast.makeText(this, "Please enable Android Beam.",
Toast.LENGTH_SHORT).show();
startActivity(new Intent(Settings.ACTION_NFCSHARING_SETTINGS));
}
else {
Uri[] mFileUris = new Uri[1];
String fileName=name;
// Retrieve the path to the user's public pictures directory
File fileDirectory = Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File fileToTransfer;
fileToTransfer = new File(fileDirectory, fileName);
fileToTransfer.setReadable(true, false);
mFileUris[0] = Uri.fromFile(fileToTransfer);
nfcAdapter.setBeamPushUris(mFileUris, this);
}
}
}
Now, as you can see in my MainActivity, I am setting my directory as Pictures.
File fileDirectory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
My question is How can I dynamically change my directory every time based on the actual directory value obtained from FileBrowser Activity?
I have already went through the android documentation of How to send files using Android Beam, but didn't find it much useful for my problem. I also went through the android documentation of Environment, but couldn't understand much.
Any help regarding this will really be appreciated. Thanks in advance!
You already have the file selected in OnActivityResult
method. Just change
mFileUris[0] = Uri.fromFile(fileToTransfer);
to
mFileUris[0] = Uri.fromFile(targetDir);