无法在奥利奥上选择文件
Posted
技术标签:
【中文标题】无法在奥利奥上选择文件【英文标题】:Unable to pick file on Oreo 【发布时间】:2018-11-30 08:45:33 【问题描述】:在 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有关。但是当我在运行时添加了对外部存储的读写权限并授予后,这个问题仍然存在。
【问题讨论】:
"The file picker is showing up, but I cannot even pick the file using the default file picker."
为什么不能? onActivityResult()
没有被调用还是什么?或resultCode != RESULT_OK
?
类似于列表视图或按钮,但没有 onClick 方法。我根本无法单击它,并且永远不会调用 onActivityResult。
我不知道你在说什么……什么按钮?什么点击?
按钮和列表视图是隐喻。我只是无法单击设备上的文件(默认)文件选择器
这个问题是因为最近的对话引起的吗?
【参考方案1】:
由于 OREO 上的默认文件选择器很麻烦,目前我正在使用自定义类来选择文件或目录。另一种解决方案是您可以使用 ES 文件资源管理器等,但并非所有用户都拥有它,主要问题仍然存在。
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);
【讨论】:
以上是关于无法在奥利奥上选择文件的主要内容,如果未能解决你的问题,请参考以下文章