nilupeng
2022-08-10 2270c82c340e89b40291efa144dd5dd73710ff51
登录信息,头像上传
1 files added
11 files modified
399 ■■■■ changed files
app/build.gradle 7 ●●●● patch | view | raw | blame | history
app/src/main/AndroidManifest.xml 11 ●●●●● patch | view | raw | blame | history
app/src/main/java/com/runt/open/mvvm/config/Configuration.java 1 ●●●● patch | view | raw | blame | history
app/src/main/java/com/runt/open/mvvm/retrofit/Interceptor/HttpLoggingInterceptor.java 31 ●●●● patch | view | raw | blame | history
app/src/main/java/com/runt/open/mvvm/retrofit/api/CommonApiCenter.java 20 ●●●● patch | view | raw | blame | history
app/src/main/java/com/runt/open/mvvm/ui/loadpage/PageViewModels.java 2 ●●● patch | view | raw | blame | history
app/src/main/java/com/runt/open/mvvm/ui/login/RegisterLoginActivity.java 9 ●●●●● patch | view | raw | blame | history
app/src/main/java/com/runt/open/mvvm/ui/main/mine/MineFragment.java 81 ●●●● patch | view | raw | blame | history
app/src/main/java/com/runt/open/mvvm/ui/main/mine/MineViewModel.java 14 ●●●● patch | view | raw | blame | history
app/src/main/java/com/runt/open/mvvm/ui/splash/SplashActivity.java 9 ●●●● patch | view | raw | blame | history
app/src/main/java/com/runt/open/mvvm/util/GlideEngine.kt 212 ●●●●● patch | view | raw | blame | history
build.gradle 2 ●●●●● patch | view | raw | blame | history
app/build.gradle
@@ -1,5 +1,6 @@
plugins {
    id 'com.android.application'
    id 'kotlin-android'
}
android {
@@ -32,6 +33,9 @@
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = '1.8'
    }
    buildFeatures {
        viewBinding true
@@ -71,6 +75,5 @@
    annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'
    implementation 'com.facebook.rebound:rebound:0.3.6'//Rebound  “弹簧”动画效果的第三方工具包,由FaceBook
    implementation 'com.github.zhaolei9527:BottomMenu:v1.0.1'//底部菜单弹框
    implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.2.3'//图片选择
    implementation 'com.github.wildma:PictureSelector:1.1.1'//图片选择裁切工具
    implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0'//图片选择
}
app/src/main/AndroidManifest.xml
@@ -42,16 +42,7 @@
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".ui.main.MainActivity"
            android:launchMode="singleTask"
            tools:ignore="WrongManifestParent"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <action android:name="com.zfwl.merchant.activities.MainActivity" />
            </intent-filter>
        </activity>
        <activity android:name=".ui.main.MainActivity" />
        <activity android:name=".ui.login.RegisterLoginActivity" />
        <activity android:name=".ui.web.WebViewActivity" />
    </application>
app/src/main/java/com/runt/open/mvvm/config/Configuration.java
@@ -9,6 +9,7 @@
    public final static String KEY_CODE= "code";
    public static final String KEY_TOKEN = "token";
    public static final String KEY_USERINFO = "userinfo";
    public static final String KEY_USERNAME = "username";
    public static final String KEY_PHONE = "phone";
    public static final String KEY_USERPASS = "userpass";
