在Android Nougat及更低版本上,我可以使用以下代码简单地在存储中获取一些文件:
Intent chooseFile = new Intent(Intent.ACTION_GET_CONTENT);
chooseFile.setType("*/*.jpg");
chooseFile = Intent.createChooser(chooseFile, "Choose a file");
startActivityForResult(chooseFile, 111);
并使用:
获取文件路径@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 111 && resultCode == RESULT_OK && data.getData() != null)
String path = data.getData().getPath();
}
但是在Android Oreo上,这不起作用。文件选择器正在显示,但是我什至不能使用默认文件选择器来选择文件。起初,我认为这与permission有关。但是,当我在运行时添加了对READ和WRITE外部存储的读取权限并授予该权限后,仍然会出现此问题。
答案 0 :(得分:1)
由于OREO上的默认文件选择器很麻烦,因此目前我正在使用自定义类选择文件或目录。另一个解决方案是您可以使用ES File Explorer等,但并非所有用户都拥有它,并且主要问题仍然发生。
public class FileChooser {
private Activity activity;
private Item[] fileList;
private File path;
private boolean rootDir = true; //check if the current directory is rootDir
private boolean pickFile = true; //flag to get directory or file
private String title = "";
private String upTitle = "Up";
private String positiveTitle = "Choose Path";
private String negativeTitle = "Cancel";
private ListAdapter adapter;
private ArrayList<String> str = new ArrayList<>(); //Stores names of traversed directories, to detect rootDir
private Listener listener;
/**
* @param pickFile true for file picker and false for directory picker
* */
public FileChooser(Activity activity, boolean pickFile, Listener fileChooserListener) {
this.activity = activity;
this.pickFile = pickFile;
this.listener = fileChooserListener;
title = pickFile ? "Choose File" : "Choose Directory";
path = new File(String.valueOf(Environment.getExternalStorageDirectory()));
}
/**
* The view of your file picker
* */
public void openDirectory() {
loadFileList();
AlertDialog.Builder builder = new AlertDialog.Builder(activity, AlertDialog.THEME_DEVICE_DEFAULT_DARK);
if (fileList == null)
builder.create();
builder.setTitle(title + "\n" + path.toString());
builder.setAdapter(adapter, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int position) {
String chosenFile = fileList[position].file;
File selectedFile = new File(path + File.separator + chosenFile);
if (selectedFile.isDirectory()) { // user click on folder
rootDir = false;
str.add(chosenFile); // Adds chosen directory to list
path = selectedFile;
openDirectory();
}
else if (chosenFile.equalsIgnoreCase(upTitle) && !selectedFile.exists()) { // 'up' was clicked
String s = str.remove(str.size() - 1); // present directory
path = new File(
path.toString().substring(0, path.toString().lastIndexOf(s))); // exclude present directory
if (str.isEmpty()) // no more directories in the list, rootDir
rootDir = true;
openDirectory();
}
else if (listener != null && pickFile)
listener.onSelectedPath(selectedFile.getAbsolutePath());
}
});
if (!pickFile) {
builder.setPositiveButton(positiveTitle, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
if (listener != null)
listener.onSelectedPath(path.getPath());
}
});
}
builder.setNegativeButton(negativeTitle, null);
builder.show();
}
/**
* Setup your file picker data
* */
private void loadFileList() {
fileList = null;
if (path.exists()) {
FilenameFilter filter = new FilenameFilter() {
@Override
public boolean accept(File dir, String filename) {
File file = new File(dir, filename);
// Filters based on whether the file is hidden or not
return ((pickFile && file.isFile()) || file.isDirectory()) && !file.isHidden();
}
};
String[] fList = path.list(filter); //set filter
if (fList != null) {
fileList = new Item[fList.length];
for (int i = 0; i < fList.length; i++)
fileList[i] = new Item(fList[i], new File(path, fList[i]).isDirectory() ?
R.drawable.ic_folder : R.drawable.ic_file); //set icon, directory or file
if (!rootDir) {
Item temp[] = new Item[fileList.length + 1];
System.arraycopy(fileList, 0, temp, 1, fileList.length);
temp[0] = new Item(upTitle, R.drawable.ic_undo);
fileList = temp;
}
}
} else
path = new File(String.valueOf(Environment.getExternalStorageDirectory()));
try {
adapter = new ArrayAdapter<Item>(activity,
android.R.layout.select_dialog_item, android.R.id.text1,
fileList) {
@NonNull
@Override
public View getView(int position, View convertView, @NonNull ViewGroup parent) {
// creates view
View view = super.getView(position, convertView, parent);
TextView textView = view.findViewById(android.R.id.text1);
textView.setTextColor(Color.WHITE);
// put the image on the text view
textView.setCompoundDrawablesWithIntrinsicBounds(fileList[position].icon, 0, 0, 0);
// add margin between image and text (support various screen densities)
int dp5 = (int) (5 * activity.getResources().getDisplayMetrics().density + 0.5f);
textView.setCompoundDrawablePadding(dp5);
return view;
}
};
} catch (Exception e) {
e.printStackTrace();
}
}
private class Item {
public String file;
public int icon;
private Item(String file, Integer icon) {
this.file = file;
this.icon = icon;
}
@Override
public String toString() {
return file;
}
}
public interface Listener {
void onSelectedPath(String path);
}
}