官方的文件选择器是我感觉功能最强大的,但是选择带回来的uri,需要解析适配,会遇到各种奇奇怪怪的问题
比如从特定目录 或者最近的文件进行选择,竟然无法进行解析,
步入正题
首先是实现任意地方调用,不需要定义onActivityResult也不需要在onCreate调用registerForActivityResult
因此我打算研究其他办法
刚开始我尝试在fragment中的onCreate中写,也一样会抛出RESUMED之后不能进行registerForActivityResult
所以只能弄了一个空的act ,透明的,无感的
xml
<activity android:name="FileChooseAct"
android:launchMode="singleInstance"
android:theme="@android:style/Theme.Translucent.NoTitleBar">
</activity>
act
public class TFileChooseAct extends FragmentActivity {
public static Consumer<Uri> resultCallback;
private static String input;
private Handler handler;
public static void chooseFileByOfficialAPI(FragmentActivity
activity, String input, Consumer<Uri> resultCallback) {
FileChooseAct.resultCallback = resultCallback;
FileChooseAct.input = input;
Intent intent = new Intent(activity, TranslateChooseAct.class);
activity.startActivityForResult(intent, 0);//
}
Runnable action = new Runnable() {
@Override
public void run() {
TranslateChooseAct.resultCallback = null;
TranslateChooseAct.input = null;
}
};
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
handler = new Handler(Looper.getMainLooper());
handler.postDelayed(action, 600 * 60);
ActivityResultLauncher<String> launcher = registerForActivityResult(
new ActivityResultContracts.GetContent(),
new ActivityResultCallback<Uri>() {
@Override
public void onActivityResult(Uri result) {
if (resultCallback == null) {
Toast.makeText(TranslateChooseAct.this, "选择超时", Toast.LENGTH_SHORT).show();
finish();
return;
}
// 处理返回结果
setResult(Activity.RESULT_OK);
finish();
Consumer<Uri> resultCallback1 = resultCallback;
resultCallback1.accept(result);
TranslateChooseAct.resultCallback = null;
TranslateChooseAct.input = null;
}
});
// 发起调用
launcher.launch(input);
}
@Override
protected void onDestroy() {
super.onDestroy();
handler.removeCallbacks(action);
FileChooseAct.resultCallback = null;
FileChooseAct.input = null;
}
}
上面有一些代码可以不用写,比如考虑到可能内存泄露问题,因为传参我目前是只想到了静态,但是使用静态必须销毁,万一不回调了,岂不是内存泄露了,虽然我测试百分百回调,如果取消,则uri为空依然会回调.
用法
chooseFileByOfficialAPI(getThis(), new Consumer<Uri>() {
@Override
public void accept(Uri uri) {}
);
这样侵入性少,但是多创建了一个act,但是兄嘚,没办法为了方便绕过检测只能这么做了.
最后是重中之中,解决兼容性问题,网上流行的代码如下: