Meet实战|上传头像与FileProvider

  • 结果展示
    当点击默认头像的时候可以弹上传头像提示框,你可以选择相册中挑选或拍照。
    在这里插入图片描述
    我这里选了拍照,然后填写昵称,完成按钮变成可点击,点击完成,更新Bmob后台用户信息。
    在这里插入图片描述
    这里是我的Bmob后台用户信息的更新结果,你可以看见用户昵称是嘤嘤嘤,用户头像也有了url地址。
    在这里插入图片描述

  • bug:在上传准备更新后台用户信息的时候,提示上传失败,要开通域名管理。查了官网,解决办法是要购买独立域名:
    目前有2种解决方案:(这是官方的解决方案,虽然心疼,但想着为知识付费,还是乖乖扫了码)
    方案一:(100/年)我们提供了备案域名:在控制台->应用设置->应用配置->开启文件独立域名,开启后图片即可访问。
    方案二:(免费)自有已经备案的域名,进入应用设置,域名管理,绑定自有域名。
    在这里插入图片描述

  • 接下来是代码:

  • 首先要写好跳转的相关代码,这里就不给出来啦,很简单,就按照你自己的逻辑,什么时候跳转到上传头像和昵称页就看个人啦。

  • 接着就是上传头像和昵称页,写好布局文件,在Activity页进行控件初始化。以下是布局文件代码。

<?xml version="1.0" encoding="utf-8"?>

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".UI.FirstUploadActivity">
    <LinearLayout
        android:orientation="vertical"
        android:gravity="center"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <TextView
            android:gravity="center"
            android:textSize="20sp"
            android:textColor="@android:color/black"
            android:layout_marginTop="50dp"
            android:layout_marginBottom="30dp"
            android:text="@string/attractPeople"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
        </TextView>
<!--        中间的头像-->
        <RelativeLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">
        <ImageView
            android:background="@drawable/img_upload_photo_bg"
            android:layout_centerInParent="true"
            android:layout_width="200dp"
            android:layout_height="200dp">
        </ImageView>
            <de.hdodenhof.circleimageview.CircleImageView
                android:id="@+id/circleImageView"
                android:src="@drawable/ic_launcher2"
                android:layout_width="145dp"
                android:layout_centerInParent="true"
                android:layout_height="145dp">
            </de.hdodenhof.circleimageview.CircleImageView>

        </RelativeLayout>
        <TextView
            android:id="@+id/tv_nameStory"
            android:layout_marginBottom="10dp"
            android:layout_marginTop="30dp"
            android:textSize="20sp"
            android:textColor="@android:color/black"
            android:text="@string/oneNameOneStory"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">
        </TextView>
        <EditText
            android:id="@+id/et_nickname"
            android:hint="昵称"
            android:layout_width="300dp"
            android:gravity="center"
            android:background="@drawable/login_edit_bg"
            android:layout_height="50dp">
        </EditText>
        <Button
            android:id="@+id/btn_finish"
            android:textSize="15sp"
            android:textColor="@android:color/white"
            android:text="@string/finish_first_upload"
            android:layout_marginTop="50dp"
            android:background="@drawable/btnbg"
            android:layout_width="300dp"
            android:layout_height="wrap_content">
        </Button>


    </LinearLayout>

</ScrollView>


布局效果图:
在这里插入图片描述

  • 然后写代码逻辑:在点击头像的时候弹出上传提示框,上传提示框有DialogManager类控制;在点击拍照是时候跳转到相机,跳转到相机有FileHelper控制;在点击相册的时候跳转到手机相册,也是有FileHelper类控制;在准备好头像和填写完昵称的时候,点击完成,更新用户信息,监听用户信息是否上传成功,有BmobManager控制。这期间有等待提示框也是有LodingView类控制。以下是各个控制类的代码:
    DialogManager:
package com.example.framework.Manager;

import android.content.Context;
import android.view.Gravity;

import com.example.framework.R;

import com.example.framework.View.DialogView;

/**
 * Created By LicaiWen
 * To DO:
 */
public class DialogManager {
    private volatile static DialogManager dialogManager = null;

    private DialogManager() {

    }

    public static DialogManager getDialogManagerInstance() {
        if (dialogManager == null) {
            synchronized (DialogManager.class) {
                if (dialogManager == null) {
                    dialogManager = new DialogManager();
                }
            }
        }
        return dialogManager;
    }

    //initView方法返回DiaogView实例
    public DialogView initView(Context context, int layout, int gravity) {
        return new DialogView(context, layout, R.style.Theme_Dialog, gravity);
    }

    //重写initView方法,因为大多是dialog的位置是在中间的,而且背景是透明无标题的,所以这个initView方法默认背景透明,无标题,且弹出位置在中间。
    public DialogView initView(Context context, int layout) {
        return new DialogView(context, layout, R.style.Theme_Dialog, Gravity.CENTER);
    }

    //显示DialogView
    public void show(DialogView view) {
        if (view != null) {
            if (!view.isShowing()) {
                view.show();
            }
        }
    }

    //隐藏DialogView
    public void hide(DialogView view) {
        if (view != null) {
            if (view.isShowing()) {
                view.dismiss();
            }
        }
    }
}

FileHelper类:

package helper;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.MediaStore;

import androidx.core.content.FileProvider;
import androidx.loader.content.CursorLoader;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Created By LicaiWen
 * To DO:
 */
//文件帮助类
public class FileHelper {
    public static final int CAMERA_REQUEST_CODE = 1004;
    public static final int ALBUM_REQUEST_CODE = 1005;

    private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MMM-ddd");
    private Uri uriFile;
    private File storageFile = null;
    private static FileHelper fileHelperInstance = null;

    private FileHelper() {

    }

    public static FileHelper getFileHelperInstance() {
        if (fileHelperInstance == null) {
            synchronized (FileHelper.class) {
                if (fileHelperInstance == null) {
                    fileHelperInstance = new FileHelper();
                }
            }
        }
        return fileHelperInstance;
    }

    public File getStorageFile() {
        return storageFile;
    }
    /*
     * 跳转到照相
     * */

    public void toCamera(Activity activity) {
        Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
        String fileName = simpleDateFormat.format(new Date());
        storageFile = new File(Environment.getExternalStorageDirectory(), fileName + ".jpg");
        //兼容android7.0
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
            //小于7.0
            uriFile = Uri.fromFile(storageFile);
        } else {
            uriFile = FileProvider.getUriForFile(activity, "com.example.meet.fileprovider", storageFile);
            //android在7.0后是要添加的
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
        }
        intent.putExtra(MediaStore.EXTRA_OUTPUT, uriFile);
        activity.startActivityForResult(intent, CAMERA_REQUEST_CODE);
    }

    /*
     * 跳转到相册
     * */
    public void toAlbum(Activity activity) {
        Intent intent = new Intent(Intent.ACTION_PICK);
        intent.setType("image/*");
        activity.startActivityForResult(intent, ALBUM_REQUEST_CODE);

    }

    /*
     * 得到uri的真实地址,一位获取到的uri是经过封装的
     * */
    public String getRealPathFRomUri(Context context, Uri uri) {
        String[] project = {MediaStore.Images.Media.DATA};
        CursorLoader cursorLoader = new CursorLoader(context, uri, project, null, null, null);
        Cursor cursor = cursorLoader.loadInBackground();
        int index = cursor.getColumnIndex(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        return cursor.getString(index);
    }
}

LodingView类:

package com.example.framework.View;

import android.animation.ObjectAnimator;
import android.content.Context;
import android.os.Build;
import android.widget.ImageView;
import android.widget.TextView;

import com.example.framework.R;

import com.example.framework.Manager.DialogManager;
import com.example.framework.utils.AnimUtils;

/**
 * Created By LicaiWen
 * To DO:
 */
public class LodingView {

    private DialogView mLodingView;
    private ImageView iv_loding;
    private TextView tv_loding;
    private ObjectAnimator anim;

    public LodingView(Context context) {
        mLodingView = DialogManager.getDialogManagerInstance().initView(context, R.layout.loding_view);
        iv_loding = (ImageView) mLodingView.findViewById(R.id.iv_loding);
        tv_loding = (TextView) mLodingView.findViewById(R.id.tv_loding);
        anim = AnimUtils.animRotation(iv_loding);
    }

    public void setLoadingText(String text) {
        tv_loding.setText(text);
    }

    public void show() {
        anim.start();
        DialogManager.getDialogManagerInstance().show(mLodingView);

    }

    public void hide() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            anim.pause();
        }
        DialogManager.getDialogManagerInstance().hide(mLodingView);
    }

    public void show(String text) {
        setLoadingText(text);
        anim.start();
        DialogManager.getDialogManagerInstance().show(mLodingView);
    }
}

BmobManager类:

package com.example.framework.Manager;

import android.content.Context;

import com.example.framework.bmob.MyBmobUser;
import com.example.framework.entity.StaticClass;

import java.io.File;

import cn.bmob.v3.Bmob;
import cn.bmob.v3.BmobSMS;
import cn.bmob.v3.BmobUser;
import cn.bmob.v3.datatype.BmobFile;
import cn.bmob.v3.exception.BmobException;
import cn.bmob.v3.listener.LogInListener;
import cn.bmob.v3.listener.QueryListener;
import cn.bmob.v3.listener.UpdateListener;
import cn.bmob.v3.listener.UploadFileListener;
import io.rong.imlib.RongIMClient;

import static cn.bmob.v3.BmobUser.signOrLoginByMobilePhone;

/**
 * Created By LicaiWen
 * To DO:
 */
//bmob管理类
public class BmobManager {
    public static final String BMOB_APPID = "8c4aa55ae7076048f72fa40e05945293";

    private volatile static BmobManager bmobManager = null;

    private BmobManager() {

    }

    public static BmobManager getBmobManagerInstance() {
        if (bmobManager == null) {
            synchronized (BmobManager.class) {
                if (bmobManager == null) {
                    bmobManager = new BmobManager();
                }
            }


        }
        return bmobManager;
    }

    public void initBmob(Context context) {
        Bmob.initialize(context, BMOB_APPID);
        // RongIMClient.init(context,StaticClass.RONGYUN_APPID);


    }

    //发送验证码
    public void sendVerifyNumber(String phone, QueryListener<Integer> listener) {
        BmobSMS.requestSMSCode(phone, "", listener);
    }

    //核对验证码
    public void ensureVerifyNumber(String phone, String code, LogInListener<MyBmobUser> listener) {
        signOrLoginByMobilePhone(phone, code, listener);
    }

    //获取登录成功的对象
    public MyBmobUser getMyBombUser() {
        return BmobUser.getCurrentUser(MyBmobUser.class);
    }

    public boolean isLogining() {
        return BmobUser.isLogin();
    }

    //用于获取用户第一次填写的昵称和头像,更新用户信息
    public void firstUploadPhoto(final String nickName, File storageFile, final UploadPhotoListener listener) {

        //获取当前登录的bmob用户
        final MyBmobUser myBmobUser = getMyBombUser();
        //上传头像文件到bmob
        final BmobFile bmobFile = new BmobFile(storageFile);
        bmobFile.uploadblock(new UploadFileListener() {
            @Override
            public void done(BmobException e) {
                if (e == null) {
                    //上传成功
                    //更新用户信息
                    myBmobUser.setNickName(nickName);
                    myBmobUser.setPhoto(bmobFile.getFileUrl());
                    //更新用户token
                    myBmobUser.setTokenNickName(nickName);
                    myBmobUser.setTokenPhoto(bmobFile.getFileUrl());
                    myBmobUser.update(new UpdateListener() {
                        @Override
                        public void done(BmobException e) {
                            if (e == null) {
                                //更新成功
                                listener.uploadDone();
                            } else {
                                //更新失败
                                listener.uploadFail(e);
                            }
                        }
                    });

                } else {
                    //上传失败
                    listener.uploadFail(e);
                }
            }
        });


    }

    public interface UploadPhotoListener {
        void uploadDone();

        void uploadFail(BmobException e);
    }
}

Activity的逻辑代码:

package com.example.meet.UI;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.Gravity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.Nullable;

import com.example.framework.Manager.BmobManager;
import com.example.framework.Manager.DialogManager;
import com.example.framework.View.DialogView;
import com.example.framework.View.LodingView;
import com.example.framework.base.BaseBackActivity;
import com.example.framework.utils.LogUtils;
import com.example.meet.R;

import java.io.File;

import cn.bmob.v3.exception.BmobException;
import de.hdodenhof.circleimageview.CircleImageView;
import helper.FileHelper;

