Fragment中onActivityResult无法返回文件路径的问题排查
问题:Fragment中调用文件选择Intent后,onActivityResult无日志输出
我正尝试从Android设备中获取选中的文件:点击弹窗中的pasirinktiFaila按钮启动文件选择Intent,之后在Fragment类KorepetitoriuiPatvirtintiMokiniai的onActivityResult方法中,尝试通过Log.d()输出选中文件的路径,但未得到任何结果。已尝试通过按钮点击获取设备文件并打印日志验证,但无结果。
问题原因及解决方案
1. Fragment中启动startActivityForResult的方式错误
你在Adapter中通过((Activity) context).startActivityForResult(intent, 1);直接调用Activity的方法,这样返回的结果会回到宿主Activity,而非Fragment的onActivityResult方法。
修复方案:
通过回调让Fragment自己启动Intent:
- 在Adapter中定义回调接口:
public interface OnFileSelectListener { void onSelectFile(); }
- 修改Adapter构造方法,传入接口实例:
private OnFileSelectListener listener; public KorepetitoriuiPatvirtintiMokiniaiCardAdapter(ArrayList<KorepetitoriuiPatvirtintasMokinysKortele> list, Context context, OnFileSelectListener listener) { this.list = list; this.context = context; this.listener = listener; }
- 在
pasirinktiFaila点击事件中触发回调:
pasirinktiFaila.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { listener.onSelectFile(); } });
- 在Fragment创建Adapter时实现接口,由Fragment启动Intent:
adapter = new KorepetitoriuiPatvirtintiMokiniaiCardAdapter(arrayList, getContext(), new KorepetitoriuiPatvirtintiMokiniaiCardAdapter.OnFileSelectListener() { @Override public void onSelectFile() { Intent intent = new Intent(Intent.ACTION_GET_CONTENT); intent.setType("*/*"); startActivityForResult(intent, 1); } });
2. 静态控件导致的RecyclerView复用问题
你的Card Holder中所有控件都是static修饰符,这会导致RecyclerView的item复用出现混乱——所有item会共用同一个静态控件实例,显示内容错误。
修复方案:去掉static修饰符,改为实例变量:
public class KorepetitoriuiPatvirtintiMokiniaiCardHolder extends RecyclerView.ViewHolder{ public TextView mokinioVardas; public Button parasyti, pridetiMedziaga; public KorepetitoriuiPatvirtintiMokiniaiCardHolder(@NonNull View itemView) { super(itemView); mokinioVardas = itemView.findViewById(R.id.vardasKorteleMokinioPatvirtintas); parasyti = itemView.findViewById(R.id.korepetitoriusParasyti); pridetiMedziaga = itemView.findViewById(R.id.korepetitoriusPridetiMedziaga); } }
同时在Adapter的onBindViewHolder中,通过holder对象访问控件:
holder.mokinioVardas.setText(sarasas.getVardasMokinio()); holder.parasyti.setOnClickListener(...); holder.pridetiMedziaga.setOnClickListener(...);
3. 可选:使用现代Activity Result API替代旧方法
从AndroidX Activity 1.2.0和Fragment 1.3.0开始,推荐使用ActivityResultContracts替代startActivityForResult,避免生命周期问题:
- 在Fragment中注册启动器:
private ActivityResultLauncher<Intent> filePickerLauncher; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); filePickerLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> { if (result.getResultCode() == Activity.RESULT_OK) { Intent data = result.getData(); if (data != null) { Uri uri = data.getData(); String path = uri.getPath(); Log.d("file", path); } } }); }
- 启动文件选择器时调用:
Intent intent = new Intent(Intent.ACTION_GET_CONTENT); intent.setType("*/*"); filePickerLauncher.launch(intent);
原代码
Fragment类
public class KorepetitoriuiPatvirtintiMokiniai extends Fragment { private RecyclerView recyclerView; private ArrayList<KorepetitoriuiPatvirtintasMokinysKortele> arrayList; private KorepetitoriuiPatvirtintiMokiniaiCardAdapter adapter; private TextView emptyRecycler; public KorepetitoriuiPatvirtintiMokiniai() { // Required empty public constructor } public static KorepetitoriuiPatvirtintiMokiniai newInstance() { KorepetitoriuiPatvirtintiMokiniai fragment = new KorepetitoriuiPatvirtintiMokiniai(); Bundle args = new Bundle(); fragment.setArguments(args); return fragment; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_korepetitoriui_patvirtinti_mokiniai, container, false); recyclerView = view.findViewById(R.id.recyclerKorepetitoriuiPatvirtintiMokiniai); recyclerView.setHasFixedSize(true); recyclerView.setLayoutManager(new LinearLayoutManager(this.getContext())); emptyRecycler = view.findViewById(R.id.neraMokiniuKorepetitoriui); arrayList = new ArrayList<KorepetitoriuiPatvirtintasMokinysKortele>(); GautiPatvirtintusMokiniusTask task = new GautiPatvirtintusMokiniusTask(prisijungti.currentKorepetitorius.getId()); task.execute(); return view; } @Override public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if(requestCode == 1 && resultCode == Activity.RESULT_OK) { Uri uri = data.getData(); String path = uri.getPath(); Log.d("file", path); } } public class GautiPatvirtintusMokiniusTask extends AsyncTask<Void, Void, Void> { private int korepetitoriausId; public GautiPatvirtintusMokiniusTask(int korepetitoriausId) { this.korepetitoriausId = korepetitoriausId; } @Override protected Void doInBackground(Void... voids) { try { URL url = new URL("http://192.168.0.104/PHPscriptai/gautiKorepetitoriuiPatvirtintusMokinius.php?korepetitoriaus_id=" + korepetitoriausId); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setRequestProperty("Accept", "application/json"); BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream()))); StringBuilder sb = new StringBuilder(); String output; while ((output = br.readLine()) != null) { sb.append(output); } conn.disconnect(); String jsonString = sb.toString(); JSONArray jsonArray = new JSONArray(jsonString); for (int i = 0; i < jsonArray.length(); i++) { JSONObject obj = jsonArray.getJSONObject(i); String vardasMokinio = obj.getString("pilnas_mokinio_vardas"); int mokinioId = obj.getInt("mokinio_id"); arrayList.add(new KorepetitoriuiPatvirtintasMokinysKortele(vardasMokinio, mokinioId)); } } catch (Exception e) { e.printStackTrace(); } return null; } @Override protected void onPostExecute(Void result) { if (arrayList.isEmpty()) { emptyRecycler.setVisibility(View.VISIBLE); recyclerView.setVisibility(View.GONE); } else { emptyRecycler.setVisibility(View.GONE); recyclerView.setVisibility(View.VISIBLE); adapter = new KorepetitoriuiPatvirtintiMokiniaiCardAdapter(arrayList, getContext()); recyclerView.setAdapter(adapter); } } } }
Adapter类
public class KorepetitoriuiPatvirtintiMokiniaiCardAdapter extends RecyclerView.Adapter<KorepetitoriuiPatvirtintiMokiniaiCardHolder> { private ArrayList<KorepetitoriuiPatvirtintasMokinysKortele> list; private Context context; private Dialog popup; public KorepetitoriuiPatvirtintiMokiniaiCardAdapter(ArrayList<KorepetitoriuiPatvirtintasMokinysKortele> list, Context context) { this.list = list; this.context = context; } @NonNull @Override public KorepetitoriuiPatvirtintiMokiniaiCardHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.korepetitoriaus_mokinys_item, parent, false); return new KorepetitoriuiPatvirtintiMokiniaiCardHolder(view); } @Override public void onBindViewHolder(@NonNull KorepetitoriuiPatvirtintiMokiniaiCardHolder holder, int position) { KorepetitoriuiPatvirtintasMokinysKortele sarasas = list.get(position); popup = new Dialog(context); KorepetitoriuiPatvirtintiMokiniaiCardHolder.mokinioVardas.setText(sarasas.getVardasMokinio()); KorepetitoriuiPatvirtintiMokiniaiCardHolder.parasyti.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(context, susirasyti.class); intent.putExtra("dabartinis_id", prisijungti.currentKorepetitorius.getId()); intent.putExtra("gavejas_id", sarasas.getMokinioId()); context.startActivity(intent); } }); KorepetitoriuiPatvirtintiMokiniaiCardHolder.pridetiMedziaga.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { View popupView = LayoutInflater.from(context).inflate(R.layout.popup_pasirinkti_faila, null); Button pasirinktiFaila = popupView.findViewById(R.id.pasirinktiFailaButton); Button uzdaryti = popupView.findViewById(R.id.uzdarytiIkeltiLanga); EditText pavadinimas = popupView.findViewById(R.id.pavadinimasPopup); Button ikeltiFaila = popupView.findViewById(R.id.ikeltiFaila); pasirinktiFaila.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(Intent.ACTION_GET_CONTENT); intent.setType("*/*"); ((Activity) context).startActivityForResult(intent, 1); } }); ikeltiFaila.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // TODO // upload the file } }); uzdaryti.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { popup.dismiss(); } }); popup = new Dialog(context); popup.setContentView(popupView); popup.show(); } }); } @Override public int getItemCount() { return list.size(); } }
Card Holder类
public class KorepetitoriuiPatvirtintiMokiniaiCardHolder extends RecyclerView.ViewHolder{ public static TextView mokinioVardas; public static Button parasyti, pridetiMedziaga; public KorepetitoriuiPatvirtintiMokiniaiCardHolder(@NonNull View itemView) { super(itemView); mokinioVardas = itemView.findViewById(R.id.vardasKorteleMokinioPatvirtintas); parasyti = itemView.findViewById(R.id.korepetitoriusParasyti); pridetiMedziaga = itemView.findViewById(R.id.korepetitoriusPridetiMedziaga); } }
内容的提问来源于stack exchange,提问作者user19540102
相关产品推荐
相关产品推荐