app/src/main/java/com/runt/open/mvvm/retrofit/Interceptor/HttpLoggingInterceptor.java
@@ -1,15 +1,18 @@
package com.runt.open.mvvm.retrofit.Interceptor;
import android.util.Log;
import com.google.gson.Gson;
import com.runt.open.mvvm.MyApplication;
import com.runt.open.mvvm.data.PhoneDevice;
import com.runt.open.mvvm.retrofit.net.NetWorkCost;
import com.runt.open.mvvm.retrofit.net.NetWorkListenear;
import com.runt.open.mvvm.retrofit.utils.HttpPrintUtils;
import com.runt.open.mvvm.ui.login.UserBean;
import com.runt.open.mvvm.util.DeviceUtil;
import okhttp3.*;
import okhttp3.internal.http.HttpHeaders;
import okio.Buffer;
import okio.BufferedSource;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
@@ -21,18 +24,6 @@
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import okhttp3.FormBody;
import okhttp3.Headers;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okhttp3.internal.http.HttpHeaders;
import okio.Buffer;
import okio.BufferedSource;
/**
 * My father is Object, ites purpose of     log打印
@@ -65,6 +56,9 @@
                .addHeader("device", new Gson().toJson(PhoneDevice.getDevice()))
                .addHeader("appVersion", DeviceUtil.getAppVersionName(MyApplication.getApplication()))
                .addHeader("os", DeviceUtil.isHarmonyOS()? "harmony" : "android");
        if(UserBean.getUser() != null){
            requestBuild.addHeader("token",UserBean.getUser().getToken());
        }
        Request request = requestBuild.build().newBuilder().build();
        ArrayList<String> logArrays = new ArrayList<>();
        Response response = null;
@@ -208,7 +202,14 @@
            if (isPlaintext(buffer)) {
                logArrays.add("---------->RESPONSE BODY<----------");
                if (contentLength != 0) {
                    logArrays.add(new JSONObject(buffer.clone().readString((charset))).toString(4));
                    String str = buffer.clone().readString(charset);
                    if(str.trim().indexOf("{") == 0) {
                        logArrays.add(new JSONObject(str).toString(4));
                    }else if(str.trim().indexOf("[") == 0) {
                        logArrays.add(new JSONArray(str).toString(4));
                    }else{
                        logArrays.add(str);
                    }
                }
                logArrays.add("<-- END HTTP (" + buffer.size() + "-byte body)");
app/src/main/java/com/runt/open/mvvm/retrofit/api/CommonApiCenter.java
@@ -5,23 +5,11 @@
import com.runt.open.mvvm.data.HttpApiResult;
import com.runt.open.mvvm.data.PageResult;
import com.runt.open.mvvm.data.Results;
import java.util.Map;
import io.reactivex.Observable;
import okhttp3.MultipartBody;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.http.Field;
import retrofit2.http.FieldMap;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.Multipart;
import retrofit2.http.POST;
import retrofit2.http.Part;
import retrofit2.http.Query;
import retrofit2.http.QueryMap;
import retrofit2.http.Url;
import retrofit2.http.*;
import java.util.Map;
/**
 * My father is Object, ites purpose of     常用接口
@@ -74,7 +62,7 @@
    @Multipart
    @POST("updatehead")
    Call<ResponseBody> updateHead(@Part MultipartBody.Part file);
    Observable<Results.StringApiResult> updateHead(@Part MultipartBody.Part file);
    /**
app/src/main/java/com/runt/open/mvvm/ui/loadpage/PageViewModels.java
@@ -11,7 +11,7 @@
 * @purpose Created by Runt (qingingrunt2010@qq.com) on 2022/8/9.
 */
