1

I have recently started working on phonegap and i came across a task in which i need to browse for a file from android mobile and display the path of selected file. I've searched alot to achive this in phonegap but all examples i've seen are able to search and upload only images from phone gallery but i want to select any type of file from mobile. As i heard that we can call android native code into phonegap html so i implemented my functionality using native code and here are my Activity classes:

MainActivity.java

public class MainActivity extends Activity implements OnClickListener {

private static final int REQUEST_PICK_FILE = 1;

private TextView mFilePathTextView;
private Button mStartActivityButton;
private File selectedFile;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    mFilePathTextView = (TextView)findViewById(R.id.file_path_text_view);
    mStartActivityButton = (Button)findViewById(R.id.start_file_picker_button);
    mStartActivityButton.setOnClickListener(this);      
}

public void onClick(View v) {
    switch(v.getId()) {
    case R.id.start_file_picker_button:
        Intent intent = new Intent(this, FilePickerActivity.class);
        startActivityForResult(intent, REQUEST_PICK_FILE);
        break;
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if(resultCode == RESULT_OK) {
        switch(requestCode) {
        case REQUEST_PICK_FILE:
            if(data.hasExtra(FilePickerActivity.EXTRA_FILE_PATH)) {
                selectedFile = new File(data.getStringExtra(FilePickerActivity.EXTRA_FILE_PATH));
                mFilePathTextView.setText(selectedFile.getPath());  

            }
        }
    }
}

FilePickerActivity.java

public class FilePickerActivity extends ListActivity {

public final static String EXTRA_FILE_PATH = "file_path";
public final static String EXTRA_SHOW_HIDDEN_FILES = "show_hidden_files";
public final static String EXTRA_ACCEPTED_FILE_EXTENSIONS = "accepted_file_extensions";
private final static String DEFAULT_INITIAL_DIRECTORY = "/";

protected File mDirectory;
protected ArrayList<File> mFiles;
protected FilePickerListAdapter mAdapter;
protected boolean mShowHiddenFiles = false;
protected String[] acceptedFileExtensions;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    LayoutInflater inflator = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View emptyView = inflator.inflate(R.layout.file_picker_empty_view, null);
    ((ViewGroup)getListView().getParent()).addView(emptyView);
    getListView().setEmptyView(emptyView);

    mDirectory = new File(DEFAULT_INITIAL_DIRECTORY);

    mFiles = new ArrayList<File>();

    mAdapter = new FilePickerListAdapter(this, mFiles);
    setListAdapter(mAdapter);

    acceptedFileExtensions = new String[] {};

    if(getIntent().hasExtra(EXTRA_FILE_PATH)) {
        mDirectory = new File(getIntent().getStringExtra(EXTRA_FILE_PATH));
    }
    if(getIntent().hasExtra(EXTRA_SHOW_HIDDEN_FILES)) {
        mShowHiddenFiles = getIntent().getBooleanExtra(EXTRA_SHOW_HIDDEN_FILES, false);
    }
    if(getIntent().hasExtra(EXTRA_ACCEPTED_FILE_EXTENSIONS)) {
        ArrayList<String> collection = getIntent().getStringArrayListExtra(EXTRA_ACCEPTED_FILE_EXTENSIONS);
        acceptedFileExtensions = (String[]) collection.toArray(new String[collection.size()]);
    }
}

@Override
protected void onResume() {
    refreshFilesList();
    super.onResume();
}

protected void refreshFilesList() {
    mFiles.clear();

   ExtensionFilenameFilter filter = new ExtensionFilenameFilter(acceptedFileExtensions);

    File[] files = mDirectory.listFiles(filter);
    if(files != null && files.length > 0) {
        for(File f : files) {
            if(f.isHidden() && !mShowHiddenFiles) {
                continue;
            }

            mFiles.add(f);
        }

        Collections.sort(mFiles, new FileComparator());
    }
    mAdapter.notifyDataSetChanged();
}

@Override
public void onBackPressed() {
    if(mDirectory.getParentFile() != null) {
        mDirectory = mDirectory.getParentFile();
        refreshFilesList();
        return;
    }

    super.onBackPressed();
}

@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
    File newFile = (File)l.getItemAtPosition(position);

    if(newFile.isFile()) {
        Intent extra = new Intent();
        extra.putExtra(EXTRA_FILE_PATH, newFile.getAbsolutePath());
        setResult(RESULT_OK, extra);
         finish();
    } else {
        mDirectory = newFile;
        refreshFilesList();
    }

    super.onListItemClick(l, v, position, id);
}

