Android Studio:获取图库选中图片名称及头像持久化异常修复
问题描述
我开发的Android应用支持Facebook登录,登录后跳转至用户资料页,加载用户的Facebook头像、姓名与邮箱,头像URL存储于SQLite数据库中。应用设置了按钮,可将头像更换为手机外部存储图库中的图片,选中图片后其Uri会覆盖Facebook头像URL。但出现异常:更换头像后退出登录,再次登录时显示的仍是Facebook头像,而非选中的图库图片。我怀疑当前代码未正确获取图片存储路径,打印的路径值不符合模拟器中图片的实际路径(如/storage/emulated/0/DCIM/Camera/image.jpg)。若能获取选中图片的名称,应该可正确将其保存到数据库,并在登录时读取。
相关代码
public class perfil_user extends Fragment { GoogleSignInClient mGoogleSignInClient; ImageView image_user,image_ok,image_edit; TextView name_user,email,tag_date; EditText alias; Button buttonSelectImage,buttonChangeAlias; public String name,facebook_firstname,facebook_lastname,email_facebook,facebook_user_name,str_datefb,str_datejoinedfb,last_season,string_Uri_gmail ; public String date_now,date_joined,last_date,alias_facebook,alias_perfil,get_alias,request_date,alias_perfil_gmail,personGivenName,personFamilyName,personName,personEmail,str_dategmail,str_datejoinedgmail,alias_name,compare_username,alias_gmail; private static int RESULT_LOAD_IMAGE = 1; public static String name_aux,alias_aux; public boolean click; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view=inflater.inflate(R.layout.perfil_user,container,false); image_user=view.findViewById(R.id.image_user); name_user=view.findViewById(R.id.NameUser); email=view.findViewById(R.id.setmail); alias=view.findViewById(R.id.setAlias); buttonSelectImage=view.findViewById(R.id.change_image); buttonChangeAlias = view.findViewById(R.id.change_alias); tag_date=view.findViewById(R.id.last_season_date); DateTimeFormatter datetime_formatter = DateTimeFormatter.ofPattern("HH:mm:ss dd/MM/YYYY"); LocalDateTime now = LocalDateTime.now(); date_now = datetime_formatter.format(now); ConexionSQliteHelper conn=new ConexionSQliteHelper(getContext(),"lala",null,1); buttonSelectImage.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(Intent.ACTION_PICK,MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(intent,3); } }); if ( accessToken != null && !accessToken.isExpired()){ GraphRequest request = GraphRequest.newMeRequest(accessToken, new GraphRequest.GraphJSONObjectCallback() { @Override public void onCompleted(JSONObject object, GraphResponse response) { try { facebook_firstname=object.getString("first_name"); facebook_lastname =object.getString("last_name"); facebook_user_name=object.getString("name"); email_facebook = object.getString("email"); String url_perfil_facebook=object.getJSONObject("picture").getJSONObject("data").getString("url"); if (url_perfil_facebook.equals("")){ url_perfil_facebook = "https://cdn.computerhoy.com/sites/navi.axelspringer.es/public/styles/1200/public/media/image/2017/08/252649-modo-incognito-no-es-seguro-ni-privado.jpg"; } Picasso.get().load(url_perfil_facebook).into(image_user); name_user.setText(facebook_user_name); email.setText(email_facebook); str_datefb = date_now; str_datejoinedfb = date_now; tag_date.setText(str_datefb); boolean exist_user = conn.verifyIfUserExists(email_facebook); if (exist_user) { String url_photo = conn.loadImage(facebook_user_name); Uri myUri = Uri.parse(url_photo); image_user.setImageURI(myUri); alias_perfil = conn.getUserName(email_facebook); alias_facebook = conn.requestAlias(alias_perfil); alias.setText(alias_facebook); String last_season = conn.getLastDateofConnection(facebook_user_name); tag_date.setText(last_season); conn.overwriteDate(date_now,facebook_user_name); } else { alias_name= generateAliasRandom(); conn.insertUser(facebook_user_name,facebook_firstname,facebook_lastname,str_datefb,str_datejoinedfb,alias_name,email_facebook,null,url_perfil_facebook); } name_aux = name_user.getText().toString(); alias_aux = alias.getText().toString(); } catch (JSONException e) { e.printStackTrace(); } } }); Bundle parameters = new Bundle(); parameters.putString("fields","id,first_name,last_name,name,email,link,picture.type(large)"); request.setParameters(parameters); request.executeAsync(); } buttonChangeAlias.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { alias.setFocusableInTouchMode(true); alias.setText(""); alias.setEnabled(true); click = true; alias.setOnKeyListener(new View.OnKeyListener() { public boolean onKey(View v, int keyCode, KeyEvent event) { if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) { alias.setCursorVisible(false); alias.setEnabled(false); alias.setTextColor(Color.BLACK); int id = conn.requestId(name_user.getText().toString()); conn.overwriteAlias(alias.getText().toString(),id); return true; } return false; } }); } }); return view; } private String generateAliasRandom(){ String chars = "0123456789abcdefghijklmnopqrstuvwxyz"; Random random = new Random(); StringBuilder name_alias = new StringBuilder(10); for (int i = 0; i < 10; i++){ name_alias.append(chars.charAt(random.nextInt(chars.length()))); } alias.setText(name_alias); return String.valueOf(name_alias); } @RequiresApi(api = Build.VERSION_CODES.P) @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); ConexionSQliteHelper conn=new ConexionSQliteHelper(getContext(),"lala",null,1); if(resultCode == RESULT_OK && data != null){ Uri selectedImage = data.getData(); image_user.setImageURI(selectedImage); String stringUri = selectedImage.toString(); int id_user = conn.requestId(name_user.getText().toString()); conn.overWriteImage(stringUri,id_user); } } }
解决方案
问题根源
- 头像加载顺序错误:登录回调中先加载Facebook头像,之后才读取数据库中的自定义头像并设置,导致自定义头像被Facebook头像覆盖。
- Uri处理不一致:使用
image_user.setImageURI(myUri)加载本地Uri,而Facebook头像用Picasso加载,且未考虑自定义Uri为空的情况。
修复步骤
1. 调整登录时的头像加载逻辑
优先读取数据库中的自定义头像,只有当数据库中无自定义头像时,才加载Facebook头像:
@Override public void onCompleted(JSONObject object, GraphResponse response) { try { facebook_firstname=object.getString("first_name"); facebook_lastname =object.getString("last_name"); facebook_user_name=object.getString("name"); email_facebook = object.getString("email"); String url_perfil_facebook=object.getJSONObject("picture").getJSONObject("data").getString("url"); if (url_perfil_facebook.equals("")){ url_perfil_facebook = "https://cdn.computerhoy.com/sites/navi.axelspringer.es/public/styles/1200/public/media/image/2017/08/252649-modo-incognito-no-es-seguro-ni-privado.jpg"; } name_user.setText(facebook_user_name); email.setText(email_facebook); str_datefb = date_now; str_datejoinedfb = date_now; tag_date.setText(str_datefb); boolean exist_user = conn.verifyIfUserExists(email_facebook); if (exist_user) { String url_photo = conn.loadImage(facebook_user_name); // 优先加载数据库中的自定义头像 if (url_photo != null && !url_photo.isEmpty()) { Uri myUri = Uri.parse(url_photo); Picasso.get().load(myUri).into(image_user); } else { Picasso.get().load(url_perfil_facebook).into(image_user); } alias_perfil = conn.getUserName(email_facebook); alias_facebook = conn.requestAlias(alias_perfil); alias.setText(alias_facebook); String last_season = conn.getLastDateofConnection(facebook_user_name); tag_date.setText(last_season); conn.overwriteDate(date_now,facebook_user_name); } else { alias_name= generateAliasRandom(); conn.insertUser(facebook_user_name,facebook_firstname,facebook_lastname,str_datefb,str_datejoinedfb,alias_name,email_facebook,null,url_perfil_facebook); Picasso.get().load(url_perfil_facebook).into(image_user); } name_aux = name_user.getText().toString(); alias_aux = alias.getText().toString(); } catch (JSONException e) { e.printStackTrace(); } }
2. 统一Uri加载方式
所有头像加载都使用Picasso,替换image_user.setImageURI(selectedImage)为:
Picasso.get().load(selectedImage).into(image_user);
3. 验证数据库读写逻辑
检查conn.loadImage()和conn.overWriteImage()方法,确保数据库中头像字段的读写正确。可添加日志输出存储和读取的Uri值,确认数据是否正确持久化。
内容的提问来源于stack exchange,提问作者wuad
相关产品推荐
相关产品推荐

