//首先导入第三方的裁剪依赖库
compile 'com.soundcloud.android:android-crop:1.0.1@aar'
//清单文件配置
- <activity android:name="com.soundcloud.android.crop.CropImageActivity" />
//之后Retrofit的工具类 RetrofitUtils
- public class RetrofitUtils {
- private static RetrofitUtils retrofitUtils;//工具类对象
- private static ApiFunction apiFunction;//请求网络接口
- public static OkHttpClient okHttpClient;
- //静态快,获取OkHttpClient对象
- static {
- getOkHttpClient();
- }
- //单例锁模式
- public static RetrofitUtils getInstence(){
- if(retrofitUtils==null){
- synchronized (RetrofitUtils.class){
- if (retrofitUtils==null){
- retrofitUtils=new RetrofitUtils();
- }
- }
- }
- return retrofitUtils;
- }
- //单例模式获取okhttp
- public static OkHttpClient getOkHttpClient(){
- if(okHttpClient==null){
- synchronized (OkHttpClient.class){
- if(okHttpClient==null){
- File fileDir = new File(Environment.getExternalStorageDirectory(), "cache");
- long fileSize = 10 * 1024 * 1024;
- okHttpClient=new OkHttpClient.Builder()
- .addInterceptor(new MyInter())
- //打印拦截器日志
- .addNetworkInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
- .connectTimeout(15, TimeUnit.SECONDS)//设置连接超时时间
- .readTimeout(15, TimeUnit.SECONDS)//设置读取超时时间
- .writeTimeout(15, TimeUnit.SECONDS)//设置写入超时时间
- //.cache(new Cache(fileDir,fileSize))//写入sd卡
- .build();
- }
- }
- }
- return okHttpClient;
- }
- //私有的无参构造
- private RetrofitUtils(){
- Retrofit retrofit=new Retrofit.Builder()
- .baseUrl(Constants.Base_url)
- .addConverterFactory(GsonConverterFactory.create())//添加gson转换器
- .addCallAdapterFactory(RxJava2CallAdapterFactory.create())//添加rxjava转换器
- .client(okHttpClient)//添加okhttp
- .build();
- apiFunction=retrofit.create(ApiFunction.class);
- }
- //获取
- public ApiFunction API(){
- return apiFunction;
- }
- //拦截器
- static class MyInter implements Interceptor {
- private int versionCode;
- private Context context;
- private SharedPreferences jiLu;
- private String token;
- @Override
- public Response intercept(Chain chain) throws IOException {
- Request request = chain.request();
- Request.Builder request_builder = request.newBuilder();
- context = MyApp.con;
- jiLu = context.getSharedPreferences("JiLu", 0);
- if(jiLu!=null){
- token = jiLu.getString("token", null);
- }
- try {
- PackageManager pm = context.getPackageManager();
- PackageInfo pi = pm.getPackageInfo(context.getPackageName(), 0);
- versionCode = pi.versionCode;
- } catch (PackageManager.NameNotFoundException e) {
- e.printStackTrace();
- }
- if("GET".equals(request.method()))
- {
- HttpUrl.Builder builder = request.url().newBuilder();
- HttpUrl build = builder.addQueryParameter("source", Constants.source)
- .addQueryParameter("appVersion", versionCode + "")
- .addQueryParameter("token", token + "")
- .build();
- request = request_builder.url(build).build();
- }
- if ("POST".equals(request.method())) {
- if (request.body() instanceof FormBody) {
- System.out.println("FormBody开始添加公共参数");
- FormBody.Builder builder = new FormBody.Builder();
- FormBody body = (FormBody) request.body();
- for (int i = 0; i < body.size(); i++) {
- builder.add(body.encodedName(i), body.encodedValue(i));
- }
- body = builder.add("source", Constants.source)
- .add("appVersion", String.valueOf(versionCode))
- .add("token", token+"")
- .build();
- System.out.println("开始添加公共参数55555" );
- request = request_builder.post(body).build();
- }
- //因为传送文件要用到 @Multipart注解
- else if(request.body() instanceof MultipartBody)
- {
- MultipartBody body = (MultipartBody) request.body();
- MultipartBody.Builder builder=new MultipartBody.Builder().setType(MultipartBody.FORM);
- builder.addFormDataPart("source","android")
- .addFormDataPart("appVersion",versionCode+"")
- .addFormDataPart("token",token+"");
- List<MultipartBody.Part> parts = body.parts();
- for (MultipartBody.Part part : parts) {
- builder.addPart(part);
- }
- request=request_builder.post(builder.build()).build();
- }
- }
- return chain.proceed(request);
- }
- /**
- * 添加公共参数
- *
- * @param oldRequest
- * @return
- */
- private Request addParam(Request oldRequest) {
- jiLu = context.getSharedPreferences("JiLu", 0);
- if(jiLu!=null){
- token = jiLu.getString("token", null);
- }
- PackageInfo packageArchiveInfo = MyApp.con.getPackageManager().getPackageArchiveInfo(MyApp.con.getPackageName(), 0);
- int versionCode = packageArchiveInfo.versionCode;
- HttpUrl.Builder builder = oldRequest.url()
- .newBuilder()
- .setEncodedQueryParameter("source", "android")
- .setEncodedQueryParameter("token",token)
- .setEncodedQueryParameter("appVersion",versionCode+"")
- ;
- Request newRequest = oldRequest.newBuilder()
- .method(oldRequest.method(), oldRequest.body())
- .url(builder.build())
- .build();
- return newRequest;
- }
- }
- }
//下面我们写 ApiFunction
- public interface ApiFunction {
- //上传文件
- @Multipart
- @POST("file/upload")
- Observable<BaseUser> uploadFile(@PartMap Map<String, RequestBody> params);
- }
//接口工具类
- public class Constants {
- public static String Base_url="https://www.zhaoapi.cn/";
- public static String UpLoad_url="file/upload";
- public static String source="android";
- }
//把文件转换RequestBody 添加到 Map<String, RequestBody> 中,用于请求数据
//工具类
HttpParameterBuilder
- public class HttpParameterBuilder {
- private static HttpParameterBuilder mParameterBuilder;
- private static Map<String, RequestBody> params;
- /**
- * 构建私有方法
- */
- private HttpParameterBuilder() {
- }
- /**
- * 初始化对象
- */
- public static HttpParameterBuilder newBuilder() {
- if (mParameterBuilder == null) {
- mParameterBuilder = new HttpParameterBuilder();
- if (params == null) {
- params = new HashMap<>();
- }
- }
- return mParameterBuilder;
- }
- /**
- * 添加参数
- * 根据传进来的Object对象来判断是String还是File类型的参数
- */
- public HttpParameterBuilder addParameter(String key, Object o) {
- if (o instanceof String) {
- RequestBody body = RequestBody.create(MediaType.parse("text/plain"), (String) o);
- params.put(key, body);
- } else if (o instanceof File) {
- RequestBody body = RequestBody.create(MediaType.parse("image/*"), (File) o);
- params.put(key + "\"; filename=\"" + ((File) o).getName() + "", body);
- }
- return this;
- }
- /**
- * 初始化图片的Uri来构建参数
- * 一般不常用
- * 主要用在拍照和图库中获取图片路径的时候
- */
- public HttpParameterBuilder addFilesByUri(String key, List<Uri> uris) {
- for (int i = 0; i < uris.size(); i++) {
- File file = new File(uris.get(i).getPath());
- RequestBody body = RequestBody.create(MediaType.parse("image/*"), file);
- params.put(key + i + "\"; filename=\"" + file.getName() + "", body);
- }
- return this;
- }
- /**
- * 构建RequestBody
- */
- public Map<String, RequestBody> bulider() {
- return params;
- }
- }
//转换图片为uri 绝对路径的工具类 UtilsImageProcess
- public class UtilsImageProcess {
- /** * 将得到的一个Bitmap保存到SD卡上,得到一个URI地址 */
- public static Uri saveBitmap(Bitmap bm) {
- //在SD卡上创建目录
- File tmpDir = new File(Environment.getExternalStorageDirectory() + "/org.chenlijian.test"); if (!tmpDir.exists()) {
- tmpDir.mkdir();
- }
- File img = new File(tmpDir.getAbsolutePath() + "test.png");
- try { FileOutputStream fos = new FileOutputStream(img);
- bm.compress(Bitmap.CompressFormat.PNG, 85, fos);
- fos.flush(); fos.close(); return Uri.fromFile(img);
- } catch (FileNotFoundException e) {
- e.printStackTrace(); return null;
- } catch (IOException e) {
- e.printStackTrace(); return null;
- }
- }
- /** * 将得到的一个Bitmap保存到SD卡上,得到一个绝对路径 */
- public static String getPath(Bitmap bm) {
- //在SD卡上创建目录
- File tmpDir = new File(Environment.getExternalStorageDirectory() + "/org.chenlijian.test");
- if (!tmpDir.exists()) {
- tmpDir.mkdir();
- }
- File img = new File(tmpDir.getAbsolutePath() + "/test.png");
- try {
- FileOutputStream fos = new FileOutputStream(img);
- bm.compress(Bitmap.CompressFormat.PNG, 85, fos);
- fos.flush(); fos.close();
- return img.getCanonicalPath();
- } catch (FileNotFoundException e) {
- e.printStackTrace(); return null;
- } catch (IOException e) {
- e.printStackTrace(); return null;
- }
- }
- /** * 将图库中选取的图片的URI转化为URI */
- public static Uri convertUri(Uri uri, Context context) {
- InputStream is; try { is = context.getContentResolver().openInputStream(uri);
- Bitmap bitmap = BitmapFactory.decodeStream(is);
- is.close(); return saveBitmap(bitmap);
- } catch (FileNotFoundException e) {
- e.printStackTrace(); return null;
- } catch (IOException e) {
- e.printStackTrace(); return null;
- }
- }
- /** * 在拍摄照片之前生成一个文件路径Uri,保证拍出来的照片没有被压缩太小,用日期作为文件名,确保唯一性 */
- public static String getSavePath(){
- String saveDir = Environment.getExternalStorageDirectory() + "/org.chenlijian.test";
- File dir = new File(saveDir);
- if (!dir.exists()) {
- dir.mkdir(); }
- Date date = new Date();
- SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss");
- String fileName = saveDir + "/" + formatter.format(date) + ".png";
- return fileName;
- }
- /** * 计算图片的缩放值 */
- public static int calculateInSampleSize(BitmapFactory.Options options,int reqWidth, int reqHeight) {
- final int height = options.outHeight; final int width = options.outWidth;
- int inSampleSize = 1;
- if (height > reqHeight || width > reqWidth) {
- final int heightRatio = Math.round((float) height/ (float) reqHeight);
- final int widthRatio = Math.round((float) width / (float) reqWidth);
- inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
- }
- return inSampleSize;
- }
- /** * 根据路径获得图片并压缩,返回bitmap用于显示 */
- public static Bitmap getSmallBitmap(String filePath) {
- final BitmapFactory.Options options = new BitmapFactory.Options();
- options.inJustDecodeBounds = true; BitmapFactory.decodeFile(filePath, options);
- // Calculate inSampleSize
- options.inSampleSize = calculateInSampleSize(options, 480, 800);
- // Decode bitmap with inSampleSize set
- options.inJustDecodeBounds = false;
- // 设置为true,画质更好一点,加载时间略长
- options.inPreferQualityOverSpeed = true; return BitmapFactory.decodeFile(filePath, options);
- }
- }
//下面是我们的Model
- public void UpLoad(@PartMap Map<String, RequestBody> params, final LoadListener loadListener) {
- RetrofitUtils.getInstence()
- .API()
- .uploadFile(params)
- .subscribeOn(Schedulers.io())
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe(new Consumer<BaseUser>() {
- @Override
- public void accept(BaseUser baseUser) throws Exception {
- loadListener.Success(baseUser);
- }
- }, new Consumer<Throwable>() {
- @Override
- public void accept(Throwable throwable) throws Exception {
- loadListener.Error(throwable.toString());
- }
- });
- }
//presenter
- //修改头像
- @Override
- public void UpLoad(@PartMap Map<String, RequestBody> params) {
- iModel.UpLoad(params, new LoadListener() {
- @Override
- public void Success(Object o) {
- showView.TouXiangSuccess(o);
- }
- @Override
- public void Error(String error) {
- showView.Error(error);
- }
- });
- }
//之后是我们的view
//头像的布局
- <span style="font-size:18px;"> <com.facebook.drawee.view.SimpleDraweeView
- app:roundAsCircle="true"
- app:placeholderImage="@drawable/ic_yonghu"
- android:layout_alignParentLeft="true"
- android:layout_marginBottom="@dimen/y5"
- android:id="@+id/touxiang"
- android:layout_width="@dimen/x42"
- android:layout_height="@dimen/y40"
- /></span>
- <span style="font-size:18px;">case R.id.my_image_view:
- //找到pop里面的选项
- if(uid!=null){//判断是否登录
- setPop();
- menu.toggle();
- }else{
- Toast.makeText(this,"请登录账号",Toast.LENGTH_SHORT).show();
- }
- break;</span>
- <span style="font-size:18px;"> //找到pop里面的选项
- private void setPop() {
- //弹出popupWindow
- v = LayoutInflater.from(this).inflate(R.layout.pp, null);
- //找到pop里面的选项
- Button pai = v.findViewById(R.id.btn_take_photo);
- Button xuan = v.findViewById(R.id.btn_pick_photo);
- Button qu =v.findViewById(R.id.btn_cancel);
- pai.setOnClickListener(this);
- xuan.setOnClickListener(this);
- qu.setOnClickListener(this);
- popupWindow = new PopupWindow(v, ViewGroup.LayoutParams.MATCH_PARENT,
- ViewGroup.LayoutParams.WRAP_CONTENT);
- popupWindow.setBackgroundDrawable(new ColorDrawable(getResources().
- getColor(android.R.color.transparent)));
- popupWindow.setOutsideTouchable(true);
- //显示
- popupWindow.showAtLocation(ShowActivity.this.findViewById(R.id.main),
- Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, 0);
- }</span>
//pp布局
- <span style="font-size:18px;"><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:orientation="vertical"
- android:layout_height="wrap_content">
- <LinearLayout
- android:id="@+id/pop_layout"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_alignParentBottom="true"
- android:background="#9999"
- android:gravity="center_horizontal"
- android:orientation="vertical">
- <Button
- android:id="@+id/btn_take_photo"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_marginLeft="20dip"
- android:layout_marginRight="20dip"
- android:layout_marginTop="20dip"
- android:background="#8e8e8e"
- android:text="拍照"
- android:textStyle="bold" />
- <Button
- android:id="@+id/btn_pick_photo"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_marginLeft="20dip"
- android:layout_marginRight="20dip"
- android:layout_marginTop="5dip"
- android:background="#8e8e8e"
- android:text="从相册选择"
- />
- <Button
- android:id="@+id/btn_cancel"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_marginBottom="15dip"
- android:layout_marginLeft="20dip"
- android:layout_marginRight="20dip"
- android:layout_marginTop="15dip"
- android:background="#8e8e8e"
- android:text="取消"
- android:textColor="#ffffff"
- />
- </LinearLayout>
- </LinearLayout>
- </span>
- <span style="font-size:18px;">@Override
- public void onClick(View v) {
- switch (v.getId()){
- //调用相机
- case R.id.btn_take_photo:
- //首先创建一个路径
- path= UtilsImageProcess.getSavePath();
- //转换成uri路径
- Uri uri1 = Uri.fromFile(new File(path));
- //打开相机
- Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
- intent.putExtra(MediaStore.EXTRA_OUTPUT, uri1);
- startActivityForResult(intent, 666);
- popupWindow.dismiss();
- break;
- //调用相册
- case R.id.btn_pick_photo:
- Intent in = new Intent(Intent.ACTION_GET_CONTENT);
- //指定图片的类型
- in.setType("image/*");
- //打开相册
- startActivityForResult(in, 999);
- popupWindow.dismiss();
- break;
- case R.id.btn_cancel:
- Toast.makeText(this,"取消了",Toast.LENGTH_SHORT).show();
- popupWindow.dismiss();
- break;
- }
- }</span>
- <span style="font-size:18px;"> //重写
- private static final String TAG = "MainActivity-----";
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
- //判断
- switch (requestCode) {
- case 666:
- //拿到相片
- Bitmap bitmap = UtilsImageProcess.getSmallBitmap(path);
- //通过工具把相片转换成uri
- Uri uri2 = UtilsImageProcess.saveBitmap(bitmap);
- //调裁剪的第三方
- beginCrop(uri2);
- break;
- case 999:
- //获取图片的地址,当更新成功之后,直接给控件赋值而不用再请求数据
- Uri uri3 = UtilsImageProcess.convertUri(data.getData(),this);
- //调裁剪的第三方
- beginCrop(uri3);
- break;
- case Crop.REQUEST_CROP:
- //裁剪完成的方法
- handleCrop(data);
- break;
- default :
- Toast.makeText(this,"取消了",Toast.LENGTH_SHORT).show();
- break;
- }
- }</span>
//调用裁剪的方法
- //启动裁剪Activity
- private void beginCrop(Uri source) {
- Uri destination1 = Uri.fromFile(new File(UtilsImageProcess.getSavePath()));
- Crop.of(source, destination1).asSquare().start(this);
- }
- <span style="font-size:18px;">//处理裁剪得到的图片,上传到服务器
- private void handleCrop(Intent data) {
- Uri u = Crop.getOutput(data);
- try {
- //拿到剪裁之后的图片
- Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), u);
- //通过工具把bitmap转换为绝对路径,创建文件上传服务器
- String imagePath = UtilsImageProcess.getPath(bitmap);
- //通过工具类把bitmap转换为uri方便直接给控件赋值
- uri= UtilsImageProcess.saveBitmap(bitmap);
- Log.e("uri",uri+"");
- file = new File(imagePath);
- postFile(file);
- } catch (IOException e) {
- e.printStackTrace();
- Log.e("sadadas",e.toString());
- }
- }
- //上传头像的方法
- public void postFile(File file){
- //准备请求的参数,接口路径 HttpParameterBuilder工具类
- Map<String, RequestBody> params = HttpParameterBuilder.newBuilder()
- .addParameter("uid",uid)
- .addParameter("file",file)
- .bulider();
- //调取工具类更新接口数据
- p.UpLoad(params);
- }</span>
//更新成功之后记得刷新头像!!!!!