- 浏览: 30220 次
- 性别:
- 来自: 泸州市
Android之修改用户头像并上传服务器(实现手机拍照和SD卡选择上传)
写了这么多个的APP,最近才把他这个功能写上来,就抽取其中的用户修改头像的相关操作这个功能写了这篇博客,来与大家分享,希望对你有所帮助。
案例包含了:
- Xutil图片上传
- 拍照和SD卡选择图片
- 图片缓存和界面逻辑处理
- 图片压缩和图片处理
- 自定义圆形头像
其他图片上传方式请看博客 :Volley-XUtils-OkHttp三种方式实现单张多张图片上传
效果图: (注:模拟器没拍照功能,效果图只有SD卡上传,手机测试拍照上传也是可以的)
代码:
MainActivity.java
public class MainActivity extends AppCompatActivity implements View.OnClickListener { ZQRoundOvalImageView zqRoundOvalImageView; ACache aCache; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); zqRoundOvalImageView = (ZQRoundOvalImageView) findViewById(R.id.my_sign_sub_img); zqRoundOvalImageView.setOnClickListener(this); findViewById(R.id.my_sign_sub_txt).setOnClickListener(this); aCache = ACache.get(MainActivity.this); initData(); } private void initData() { if (UtilFileDB.SELETEFile(aCache, "stscimage") != null) { if (aCache.getAsBitmap("myimg") == null) { getImage(UtilFileDB.LOGINIMGURL(aCache)); } else { zqRoundOvalImageView.setImageBitmap(aCache.getAsBitmap("myimg")); } } } @Override public void onClick(View v) { switch (v.getId()) { case R.id.my_sign_sub_img: case R.id.my_sign_sub_txt: Intent intents = new Intent(MainActivity.this, SettingActivity.class); startActivityForResult(intents, 1); break; } } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == 1) { if (resultCode == 3) { getImage(data.getStringExtra("urlimg")); } else { zqRoundOvalImageView.setImageResource(R.mipmap.zhangwo_hometop1); } } } public void getImage(String url) { UtilFileDB.DELETEFile(aCache, "myimg"); OkHttpUtils.get().url(url).tag(this).build().connTimeOut(20000) .readTimeOut(20000).writeTimeOut(20000) .execute(new BitmapCallback() { @Override public void onError(Call call, Exception e, int id) { } @Override public void onResponse(Bitmap bitmap, int id) { zqRoundOvalImageView.setImageBitmap(bitmap); aCache.put("myimg", bitmap); } }); } }
SettingActivity.Java
public class SettingActivity extends AppCompatActivity implements View.OnClickListener { String URL = "url"; TextView homeTopName; ZQRoundOvalImageView zqRoundOvalImageView; PopupWindow pop; LinearLayout ll_popup; Intent intent; String urlsf = ""; int img = 1; ACache aCache; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.my_setting); initView(); } private void initView() { homeTopName = (TextView) findViewById(R.id.home_top_name); homeTopName.setText("设置"); aCache = ACache.get(SettingActivity.this); zqRoundOvalImageView = (ZQRoundOvalImageView) findViewById(R.id.my_setting_txlehs); zqRoundOvalImageView.setOnClickListener(this); findViewById(R.id.home_tour_close).setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.my_setting_txlehs: showPopupWindow(); ll_popup.startAnimation(AnimationUtils.loadAnimation( SettingActivity.this, R.anim.activity_translate_in)); pop.showAtLocation(v, Gravity.BOTTOM, 0, 0); break; case R.id.home_tour_close: intent = new Intent(); intent.putExtra("urlimg", urlsf); setResult(img, intent); finish(); break; } } /**** * 头像提示框 */ public void showPopupWindow() { pop = new PopupWindow(SettingActivity.this); View view = getLayoutInflater().inflate(R.layout.item_popupwindows, null); ll_popup = (LinearLayout) view.findViewById(R.id.ll_popup); pop.setWidth(ViewGroup.LayoutParams.MATCH_PARENT); pop.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT); pop.setBackgroundDrawable(new BitmapDrawable()); pop.setFocusable(true); pop.setOutsideTouchable(true); pop.setContentView(view); RelativeLayout parent = (RelativeLayout) view.findViewById(R.id.parent); Button bt1 = (Button) view.findViewById(R.id.item_popupwindows_camera); Button bt2 = (Button) view.findViewById(R.id.item_popupwindows_Photo); Button bt3 = (Button) view.findViewById(R.id.item_popupwindows_cancel); parent.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { pop.dismiss(); ll_popup.clearAnimation(); } }); bt1.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { Intent camera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(camera, 1); pop.dismiss(); ll_popup.clearAnimation(); } }); bt2.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { Intent picture = new Intent( Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(picture, 2); pop.dismiss(); ll_popup.clearAnimation(); } }); bt3.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { pop.dismiss(); ll_popup.clearAnimation(); } }); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == 1 && resultCode == Activity.RESULT_OK && null != data) { String sdState = Environment.getExternalStorageState(); if (!sdState.equals(Environment.MEDIA_MOUNTED)) { return; } new DateFormat(); String name = DateFormat.format("yyyyMMdd_hhmmss", Calendar.getInstance(Locale.CHINA)) + ".jpg"; Bundle bundle = data.getExtras(); // 获取相机返回的数据,并转换为图片格式 Bitmap bmp = (Bitmap) bundle.get("data"); FileOutputStream fout = null; String filename = null; try { filename = UtilImags.SHOWFILEURL(SettingActivity.this) + "/" + name; } catch (IOException e) { } try { fout = new FileOutputStream(filename); bmp.compress(Bitmap.CompressFormat.JPEG, 100, fout); } catch (FileNotFoundException e) { showToastShort("上传失败"); } finally { try { fout.flush(); fout.close(); } catch (IOException e) { showToastShort("上传失败"); } } zqRoundOvalImageView.setImageBitmap(bmp); staffFileupload(new File(filename)); } if (requestCode == 2 && resultCode == Activity.RESULT_OK && null != data) { try { Uri selectedImage = data.getData(); String[] filePathColumns = {MediaStore.Images.Media.DATA}; Cursor c = this.getContentResolver().query(selectedImage, filePathColumns, null, null, null); c.moveToFirst(); int columnIndex = c.getColumnIndex(filePathColumns[0]); String picturePath = c.getString(columnIndex); c.close(); Bitmap bmp = BitmapFactory.decodeFile(picturePath); // 获取图片并显示 zqRoundOvalImageView.setImageBitmap(bmp); saveBitmapFile(UtilImags.compressScale(bmp), UtilImags.SHOWFILEURL(SettingActivity.this) + "/stscname.jpg"); staffFileupload(new File(UtilImags.SHOWFILEURL(SettingActivity.this) + "/stscname.jpg")); } catch (Exception e) { showToastShort("上传失败"); } } } public void saveBitmapFile(Bitmap bitmap, String path) { File file = new File(path);//将要保存图片的路径 try { BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file)); bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos); bos.flush(); bos.close(); } catch (IOException e) { e.printStackTrace(); } } public void staffFileupload(File file) { if (false) { showToastShort("网络未连接"); return; } HttpUtils http = new HttpUtils(); http.send(HttpRequest.HttpMethod.POST, URL, MYUPDATEIMG(file), new RequestCallBack<String>() { @Override public void onFailure(HttpException arg0, String arg1) { } @Override public void onSuccess(ResponseInfo<String> arg0) { JSONObject jsonobj; try { jsonobj = new JSONObject(arg0.result.toString()); String errno = jsonobj.getString("errno"); String error = jsonobj.getString("error"); if (errno.equals("0") && error.equals("success")) { JSONArray jsonarray = jsonobj.getJSONArray("data"); JSONObject jsonobjq = jsonarray.getJSONObject(0); urlsf = jsonobjq.getString("url"); UtilFileDB.ADDFile(aCache, "stscimage", urlsf); img = 3; showToastShort("头像修改成功"); } else { showToastShort("头像修改失败"); } } catch (JSONException e) { return; } } }); } /*** * 修改头像 * * @return */ public static final RequestParams MYUPDATEIMG(File file) { RequestParams params = new RequestParams(); params.addBodyParameter("c", "profile"); params.addBodyParameter("a", "setavatar"); params.addBodyParameter("uid", ""); params.addBodyParameter("username", ""); if (file != null) { params.addBodyParameter("filedata", file); } return params; } private void showToastShort(String string) { Toast.makeText(SettingActivity.this, string, Toast.LENGTH_LONG).show(); } }
AndroidManifest.xml权限
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- SD卡权限 --> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /> <!-- 定位 --> <!-- 用于进行网络定位 --> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" > </uses-permission> <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"> </uses-permission> <!-- 用于访问wifi网络信息,wifi信息会用于进行网络定位 --> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" > </uses-permission> <!-- 这个权限用于获取wifi的获取权限,wifi信息会用来进行网络定位 --> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" > </uses-permission> <!-- 用于读取手机当前的状态 --> <uses-permission android:name="android.permission.READ_PHONE_STATE" > </uses-permission> <!-- 写入扩展存储,向扩展卡写入数据,用于写入缓存定位数据 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" > </uses-permission>
相关推荐
本教程将深入探讨如何实现从SD卡中选取图片并利用HTTP POST方法上传至服务器的完整流程。 首先,我们需要理解Android权限管理。在AndroidManifest.xml文件中,你需要添加读取外部存储的权限: ```xml ...
本话题主要关注如何在Android系统中保存未被捕获的Crash信息至SD卡,并进一步将这些信息上传至服务器。 一、Android崩溃处理机制 Android系统为每个应用提供了默认的错误处理机制,但这个机制往往不足以满足开发者...
在Android平台上,开发一款应用允许用户拍照、剪切图片并保存至SD卡是常见的功能需求。这个过程涉及到了Android的多媒体处理、相机API、文件系统操作等多个知识点。下面将详细阐述这些关键点。 1. **Android相机API...
以上就是“android拍照后将照片上传服务器的例子”所涉及的主要技术点,实现这样一个功能需要理解Android的相机API、文件操作、网络请求以及权限管理等多个方面的知识。通过这个例子,开发者可以更好地掌握Android...
在Android开发中,实现“拍照、剪切及上传到PHP服务器”的功能涉及到多个技术环节,主要包括Android系统的相机API、图片处理以及网络通信。下面将详细解释这些知识点。 1. **Android相机API**: - `ACTION_IMAGE_...
在Android平台上,实现手机拍照并保存照片涉及到一系列的步骤和技术,包括权限管理、启动相机服务、处理相机回调、保存图片到SD卡等。下面将详细解释这些知识点。 首先,我们需要在`AndroidManifest.xml`文件中添加...
在Android平台上实现后台连续静默拍照是一项技术挑战,涉及到多个关键知识点。首先,我们要理解Android系统的权限管理和运行机制,然后是相机API的使用,以及如何在后台执行任务。以下是对这些核心概念的详细阐述。 ...
iDRAC 6是DELL服务器的一种远程管理工具,vFlash是其的一种功能,允许用户从SD卡中上传image文件,并将其作为启动设备使用。vFlash功能需要DELL OEM的SD卡,否则无法正常使用。 二、实验环境和要求 实验环境为T310...
### 安卓应用中修改头像并保存至SD卡的技术解析 #### 技术背景与需求分析 在移动应用开发中,尤其是社交类、个人中心类应用中,为用户提供个性化设置的功能是提升用户体验的重要手段之一。其中,允许用户自定义...
SD卡序列号修改工具是一种专门用于更改SD卡标识序列号的软件,主要应用于安卓设备和Windows操作系统。在本文中,我们将深入探讨SD卡序列号、为何需要修改以及如何使用这样的工具进行修改。 首先,理解SD卡序列号的...
- 拍照后,通常会将照片保存到SD卡或者手机内部存储的特定目录下,可以通过ContentResolver的insert方法将图片数据插入到MediaStore中,以便系统能自动扫描并显示在图库中。 - 录像完成后,同样需要将视频文件保存...
总结来说,"Android手机SD卡文件浏览器"是Android系统中不可或缺的一部分,它的实现涉及到文件系统的操作、用户界面的设计、权限管理以及性能优化等多个方面。开发者需要理解Android的文件系统结构,熟悉Java I/O...
为了更好地利用SD卡的空间,许多Android用户选择为SD卡进行分区处理,以便更好地管理和使用存储资源。本文将详细介绍如何在Android系统的手机上对SD卡进行分区,尤其是如何在不影响原有数据的情况下新增一个ext分区...
- 使用`Intent.createChooser()`启动一个文件选择器,让用户选择SD卡上的图片。这个Intent的响应会返回一个Uri,这个Uri可以传递给ContentProvider。 5. 在WebView中显示图片: - 使用`WebView.loadUrl()`方法...
在Android平台上,开发一款应用程序来浏览SD卡目录并实现音频播放功能是一项常见的需求。这个功能可以让用户自由选择存储在外部存储设备(如SD卡)上的音频文件进行播放,增加了应用的灵活性和用户体验。下面我们将...
在Android平台上,调用摄像头拍摄视频并将其上传到服务器是一项常见的功能,特别是在开发移动应用时。这个名为"Android调用摄像头拍摄并上传视频源码.rar"的压缩包可能包含了一个完整的示例项目,用于演示如何实现这...
来获取内置SD卡的路径,但是每款定制过的android 系统的外置SD卡的路径都不一样,那我们怎么才能去获取这个路径呢,我们可以想其它的办法,我这里提供了一个类可以获取外置SD卡或内置SD卡的 label(名称),path(路径)...
在Android平台上,对SD卡文件进行浏览是一项常见的需求,尤其对于开发者来说,这涉及到文件系统的交互和用户界面的实现。Android系统提供了丰富的API接口来访问和操作文件,包括SD卡上的文件。以下将详细讲解如何...
在Android开发中,模仿QQ上传头像功能是一个常见的需求,特别是在社交应用中。这个过程涉及到多个技术点,包括图片选择、图片预览、图片裁剪、上传服务以及UI设计等。接下来,我们将深入探讨实现这一功能所涉及的...