private class FilePickerListAdapter extends ArrayAdapter<File> {

    private List<File> mObjects;

    public FilePickerListAdapter(Context context, List<File> objects) {
        super(context, R.layout.file_picker_list_item, android.R.id.text1, objects);
        mObjects = objects;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        View row = null;

        if(convertView == null) { 
            LayoutInflater inflater = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            row = inflater.inflate(R.layout.file_picker_list_item, parent, false);
        } else {
            row = convertView;
        }

        File object = mObjects.get(position);

        ImageView imageView = (ImageView)row.findViewById(R.id.file_picker_image);
        TextView textView = (TextView)row.findViewById(R.id.file_picker_text);
        textView.setSingleLine(true);

        textView.setText(object.getName());
        if(object.isFile()) {
            imageView.setImageResource(R.drawable.file);
        } else {
            imageView.setImageResource(R.drawable.folder);
        }

        return row;
    }

}

private class FileComparator implements Comparator<File> {
    public int compare(File f1, File f2) {
        if(f1 == f2) {
            return 0;
        }
        if(f1.isDirectory() && f2.isFile()) {
            return -1;
        }
        if(f1.isFile() && f2.isDirectory()) {
             return 1;
        }
        return f1.getName().compareToIgnoreCase(f2.getName());
    }
}

private class ExtensionFilenameFilter implements FilenameFilter {
    private String[] mExtensions;

    public ExtensionFilenameFilter(String[] extensions) {
        super();
        mExtensions = extensions;
    }

    public boolean accept(File dir, String filename) {
        if(new File(dir, filename).isDirectory()) {
            return true;
        }
        if(mExtensions != null && mExtensions.length > 0) {
            for(int i = 0; i < mExtensions.length; i++) {
                if(filename.endsWith(mExtensions[i])) {
                    return true;
                }
            }
            return false;
        }
        return true;
    }
}

Now i want to use these activities in phonegap html.I've seen some eamples from these sites site1 site2 site3 but not able to get how can i use my activity classes in them. Can anyone please help me how to call my above 2 activity classes in phonegap? I hope my question is clear.

Here are my xml's:

main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
       android:orientation="vertical"
       android:layout_width="fill_parent"
       android:layout_height="fill_parent"
       android:gravity="top">
<Button android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:id="@+id/start_file_picker_button"
    android:text="Browse" />
<TextView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="Selected file"
    android:textStyle="bold"
    android:textColor="#0f894a"
    android:textSize="24sp" />
<TextView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:id="@+id/file_path_text_view"
    android:text="No file has been selected"
    android:textSize="28sp" />
</LinearLayout>

file_view.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="?android:attr/listPreferredItemHeight"

android:padding="6dip">

<ImageView
    android:id="@+id/icon"

    android:layout_width="wrap_content"
    android:layout_height="fill_parent"
    android:layout_marginRight="6dip"

    android:src="@drawable/ic_launcher" />

<LinearLayout
    android:orientation="vertical"

    android:layout_width="0dip"
    android:layout_weight="1"
    android:layout_height="fill_parent">

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="0dip"
        android:layout_weight="1"

        android:gravity="center_vertical"
        android:text="My Application" />

    <TextView  
        android:layout_width="fill_parent"
        android:layout_height="0dip"
        android:layout_weight="1" 

        android:singleLine="true"
        android:ellipsize="marquee"
        android:text="Simple application that shows how to use RelativeLayout" />

</LinearLayout>

