androidnfcandroid-external-storageandroid-beam

How to set directory for sending files using Android Beam


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!


Solution

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

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

    to

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