0

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!

Exception
  • 2,273
  • 1
  • 24
  • 42
  • Dont understand the problem. You return "file" and "path" from the picker. So in onActivityResult you know the complete path to the picked file. You only have to use that. You start the picker in /. Why? You could better let it start in the pictures directory. – greenapps Apr 06 '15 at 10:27
  • I must say that it is unclear to me what you want to change dynamically every time. Can you rephrase what you want? – greenapps Apr 06 '15 at 10:31
  • 'returnIntent.putExtra("file", targetFile);'. As targetFile is a File instance i wonder what you put in there? targetFile.getName()? targetFile.getAbsolutePath()? What do you get in onActivityResult? – greenapps Apr 06 '15 at 10:35
  • At current I have hard coded the value of my directory to Pictures, but I don't want that. Instead I want the directory as per the path returned from FileBrowser Activity. – Exception Apr 06 '15 at 10:36
  • That is a useless comment. Please react to the point. And answer already has been given. – greenapps Apr 06 '15 at 10:37
  • The part you are talking about is working fine, just a little clumsy. And I am yet to test the answer. I will update once I test the changes suggested in the answer. – Exception Apr 06 '15 at 10:46
  • 1
    You got two answers already. If you only let the picker return the full path of the chosen file you have enough. You then can use that full path to upload the file. Nowhere there is need to indicate a directory. Think about it. – greenapps Apr 06 '15 at 10:49
  • Thanks!!! I realized it after I got the first answer. I have made the changes just waiting for one more device with NFC to test my app. I really appreciate your help. – Exception Apr 06 '15 at 10:54

1 Answers1

0

You already have the file selected in OnActivityResult method. Just change

mFileUris[0] = Uri.fromFile(fileToTransfer);

to

mFileUris[0] = Uri.fromFile(targetDir);
mromer
  • 1,867
  • 1
  • 13
  • 18