file_picker_list_item.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
       android:layout_width="fill_parent"
       android:layout_height="wrap_content"
       android:orientation="horizontal" >
<ImageView
  android:id="@+id/file_picker_image"
  android:layout_width="40dip"
  android:layout_height="40dip"
  android:layout_marginTop="5dip"
  android:layout_marginBottom="5dip"
  android:layout_marginLeft="5dip"
  android:src="@drawable/file"
  android:scaleType="centerCrop"/>
 <TextView
  android:id="@+id/file_picker_text"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:layout_weight="1"
  android:layout_gravity="left|center_vertical"
  android:textSize="24sp"
  android:layout_marginLeft="10dip"
  android:singleLine="true"
  android:text="filename"/>
 </LinearLayout>

file_picker_empty_view.xml

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"
     android:text="No files or directories"
     android:background="@android:drawable/toast_frame"
     android:textSize="24sp"
     android:gravity="center_vertical|center_horizontal"/>
Community
  • 1
  • 1

1 Answers1

0

You need to create a helper class something like:

public class HelperClass extends Plugin implements OnClickListener 

    protected static final String TAG = null;
    private DroidGap mGap;
    public HelperClass(DroidGap gap, WebView view)
    {
        mGap = gap;
    }   
       @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

    mFilePathTextView = (TextView)findViewById(R.id.file_path_text_view);
    mStartActivityButton = (Button)findViewById(R.id.start_file_picker_button);
    mStartActivityButton.setOnClickListener(this);      
}

    public void onClick(View v) {
    switch(v.getId()) {
    case R.id.start_file_picker_button:
        Intent intent = new Intent(this, FilePickerActivity.class);
        startActivityForResult(intent, REQUEST_PICK_FILE);
        break;
    }
}   

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if(resultCode == RESULT_OK) {
            switch(requestCode) {
            case REQUEST_PICK_FILE:
                if(data.hasExtra(FilePickerActivity.EXTRA_FILE_PATH)) {
                    selectedFile = new     File(data.getStringExtra(FilePickerActivity.EXTRA_FILE_PATH));
                    mFilePathTextView.setText(selectedFile.getPath());  

            }
        }
    }
}

@Override
public PluginResult execute(String arg0, JSONArray arg1, String arg2) {
    // TODO Auto-generated method stub
    return null;
}

}

then your main activity needs to be something like:

        public class MainActivity extends DroidGap {
    /** Called when the activity is first created. */
HelperClass cna;
    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);      
    super.init();    
    cna = new HelperClass(this, appView);    
    appView.addJavascriptInterface(cna, "HelperClass");      
    super.loadUrl("file:///android_asset/www/index.html");
    }
}
fasheikh
  • 419
  • 3
  • 19
  • You need to have the phoneGap.js in the assets folder as well as the index.html and style.css. Just remember to add a link to the js and css files in the html file. – fasheikh Aug 10 '12 at 12:08
  • could you please post your xml as those are the only errors i seem to be getting. – fasheikh Aug 13 '12 at 09:14
  • ok basically, the problem is that your layouts should be webpages in the assets folder. – fasheikh Aug 13 '12 at 12:06
  • you should use index.html as your main layout. have you considered doing this without phoneGap? – fasheikh Aug 13 '12 at 12:14
  • ok so give me a brief explanation of exactly what you are trying to do and we can go from there, remember the code will not be the same as native, that's the whole point of phonegap :) – fasheikh Aug 13 '12 at 12:18
  • Have a look [here](http://docs.phonegap.com/en/2.0.0/cordova_file_file.md.html#File), it can be done in plain js and html – fasheikh Aug 13 '12 at 12:29
  • why not just use a webview in the native code? you can specify the URL to download the file from – fasheikh Aug 13 '12 at 12:35
  • sorry i haven't done it myself but the documentation is quite in depth – fasheikh Aug 14 '12 at 10:49
  • yah but the documentation is only sowin ghow to upload an image but not other files. –  Aug 14 '12 at 10:52
  • Where is the `Plugin` class coming from? – muttley91 Jan 26 '14 at 22:25