Simple Android File ChooserSurprisingly, the Android API doesn't include a file chooser. I'm not sure why that is, I guess the developers don't want to make the assumption that the device has a user filesystem available. Anyway, it's not my job to speculate on what the Android developers talk about over lunch. I just need a file chooser.
It seems like there are a few options out there but I wanted something uber simple and ultra light. It's just for users to select an import file.
My solution is a single Java class utilising regular android Dialog and ListViews. It just wires up the event handlers to read from the disk and refresh the list. You provide a FileSelectedListener implementation to handle the file selection event. Menial stuff that you don't want to bother implementing yourself. It can be used like this:
new FileChooser(activity).setFileListener(new FileSelectedListener() {
@Override public void fileSelected(final File file) {
// do something with the file
}).showDialog();
Here is the FileChooser class which you can cut and paste into your project. Public domain code so do what you want with it.
Peace.
Simple Android File Chooser
package au.com.ninthavenue.patterns.android.dialogs;
import android.app.Activity;
import android.app.Dialog;
import android.os.Environment;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager.LayoutParams;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import java.io.File;
import java.io.FileFilter;
import java.util.Arrays;
public class FileChooser {
private static final String PARENT_DIR = "..";
private final Activity activity;
private ListView list;
private Dialog dialog;
private File currentPath;
// filter on file extension
private String extension = null;
public void setExtension(String extension) {
this.extension = (extension == null) ? null :
extension.toLowerCase();
}
// file selection event handling
public interface FileSelectedListener {
void fileSelected(File file);
}
public FileChooser setFileListener(FileSelectedListener fileListener) {
this.fileListener = fileListener;
return this;
}
private FileSelectedListener fileListener;
public FileChooser(Activity activity) {
this.activity = activity;
dialog = new Dialog(activity);
list = new ListView(activity);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override public void onItemClick(AdapterView<?> parent, View view, int which, long id) {
String fileChosen = (String) list.getItemAtPosition(which);
File chosenFile = getChosenFile(fileChosen);
if (chosenFile.isDirectory()) {
refresh(chosenFile);
} else {
if (fileListener != null) {
fileListener.fileSelected(chosenFile);
}
dialog.dismiss();
}
}
});
dialog.setContentView(list);
dialog.getWindow().setLayout(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
refresh(Environment.getExternalStorageDirectory());
}
public void showDialog() {
dialog.show();
}
/**
* Sort, filter and display the files for the given path.
*/
private void refresh(File path) {
this.currentPath = path;
if (path.exists()) {
File[] dirs = path.listFiles(new FileFilter() {
@Override public boolean accept(File file) {
return (file.isDirectory() && file.canRead());
}
});
File[] files = path.listFiles(new FileFilter() {
@Override public boolean accept(File file) {
if (!file.isDirectory()) {
if (!file.canRead()) {
return false;
} else if (extension == null) {
return true;
} else {
return file.getName().toLowerCase().endsWith(extension);
}
} else {
return false;
}
}
});
// convert to an array
int i = 0;
String[] fileList;
if (path.getParentFile() == null) {
fileList = new String[dirs.length + files.length];
} else {
fileList = new String[dirs.length + files.length + 1];
fileList[i++] = PARENT_DIR;
}
Arrays.sort(dirs);
Arrays.sort(files);
for (File dir : dirs) { fileList[i++] = dir.getName(); }
for (File file : files ) { fileList[i++] = file.getName(); }
// refresh the user interface
dialog.setTitle(currentPath.getPath());
list.setAdapter(new ArrayAdapter(activity,
android.R.layout.simple_list_item_1, fileList) {
@Override public View getView(int pos, View view, ViewGroup parent) {
view = super.getView(pos, view, parent);
((TextView) view).setSingleLine(true);
return view;
}
});
}
}
/**
* Convert a relative filename into an actual File object.
*/
private File getChosenFile(String fileChosen) {
if (fileChosen.equals(PARENT_DIR)) {
return currentPath.getParentFile();
} else {
return new File(currentPath, fileChosen);
}
}
}
About Roger Keays
|
Roger Keays is an artist, an engineer, and a student of life. He has no fixed address and has left footprints on 40-something different countries around the world. Roger is addicted to surfing. His other interests are music, psychology, languages, the proper use of semicolons, and finding good food.
|
Hey Man. I would really love if I could implement this into my project. I'm a complete noob and could use some extra help. Does the entire script go into mainactivity.java?.. and where exactly?
When you understand the following trick, you may ignore everything else:
Like my page http://www.facebook.com/atramegadynamics/
public int REQCODE_SAVEFILE_ = 0; //make this special
public void openFile_(){
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");
//intent.putExtra(Intent.EXTRA_MIME_TYPES, "*/*");
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
startActivityForResult(intent, REQCODE_OPENFILE);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQCODE_SAVEFILE_) {
if (resultCode == Activity.RESULT_OK && data != null) {
Uri file_uri = data.getData();
//Globals.saveFile(file_uri, getAll_ringItems(), the_context);//this.getApplicationContext());
}
}
}
public static boolean saveFile(Uri file_uri, String data, Context context){
try {
android.os.ParcelFileDescriptor pfd = context.getContentResolver().openFileDescriptor(file_uri, "w");
java.io.FileOutputStream fos = new java.io.FileOutputStream( pfd.getFileDescriptor() );
fos.write(data.getBytes());
fos.close();
fos.flush();
pfd.close();
return true;
} catch (Exception e) {
//Toast.makeText(context.getApplicationContext(), e.getMessage(),Toast.LENGTH_SHORT);
}
return false;
}
Hello friends. I updated the file to cater for more feature. \
[code]
package com.atramega.schbell;
import android.Manifest;
import android.app.Dialog;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.os.Environment;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager.LayoutParams;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TableLayout;
import android.widget.TextView;
import android.widget.Toast;
import java.io.File;
import java.io.FileFilter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class FileChooser {
private static final String PARENT_DIR = "..";
private Context the_context;
private ListView listView;
private Dialog dialog;
private File currentPath;
private String title = "Choose File";
private boolean dirsOnly = false;
private boolean canShow = true;
private boolean excludeDotPrefixDirs = false;
private boolean excludeDotPrefixFiles = false;
private String extension = null;
private FileChosenListener fileChosenListener;
public interface FileChosenListener {
void onFileChosen(File file);
}
public FileChooser setFileChosenListener(FileChosenListener fileChosenListener) {
this.fileChosenListener = fileChosenListener;
return this;
}
public FileChooser(final Context context){
this.the_context = context;
dialog = new Dialog( context );
listView = new ListView(context);
dialog.setContentView(listView );
dialog.getWindow().setLayout(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
if( (ContextCompat.checkSelfPermission(the_context, Manifest.permission.READ_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED)
|| (ContextCompat.checkSelfPermission(the_context, Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED) ){
String msg = "First setup Storage permissions in Settings - Apps - "+the_context.getString(R.string.app_name)+" - permissions";
Toast.makeText(the_context, msg, Toast.LENGTH_LONG);
Toast.makeText(the_context, msg, Toast.LENGTH_LONG);
Toast.makeText(the_context, msg, Toast.LENGTH_LONG);
canShow = false;
}
}
public void setExtension(String extension) {
this.extension = (extension == null) ? null :
extension.toLowerCase();
}
public void setDirsOnly(boolean val){
this.dirsOnly = val;
}
public void excludeDotPrefixDirs(boolean val){
this.excludeDotPrefixDirs = val;
}
public void excludeDotPrefixFiles(boolean val){
this.excludeDotPrefixFiles = val;
}
public void setTitle(String title){
this.title = title;
}
public void showDialog() {
if(canShow){
refresh(Environment.getExternalStoragePublicDirectory(""));
dialog.show();
}
}
private File[] getDirsUnder(File path){
File[] dirs = path.listFiles(new FileFilter() {
@Override public boolean accept(File file) {
return (file.isDirectory() );//&& file.canRead());
}
});
return dirs;
}
private File[] getFilesUnder(File path){
File[] files = path.listFiles(new FileFilter() {
@Override public boolean accept(File file) {
if (!file.isDirectory()) {
//if (!file.canRead()) {return false;} else
if (extension == null) {
return true;
} else {
return file.getName().toLowerCase().endsWith(extension);
}
} else {
return false;
}
}
});
return files;
}
/**
* Sort, filter and display the files for the given path.
*/
private void refresh(File path) {
this.currentPath = path;
if (path.exists()) {
File[] dirs = getDirsUnder(path);
File[] files = getFilesUnder(path);
Arrays.sort(dirs);
Arrays.sort(files);
ArrayList<File> fileList = new ArrayList<>();
fileList.add(null); //item 0 for the heading
if(path.getParentFile() != null && path.getParentFile().canRead()) { //this parrent be used used as item 1
fileList.add( path.getParentFile() );
} else {
fileList.add(null); //item 1 does no
}
for (File dir : dirs) {
if( !(excludeDotPrefixDirs && dir.getName().startsWith(".")) ){ fileList.add(dir); }
}
if(!dirsOnly){
for (File file : files ) {
if( !(excludeDotPrefixFiles && file.getName().startsWith(".")) ){ fileList.add(file); }
}
}
listView.setBackgroundColor(the_context.getColor(R.color.atramegaLightGray));
listView.setAdapter(new FileArrayAdapter(the_context, 0, fileList));
}
}
/**
* Convert a relative filename into an actual File object.
*/
private File getChosenFile(String fileChosen) {
if (fileChosen.equals(PARENT_DIR)) {
return currentPath.getParentFile();
} else {
return new File(currentPath, fileChosen);
}
}
//custom ArrayAdapter
public class FileArrayAdapter extends ArrayAdapter<File> {
public Context context;
public List<File> myFileList;
public FileArrayAdapter(Context contex, int resourc, ArrayList<File> myFileLis) {
super(contex, resourc, myFileLis);
this.context = contex;
this.myFileList = myFileLis;
}
//called when rendering the list
public View getView(final int position, final View convertView, ViewGroup parent) {
LinearLayout linearLayout = new LinearLayout(the_context);
linearLayout.setOrientation( LinearLayout.HORIZONTAL );
linearLayout.setPadding(10, 10, 5, 5);
linearLayout.setDividerPadding(5);
////////////////////////
TextView name_textView = new TextView(the_context);
name_textView.setTextColor( the_context.getColor(R.color.atramegaBlack) );
name_textView.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START);
name_textView.setHeight(40);
name_textView.setTextSize(18);
///////////////////////////
ImageView dir_imageButton = new ImageView(the_context);
dir_imageButton.setImageDrawable( the_context.getDrawable(android.R.drawable.sym_contact_card) );
dir_imageButton.setVisibility( View.INVISIBLE );
////////////////////////////////
ImageView file_imageButton = new ImageView(the_context);
file_imageButton.setImageDrawable( the_context.getDrawable(android.R.drawable.stat_notify_chat) );
file_imageButton.setPadding(10, 0, 0, 0);
file_imageButton.setVisibility( View.GONE );
////////////////////////////////
linearLayout.addView(dir_imageButton);
linearLayout.addView(file_imageButton);
linearLayout.addView(name_textView);
//////////////////////////////
if(position==0) { //heading
name_textView.setText(title);
name_textView.setTextAlignment( View.TEXT_ALIGNMENT_CENTER );
name_textView.setTextColor(the_context.getColor(R.color.atramegaWhite));
linearLayout.setBackgroundColor(the_context.getColor(R.color.atramegaBlue));
return linearLayout;
} else { //directories and files
if( null != myFileList.get(position)) {
final File fileItem = myFileList.get(position);
name_textView.setText( " "+fileItem.getName() );
if (fileItem.isDirectory()) {
if (position == 1) { //parent directory
name_textView.setTextColor(the_context.getColor(R.color.atramegaBlue) );
linearLayout.setBackgroundColor(the_context.getColor(R.color.atramegaLightBlue));
} else { //other directories
dir_imageButton.setVisibility( View.VISIBLE );
file_imageButton.setVisibility( View.GONE );
}
} else { //files
dir_imageButton.setVisibility( View.GONE );
file_imageButton.setVisibility( View.VISIBLE );
}
if(!fileItem.canRead()) {
name_textView.setTextColor( the_context.getColor(R.color.atramegaGray));
linearLayout.setEnabled(false);
}
linearLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (fileItem.isDirectory()) {
refresh(fileItem);
} else {
if (fileChosenListener != null) {
fileChosenListener.onFileChosen(fileItem);
}
dialog.dismiss();
}
}
});
if (dirsOnly && fileItem.isDirectory()) {
linearLayout.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
if (fileChosenListener != null) {
fileChosenListener.onFileChosen(fileItem);
}
dialog.dismiss();
return false;
}
});
}
} else {
linearLayout.removeAllViews();
File[] dirs = context.getExternalFilesDirs(null);
String[] names = {"Internal Storage", "SD Card", "External Storage 2"}; int i = 0;
for( File dir: dirs) {
while(null != dir.getParentFile() && dir.getParentFile().canRead()) {
dir = dir.getParentFile();
}
final File the_dir = dir;
Button button = new Button(the_context);
try {
button.setText( names[i++] );
}catch (IndexOutOfBoundsException iobe){}finally {}
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
refresh(the_dir);
}
});
linearLayout.addView(button);
}
return linearLayout;
}
return linearLayout;
}
}
}
}
/*
FileChooser fc = new FileChooser( the_context );
fc.setTitle("Choose a File");
fc.excludeDotPrefixDirs(true);
fc.excludeDotPrefixFiles(true);
fc.setFileChosenListener(new FileChooser.FileChosenListener() {
@Override
public void onFileChosen(final File chosenFile) {
fillFromString( Globals.readFile(chosenFile) );
}
});
fc.showDialog();
*/
[/code]
Hello. Thanks a lot to every one. After going through the main post and one advice, i have come up with the following for those who want to pass context instead of activity. I found this important since I was using a fragment
package _YOUR PACKAGE_;
import android.app.Activity;
import android.app.Dialog;
import android.app.TimePickerDialog;
import android.content.Context;
import android.graphics.Color;
import android.os.Environment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager.LayoutParams;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.TimePicker;
import java.io.File;
import java.io.FileFilter;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;
public class FileChooser {
private static final String PARENT_DIR = "..";
private Context the_context;
private ListView list;
private Dialog dialog;
private File currentPath;
// filter on file extension
private String extension = null;
public void setExtension(String extension) {
this.extension = (extension == null) ? null :
extension.toLowerCase();
}
// file selection event handling
public interface FileSelectedListener {
void fileSelected(File file);
}
public FileChooser setFileListener(FileSelectedListener fileListener) {
this.fileListener = fileListener;
return this;
}
private FileSelectedListener fileListener;
public FileChooser(Context context){
this.the_context = context;
dialog = new Dialog( context );
list = new ListView(context);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String fileChosen = (String) list.getItemAtPosition(position);
File chosenFile = getChosenFile(fileChosen);
if (chosenFile.isDirectory()) {
refresh(chosenFile);
} else {
if (fileListener != null) {
fileListener.fileSelected(chosenFile);
}
dialog.dismiss();
}
}
});
dialog.setContentView(list);
dialog.getWindow().setLayout(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
refresh( Environment.getRootDirectory() );//getExternalStorageDirectory( ) );
}
public void showDialog() {
dialog.show();
}
private File[] getDirsUnder(File path){
File[] dirs = path.listFiles(new FileFilter() {
@Override public boolean accept(File file) {
return (file.isDirectory() && file.canRead());
}
});
return dirs;
}
private File[] getFilesUnder(File path){
File[] files = path.listFiles(new FileFilter() {
@Override public boolean accept(File file) {
if (!file.isDirectory()) {
if (!file.canRead()) {
return false;
} else if (extension == null) {
return true;
} else {
return file.getName().toLowerCase().endsWith(extension);
}
} else {
return false;
}
}
});
return files;
}
/**
* Sort, filter and display the files for the given path.
*/
private void refresh(File path) {
this.currentPath = path;
if (path.exists()) {
File[] dirs = getDirsUnder(path);
File[] files = getFilesUnder(path);
Arrays.sort(dirs);
Arrays.sort(files);
// convert to an array
int i = 0;
String[] fileList;
if (path.getParentFile() == null || !path.getParentFile().canRead()) {
fileList = new String[dirs.length + files.length];
} else {
fileList = new String[dirs.length + files.length + 1];
fileList[i++] = PARENT_DIR;
}
for (File dir : dirs) { fileList[i++] = dir.getName(); }
for (File file : files ) { fileList[i++] = file.getName(); }
// refresh the user interface
dialog.setTitle(currentPath.getPath());
list.setAdapter( new ArrayAdapter(the_context,
android.R.layout.simple_list_item_1, fileList) {
@Override public View getView(int pos, View view, ViewGroup parent) {
view = super.getView(pos, view, parent);
((TextView) view).setSingleLine(true);
return view;
}
});
}
}
/**
* Convert a relative filename into an actual File object.
*/
private File getChosenFile(String fileChosen) {
if (fileChosen.equals(PARENT_DIR)) {
return currentPath.getParentFile();
} else {
return new File(currentPath, fileChosen);
}
}
}
You can contact me on Facebook www.facebook.com/atramegadynamics/
aa首席阿里巴巴zzzzzzzzzzz
First of all, thans very much for your sharing, it is very helpful.
But, in the very first dialog display, first list item with ".." should not appear, because we can not ask parent of root to list files.
If one tap on this ".." item, device will crash.
So I suggest make following fix in refresh():
replace
if (path.getParentFile() == null) {
fileList = new String[dirs.length + files.length];
} else {
fileList = new String[dirs.length + files.length + 1];
fileList[i++] = PARENT_DIR;
}
with
if (path.getParentFile() == null || !path.getParentFile().canRead()) {
fileList = new String[dirs.length + files.length];
} else {
fileList = new String[dirs.length + files.length + 1];
fileList[i++] = PARENT_DIR;
}
Hi, My name is Jeff, I work as a Internet Marketing Consultant, and was doing research for another client when I came across your site rogerkeays.com. and thought I would message you on your contact form.
After doing a quick analysis of your website, I noticed a couple of issues that are most likely causing people to leave without making contact.
I really liked your website but noticed you weren't getting a lot of traffic to your site and your Alexa ranking wasn't as strong as it could be.
http://OnTargetSEO.us
I can get 1,000’s of visitors looking at rogerkeays.com, ready to buy your product, service or signup for your offer. Our advertising network of over 9000 websites provides a low cost and effective online marketing solution that actually works. We can help your business get more online quality traffic by advertising your business on websites that are targeted to your market.
The internet is a vast entity and kick starting your online business doesn’t have to take a ridiculous amount of cash.
We’ll send real people to see your web site starting almost immediately!
In fact, I can get 10,000 highly targeted visitors to your website for as little as $29 just so you can test out our service.
Right now to make things really exciting you can get 200,000 Targeted visitors to you site in 30 days for only $199. If you'd like to talk personally please give me a call at 480-457-0165 9 to 5 MST USA.
I have a short video here that explains how everything works http://OnTargetSEO.us
Best Regards,
Jeff
http://OnTargetSEO.us
1st time that i just copy/paste sth and its work ! thanks a lot
I made a few tweaks, because the original method was a bit unreadable and called path.listFiles() twice for no apparent reason:
if (path.exists() && path.canRead()) {
// find em all
TreeSet<String> dirs = new TreeSet<>();
TreeSet<String> files = new TreeSet<>();
for(File file : path.listFiles()) {
if(!file.canRead())
continue;
if(file.isDirectory()) {
dirs.add(file.getName());
} else {
if(extension == null || file.getName().toLowerCase().endsWith(extension))
files.add(file.getName());
}
}
// convert to an array
ArrayList<String> fileList = new ArrayList<>(dirs.size() + files.size());
if (path.getParentFile() != null)
fileList.add(PARENT_DIR);
fileList.addAll(dirs);
fileList.addAll(files);
// refresh the user interface
dialog.setTitle(currentPath.getPath());
list.setAdapter(new ArrayAdapter<String>(activity, android.R.layout.simple_list_item_1, fileList) {
@Override public View getView(int pos, View view, ViewGroup parent) {
view = super.getView(pos, view, parent);
((TextView) view).setSingleLine(true);
return view;
}
});
} else {
list.setAdapter(new ArrayAdapter<>(activity, android.R.layout.simple_list_item_1, new String[]{"Can't access "+path}));
}
Oh and by the way, you should address the new permission issues with Android 6.0
Brian Young,
have you got this in manifest?
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Nice! Really help me.
Many thanks for this topic!
Ai uitat o acolada pisa-m-as pe mortii matii
Just had to say:
Thank you for sharing, helped me a lot.
Well, just to say thanks.
Simple and efficient
Hey @Robot Maxwell. Thanks for the patch. It looks like path.listFiles() is returning null in your case. The javadoc says "The array will be empty if the directory is empty. Returns null if this abstract pathname does not denote a directory, or if an I/O error occurs."
So I think this code should work if the directory is empty, but will probably crash if Environment.getExternalStorageDirectory() does not return a valid directory. What happens if you change:
if (path.exists()) {
to
if (path.exists() && path.isDirectory()) {
?
Roger you have a nasty error in your code, when the sdcard is "empty" it will crash. I had to bolster it up with a bit of checking thus:
~ // convert to an array
int i = 0;
int j = 0;
int k = 0;
if(dirs!=null && dirs.length>0)
j = dirs.length;
if(files!=null && files.length>0)
k = files.length;
String[] fileList;
if (path.getParentFile() == null) {
fileList = new String[j + k];
} else {
//fileList = new String[dirs.length + files.length + 1];
fileList = new String[j + k + 1];
fileList[i++] = PARENT_DIR;
}
if(dirs!=null && dirs.length>0) {
Arrays.sort(dirs);
for (File dir : dirs) { fileList[i++] = dir.getName(); }}
if(files!=null && files.length>0){
Arrays.sort(files);
for (File file : files ) { fileList[i++] = file.getName(); }}
Really Useful code for many Android Developers.
Great step by step solution, thanks for the help!
Great! Thanks alot you save my time!
Marthono, it gave the same error to me. Just substitute this line:
FileChooser(this.getParent())
with this:
FileChooser(this)
and it worked for me.
it gives error :
06-15 03:43:31.038 24606-24606/on4shop.androidapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: on4shop.androidapp, PID: 24606
java.lang.IllegalStateException: Could not execute method for android:onClick
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:293)
at android.view.View.performClick(View.java:4438)
at android.view.View$PerformClick.run(View.java:18422)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5001)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
at android.view.View.performClick(View.java:4438)
at android.view.View$PerformClick.run(View.java:18422)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5001)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at on4shop.androidapp.DialogClassCollection.clsSaveFileDialog.refresh(clsSaveFileDialog.java:99)
at on4shop.androidapp.DialogClassCollection.clsSaveFileDialog.<init>(clsSaveFileDialog.java:62)
at on4shop.androidapp.frm_file_act.WriteExternalFile(frm_file_act.java:67)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
at android.view.View.performClick(View.java:4438)
at android.view.View$PerformClick.run(View.java:18422)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5001)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)
Hey Brian, the stack trace might tell you if this.getParent() is the cause of the problem. Couldn't you just use 'this'?
I'm trying to use your file picker to pick a file for the XML parser to parse... I have the FileChooser Class and everything compiling, but my APP blows up when I include this code to present the file chooser. I only pick an XML file to parse on the initial startup of the app. It's likely the "this.getParent()" to get the activity, but I cannot be sure.
public class XMLPullParserActivity extends Activity {
...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
if (savedInstanceState != null) {
...
} else {
new FileChooser(this.getParent()).setFileListener(new FileChooser.FileSelectedListener() {
@Override public void fileSelected(final File file) {
// do something with the file
Application application=(Application)CBA_Application.getContext();
CBA_Application app = (CBA_Application)application;
Context context=getApplicationContext();
CharSequence mytext;
Integer myduration;
Toast mytoast;
mytext = "Root Directory for selected File " + file.getAbsolutePath();
myduration = Toast.LENGTH_LONG;
mytoast = Toast.makeText(context,mytext,myduration);
mytoast.show();
}}).showDialog();
...
Thanks .. that made my life easy .. Made a few minor tweaks.. but I had some issues with the extensions. So, since I know what the extension is ahead of time, I just added it to the construction methods. I could add multiple extension filters on... your skeleton was what I really needed.. So, I use it like
private void processFile(){
filechooser = new FileChooser(ImportActivity.this);
filechooser.setFileListener(new FileChooser.FileSelectedListener() {
@Override
public void fileSelected(final File file) {
// ....do something with the file
String filename = file.getAbsolutePath();
Log.d("File", filename);
// then actually do something in another module
}
});
// Set up and filter my extension I am looking for
filechooser.setExtension("pdf");
filechooser.showDialog();
}
Hello, i already have a button in main activity to access this class, how i implement my button actionListener with this class?
Hi,
Thank you. This is absolutely brilliant and saved me a lot of time.
I noticed one issue with the processing order. When using "setExtension", the "refresh" method is not called. This results in the first screen displaying all file formats not just directories and the designated extension.
Thank you once again
I don't understand with this part:
// do something with the file
can you give me an example what i can do with that line?
How do i implement the class within a button click of another class
Hi Roger,
Thank you so much for this code... I am so thankful that you allow this code to be used on our projects.