public class PageViewModels {
    public class HomeViewModel extends LoadPageViewModel<Results.Message> {
    public static class HomeViewModel extends LoadPageViewModel<Results.Message> {
        @Override
        public Observable<HttpApiResult<PageResult<Results.Message>>> request(int page, Object... objects) {
            return commonApi.getMsgList(page,SIZE);
app/src/main/java/com/runt/open/mvvm/ui/login/RegisterLoginActivity.java
@@ -46,13 +46,10 @@
           }
        });
        mViewModel.getLoginResult().observe(this, loggedInUser -> {
            putBooleanProjectPrefrence(Configuration.IS_LOGIN,true);
            putStringProjectPrefrence(Configuration.KEY_USERNAME, mBinding.editPhone.getText().toString());
            UserBean user = new Gson().fromJson(new Gson().toJson(loggedInUser) ,UserBean.class);
            UserBean.setUser(user);
            putStringProjectPrefrence(Configuration.KEY_TOKEN, user.getToken());
            MyLog.i("registerlogin",user.toString());
            UserBean.setUser(loggedInUser);
            putStringProjectPrefrence(Configuration.KEY_USERINFO, new Gson().toJson(loggedInUser));
            MyLog.i("registerlogin",loggedInUser.toString());
            showToast(R.string.login_success);
            setResult(RESULT_CODE_SUCESS);
            finish();
app/src/main/java/com/runt/open/mvvm/ui/main/mine/MineFragment.java
@@ -2,27 +2,32 @@
import android.app.Activity;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.util.Log;
import android.view.View;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import com.permissionx.guolindev.PermissionX;
import com.luck.picture.lib.PictureSelector;
import com.luck.picture.lib.config.PictureConfig;
import com.luck.picture.lib.config.PictureMimeType;
import com.luck.picture.lib.entity.LocalMedia;
import com.runt.open.mvvm.BuildConfig;
import com.runt.open.mvvm.R;
import com.runt.open.mvvm.base.fragments.BaseFragment;
import com.runt.open.mvvm.data.HttpApiResult;
import com.runt.open.mvvm.data.Results;
import com.runt.open.mvvm.databinding.FragmentMineBinding;
import com.runt.open.mvvm.listener.ResPonse;
import com.runt.open.mvvm.retrofit.observable.HttpObserver;
import com.runt.open.mvvm.ui.login.UserBean;
import com.runt.open.mvvm.util.GlideEngine;
import com.runt.open.mvvm.util.MyLog;
import com.wildma.pictureselector.PictureSelector;
import java.io.File;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import java.io.File;
import java.util.List;
/**
 * My father is Object, ites purpose of
@@ -118,27 +123,25 @@
     * 打开相册
     */
    public void openAlthum(){
        PermissionX.init(this)
                .permissions(mActivity.CAMERA_PERMISSIONS)
                .request((allGranted, grantedList, deniedList) -> {
                    if(allGranted){
                        PictureSelector
                                .create(this, PictureSelector.SELECT_REQUEST_CODE)
                                .selectPicture(true, 300, 300, 20, 20);
                    }else{
                        mActivity.showDialog("警告", "软件需要权限才能运行", "申请权限", "取消", new ResPonse() {
                            @Override
                            public void doSuccess(Object obj) {
                                openAlthum();
                            }
                            @Override
                            public void doError(Object obj) {
                            }
                        });
                    }
                });
        PictureSelector.create(this)
                .openGallery(PictureMimeType.ofImage()) // 全部.PictureMimeType.ofAll()、图片.ofImage()、视频.ofVideo()、音频.ofAudio()
                .imageEngine(GlideEngine.Companion.getInstance()) // 外部传入图片加载引擎,必传项
                .maxSelectNum(1) // 最大图片选择数量
                .minSelectNum(1) // 最小选择数量
                .imageSpanCount(3) // 每行显示个数
                .isReturnEmpty(true) // 未选择数据时点击按钮是否可以返回
                .isAndroidQTransform(false) // 是否需要处理Android Q 拷贝至应用沙盒的操作,只针对compress(false); && .isEnableCrop(false);有效,默认处理
                .setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) // 设置相册Activity方向,不设置默认使用系统
                .isSingleDirectReturn(true) // 单选模式下是否直接返回,PictureConfig.SINGLE模式下有效
                .isPreviewImage(true) // 是否可预览图片
                .isCamera(true) // 是否显示拍照按钮
                .isZoomAnim(false) // 图片列表点击 缩放效果 默认true
                .isEnableCrop(true) // 是否裁剪
                .withAspectRatio(1, 1) // 裁剪比例 如16:9 3:2 3:4 1:1 可自定义
                .isCompress(false) // 是否压缩
                .cutOutQuality(100) // 裁剪输出质量 默认100
                .selectionMode(PictureConfig.SINGLE)
                .forResult(PictureConfig.CHOOSE_REQUEST);//结果回调onActivityResult code
    }
@@ -147,24 +150,18 @@
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        /*结果回调*/
        if (requestCode == PictureSelector.SELECT_REQUEST_CODE) {
        if (requestCode == PictureConfig.CHOOSE_REQUEST) {
            if (data != null) {
                String picturePath = data.getStringExtra(PictureSelector.PICTURE_PATH);
                MyLog.i("mineActivity","picturePath:"+picturePath);
                final  File file = new File(picturePath);
                mViewModel.updateHead(file).enqueue(new Callback<ResponseBody>() {
                List<LocalMedia> selectList = PictureSelector.obtainMultipleResult(data);
                final  File file = new File(selectList.get(0).getCutPath());
                MyLog.i("mineActivity","picturePath:"+selectList.get(0).getCutPath()+" exists:"+file.exists());
                mViewModel.updateHead(file, new HttpObserver<String>() {
                    @Override
                    public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                        /*UserBean.getUser().setHead(obj.toString());
                        file.delete();
                        Glide.with(getContext()).load(BuildConfig.HOST_IP_ADDR+UserBean.getUser().getHead()) .into(mBinding.img); //获取选取的图片*/
                    protected void onSuccess(String data) {
                        UserBean.getUser().setHead(data);
                        Glide.with(getContext()).load(BuildConfig.HOST_IP_ADDR+UserBean.getUser().getHead()) .into(mBinding.img); //获取选取的图片
                    }
                    @Override
                    public void onFailure(Call<ResponseBody> call, Throwable t) {
                        file.delete();
                    }
                });
            }
        }else if(requestCode == REQUEST_CODE_SIGN && resultCode == Activity.RESULT_OK){
app/src/main/java/com/runt/open/mvvm/ui/main/mine/MineViewModel.java
@@ -1,17 +1,16 @@
package com.runt.open.mvvm.ui.main.mine;
import com.runt.open.mvvm.base.model.BaseViewModel;
import com.runt.open.mvvm.data.Results;
import com.runt.open.mvvm.listener.ResPonse;
import com.runt.open.mvvm.retrofit.observable.HttpObserver;
import com.runt.open.mvvm.ui.login.UserBean;
import java.io.File;
import io.reactivex.Observable;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Call;
import java.io.File;
/**
 * @purpose Created by Runt (qingingrunt2010@qq.com) on 2022/7/27.
@@ -29,8 +28,9 @@
        }
    }
    public Call<ResponseBody> updateHead(File file){
        return commonApi.updateHead(MultipartBody.Part.createFormData("head",file.getName(), RequestBody.create(MediaType.parse("text/plain"), file)));
    public void updateHead(File file, HttpObserver<String> observer){
        Observable<Results.StringApiResult> observable = commonApi.updateHead(MultipartBody.Part.createFormData("head", file.getName(), RequestBody.create(MediaType.parse("text/plain"), file)));
        httpObserverOnLoading(observable,observer);
    }
}
app/src/main/java/com/runt/open/mvvm/ui/splash/SplashActivity.java
@@ -5,10 +5,12 @@
import android.os.Handler;
import android.view.View;
import android.view.WindowManager;
import com.google.gson.Gson;
import com.runt.open.mvvm.base.activities.BaseActivity;
import com.runt.open.mvvm.base.model.ImpViewModel;
import com.runt.open.mvvm.config.Configuration;
import com.runt.open.mvvm.databinding.ActivitySplashBinding;
import com.runt.open.mvvm.ui.login.UserBean;
import com.runt.open.mvvm.ui.main.MainActivity;
@@ -36,6 +38,11 @@
    @Override
    public void loadData() {
        String json = getStringProjectPrefrence(Configuration.KEY_USERINFO);
        if(!isNull(json)){
            UserBean user = new Gson().fromJson(json ,UserBean.class);
            UserBean.setUser(user);
        }
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
app/src/main/java/com/runt/open/mvvm/util/GlideEngine.kt
New file
@@ -0,0 +1,212 @@
package com.runt.open.mvvm.util
import android.content.Context
import android.graphics.Bitmap
import android.graphics.PointF
import android.graphics.drawable.Drawable
import android.view.View
import android.widget.ImageView
import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory
import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions
import com.bumptech.glide.request.target.BitmapImageViewTarget
import com.bumptech.glide.request.target.ImageViewTarget
import com.luck.picture.lib.engine.ImageEngine
import com.luck.picture.lib.listener.OnImageCompleteCallback
import com.luck.picture.lib.tools.MediaUtils
import com.luck.picture.lib.widget.longimage.ImageSource
import com.luck.picture.lib.widget.longimage.ImageViewState
import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView
import com.runt.open.mvvm.R
class GlideEngine : ImageEngine {
    private constructor()
    companion object {
        val instance = GlideEngineInit.init
    }
    private object GlideEngineInit {
        val init = GlideEngine()
    }
    /**
     * 加载图片
     *
     * @param context
     * @param url
     * @param imageView
     */
    override fun loadImage(context: Context, url: String, imageView: ImageView) {
        Glide.with(context)
            .load(url)
            .into(imageView)
    }
    /**
     * 加载网络图片适配长图方案
     * # 注意:此方法只有加载网络图片才会回调
     *
     * @param context
     * @param url
     * @param imageView
     * @param longImageView
     * @param callback      网络图片加载回调监听 {link after version 2.5.1 Please use the #OnImageCompleteCallback#}
     */
    override fun loadImage(
        context: Context, url: String,
        imageView: ImageView,
        longImageView: SubsamplingScaleImageView, callback: OnImageCompleteCallback?
    ) {
        Glide.with(context)
            .asBitmap()
            .load(url)
            .into(object : ImageViewTarget<Bitmap?>(imageView) {
                override fun onLoadStarted(placeholder: Drawable?) {
                    super.onLoadStarted(placeholder)
                    callback?.onShowLoading()
                }
                override fun onLoadFailed(errorDrawable: Drawable?) {
                    super.onLoadFailed(errorDrawable)
                    callback?.onHideLoading()
                }
                override fun setResource(resource: Bitmap?) {
                    callback?.onHideLoading()
                    if (resource != null) {
                        val eqLongImage = MediaUtils.isLongImg(
                            resource.width,
                            resource.height
                        )
                        longImageView.visibility = if (eqLongImage) View.VISIBLE else View.GONE
                        imageView.visibility = if (eqLongImage) View.GONE else View.VISIBLE
                        if (eqLongImage) {
                            // 加载长图
                            longImageView.isQuickScaleEnabled = true
                            longImageView.isZoomEnabled = true
                            longImageView.setDoubleTapZoomDuration(100)
                            longImageView.setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CENTER_CROP)
                            longImageView.setDoubleTapZoomDpi(SubsamplingScaleImageView.ZOOM_FOCUS_CENTER)
                            longImageView.setImage(
                                ImageSource.bitmap(resource),
                                ImageViewState(0f, PointF(0f, 0f), 0)
                            )
                        } else {
                            // 普通图片
                            imageView.setImageBitmap(resource)
                        }
                    }
                }
            })
    }
    /**
     * 加载网络图片适配长图方案
     * # 注意:此方法只有加载网络图片才会回调
     *
     * @param context
     * @param url
     * @param imageView
     * @param longImageView
     * @ 已废弃
     */
    override fun loadImage(
        context: Context, url: String,
        imageView: ImageView,
        longImageView: SubsamplingScaleImageView
    ) {
        Glide.with(context)
            .asBitmap()
            .load(url)
            .into(object : ImageViewTarget<Bitmap?>(imageView) {
                override fun setResource(resource: Bitmap?) {
                    if (resource != null) {
                        val eqLongImage = MediaUtils.isLongImg(
                            resource.width,
                            resource.height
                        )
                        longImageView.visibility = if (eqLongImage) View.VISIBLE else View.GONE
                        imageView.visibility = if (eqLongImage) View.GONE else View.VISIBLE
                        if (eqLongImage) {
                            // 加载长图
                            longImageView.isQuickScaleEnabled = true
                            longImageView.isZoomEnabled = true
                            longImageView.setDoubleTapZoomDuration(100)
                            longImageView.setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CENTER_CROP)
                            longImageView.setDoubleTapZoomDpi(SubsamplingScaleImageView.ZOOM_FOCUS_CENTER)
                            longImageView.setImage(
                                ImageSource.bitmap(resource),
                                ImageViewState(0f, PointF(0f, 0f), 0)
                            )
                        } else {
                            // 普通图片
                            imageView.setImageBitmap(resource)
                        }
                    }
                }
            })
    }
    /**
     * 加载相册目录
     *
     * @param context   上下文
     * @param url       图片路径
     * @param imageView 承载图片ImageView
     */
    override fun loadFolderImage(context: Context, url: String, imageView: ImageView) {
        Glide.with(context)
            .asBitmap()
            .load(url)
            .override(180, 180)
            .centerCrop()
            .sizeMultiplier(0.5f)
            .apply(RequestOptions().placeholder(R.drawable.picture_image_placeholder))
            .into(object : BitmapImageViewTarget(imageView) {
                override fun setResource(resource: Bitmap?) {
                    val circularBitmapDrawable =
                        RoundedBitmapDrawableFactory.create(context.resources, resource)
                    circularBitmapDrawable.cornerRadius = 8f
                    imageView.setImageDrawable(circularBitmapDrawable)
                }
            })
    }
    /**
     * 加载gif
     *
     * @param context   上下文
     * @param url       图片路径
     * @param imageView 承载图片ImageView
     */
    override fun loadAsGifImage(
        context: Context, url: String,
        imageView: ImageView
    ) {
        Glide.with(context)
            .asGif()
            .load(url)
            .into(imageView)
    }
    /**
     * 加载图片列表图片
     *
     * @param context   上下文
     * @param url       图片路径
     * @param imageView 承载图片ImageView
     */
    override fun loadGridImage(context: Context, url: String, imageView: ImageView) {
        Glide.with(context)
            .load(url)
            .override(200, 200)
            .centerCrop()
            .apply(RequestOptions().placeholder(R.drawable.picture_image_placeholder))
            .into(imageView)
    }
}
build.gradle
@@ -1,11 +1,13 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
    ext.kotlin_version = "1.4.31"
    repositories {
        google()
        mavenCentral()
    }
    dependencies {
        classpath "com.android.tools.build:gradle:7.0.3"
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.20"
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files