public class FirstUploadActivity extends BaseBackActivity implements View.OnClickListener {
    private CircleImageView circleImageView;
    private TextView tvNameStory;
    private EditText etNickname;
    private Button btnFinish;
    private DialogView upload_Dialog;
    private TextView tvTakephoto;
    private TextView tvPictures;
    private TextView tvCancel;
    private File storageFile;
    private LodingView lodingView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_first_upload);
        initView();
    }

    private void initView() {
        circleImageView = (CircleImageView) findViewById(R.id.circleImageView);
        tvNameStory = (TextView) findViewById(R.id.tv_nameStory);
        etNickname = (EditText) findViewById(R.id.et_nickname);
        btnFinish = (Button) findViewById(R.id.btn_finish);
        btnFinish.setEnabled(false);
        btnFinish.setBackground(getResources().getDrawable(R.color.darkGray));
        etNickname.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                if (s.length() > 0) {
                    btnFinish.setEnabled(storageFile != null);
                    btnFinish.setBackground(getResources().getDrawable(storageFile != null ? R.color.orange_dark : R.color.darkGray));
                } else {
                    btnFinish.setEnabled(false);
                    btnFinish.setBackground(getResources().getDrawable(R.color.darkGray));
                }
            }

            @Override
            public void afterTextChanged(Editable s) {
            }
        });
        circleImageView.setOnClickListener(this);
        btnFinish.setOnClickListener(this);
        //在初始化的时候调用 creatUploadDialog()方法创建上传提示框并初始化提示框中的按钮
        creatUploadDialog();
    }

    public static void startFirstUploadActivity(Activity content, int requestCode) {
        Intent intent = new Intent(content, FirstUploadActivity.class);
        content.startActivityForResult(intent, requestCode);
    }

    public void creatUploadDialog() {
        upload_Dialog = DialogManager.getDialogManagerInstance().initView(this, R.layout.upload_dialog, Gravity.BOTTOM);
        upload_Dialog.setCancelable(false);
        tvTakephoto = (TextView) upload_Dialog.findViewById(R.id.tv_takephoto);
        tvPictures = (TextView) upload_Dialog.findViewById(R.id.tv_pictures);
        tvCancel = (TextView) upload_Dialog.findViewById(R.id.tv_cancel);
        tvTakephoto.setOnClickListener(this);
        tvPictures.setOnClickListener(this);
        tvCancel.setOnClickListener(this);

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.circleImageView:
                //  creatUploadDialog();
                // Toast.makeText(this, "点击了", Toast.LENGTH_SHORT).show();
                //弹出上传提示框
                DialogManager.getDialogManagerInstance().show(upload_Dialog);
                break;
            //完成,更改bmob
            case R.id.btn_finish:
                uploadPhoto();
                break;
            //跳转到照相
            case R.id.tv_takephoto:
                DialogManager.getDialogManagerInstance().hide(upload_Dialog);
                FileHelper.getFileHelperInstance().toCamera(this);
                break;
            //跳转到相册
            case R.id.tv_pictures:
                DialogManager.getDialogManagerInstance().hide(upload_Dialog);
                FileHelper.getFileHelperInstance().toAlbum(this);
                break;
            case R.id.tv_cancel:
                DialogManager.getDialogManagerInstance().hide(upload_Dialog);
                break;
            default:
                break;

        }

    }

    private void uploadPhoto() {
        lodingView = new LodingView(this);
        lodingView.show();
        String nickName = etNickname.getText().toString().trim();
        BmobManager.getBmobManagerInstance().firstUploadPhoto(nickName, storageFile, new BmobManager.UploadPhotoListener() {
            @Override
            public void uploadDone() {
                //更新成功的监听
                lodingView.hide();
                finish();
            }

            @Override
            public void uploadFail(BmobException e) {
                //更新失败的监听
                lodingView.hide();
                Toast.makeText(FirstUploadActivity.this, "上传事变" + e.toString(), Toast.LENGTH_SHORT).show();

            }
        });

    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        //LogUtils.i("jnru result");
        if (resultCode == Activity.RESULT_OK) {
            // LogUtils.i("resultok");
            if (requestCode == FileHelper.CAMERA_REQUEST_CODE) {
                storageFile = FileHelper.getFileHelperInstance().getStorageFile();
                //  LogUtils.i("是否为空:"+storageFile==null?"yes":"no");
            } else if (requestCode == FileHelper.ALBUM_REQUEST_CODE) {
                LogUtils.i("进入相册");
                Uri uri = data.getData();
                if (uri != null) {
                    // LogUtils.i("uribuweikong");
                    String path = FileHelper.getFileHelperInstance().getRealPathFRomUri(this, uri);
                    storageFile = new File(path);
                }
            }
            //放置图片
            if (storageFile != null) {
                // LogUtils.i("buweikong ");
                Bitmap bitmap = BitmapFactory.decodeFile(storageFile.getPath());
                circleImageView.setImageBitmap(bitmap);
            }
            boolean nickNameIsEmpty = TextUtils.isEmpty(etNickname.getText().toString().trim());
            btnFinish.setEnabled(!nickNameIsEmpty);
            btnFinish.setBackground(getResources().getDrawable(!nickNameIsEmpty ? R.color.orange_dark : R.color.darkGray));

        }
        //设置头像
        super.onActivityResult(requestCode, resultCode, data);
    }
}


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值