Glide结合OkHttp保证短信验证接口携带图形验证码接口返回Cookie值去做网络请求

一、实现效果

Glide结合OkHttp保证短信验证接口携带图形验证码接口返回Cookie值去做网络请求_第1张图片

二、步骤

注意:仅展示核心部分代码

1、导入依赖

api 'com.github.bumptech.glide:glide:4.10.0'
kapt 'com.github.bumptech.glide:compiler:4.10.0'
api 'com.squareup.okhttp3:okhttp:3.11.0'
api 'com.squareup.okhttp3:logging-interceptor:3.11.0'

2、自定义MyAppGlideModule类

自定义Okhttp的cookie管理,在Okhttp初始化的时候设置进去。并在Glide中注册请求对象。

因为发送短信的请求需要利用图形验证码请求的cookie,所以cookie管理的逻辑就是,保存上一次请求的cookie,下一次请求的时候利用上一次请求的cookie。

大概业务流程原理如图所示:
Glide结合OkHttp保证短信验证接口携带图形验证码接口返回Cookie值去做网络请求_第2张图片
代码如下:

package com.custom.jfrb.http;

import android.content.Context;
import androidx.annotation.NonNull;
import com.bumptech.glide.Glide;
import com.bumptech.glide.Registry;
import com.bumptech.glide.annotation.GlideModule;
import com.bumptech.glide.integration.okhttp3.OkHttpUrlLoader;
import com.bumptech.glide.load.model.GlideUrl;
import com.bumptech.glide.module.AppGlideModule;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import okhttp3.Cookie;
import okhttp3.CookieJar;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
//......

@GlideModule
public class MyAppGlideModule extends AppGlideModule {

    public static OkHttpClient okHttpClient;

    @Override
    public void registerComponents(@NonNull Context context, @NonNull Glide glide, @NonNull Registry registry) {
        okHttpClient = new OkHttpClient.Builder()
                .cookieJar(new CookiesManager())
                .build();
        registry.replace(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory(okHttpClient));
    }

    @Override
    public boolean isManifestParsingEnabled() {
        return false;
    }

    /**
     * Cookie管理类
     */
    private class CookiesManager implements CookieJar {

        //保存每个url的cookie
        private HashMap> cookieStore = new HashMap<>();

        //上一个请求url
        private HttpUrl url;

        @Override
        public void saveFromResponse(HttpUrl httpUrl, List list) {
            //保存链接的cookie
            cookieStore.put(httpUrl, list);
            //保存上一次的url,供给下一次cookie的提取。
            url = httpUrl;
        }

        @Override
        public List loadForRequest(HttpUrl httpUrl) {

            //加载上一个链接的cookie
            List cookies = cookieStore.get(url);
            return cookies != null ? cookies : new ArrayList();
        }
    }
}

3、自定义输入图形验证码弹窗Dialog

package com.custom.jfrb.ui.jfrb.login;

import android.annotation.SuppressLint;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.DialogFragment;
import com.alibaba.fastjson.JSONObject;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import org.jetbrains.annotations.NotNull;

@SuppressLint("ValidFragment")
public class SMSCheckDialog extends DialogFragment {

    private ImageView ivCode;
    private SMSCheckCallback checkCallback;
    //手机号
    private String phone;
    //账号名
    private String account;

	//可以把请求短信验证码接口时候需要的接口参数通过构造方法传进来
    public SMSCheckDialog(SMSCheckCallback callback, String phone,String account) {
        this.checkCallback = callback;
        this.phone = phone;
        this.account = account;
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setStyle(STYLE_NORMAL, R.style.CustomDialog);
        setCancelable(false);
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.dialog_sms_check, container, false);
        ImageView ivDelete = view.findViewById(R.id.iv_delete);
        ivCode = view.findViewById(R.id.iv_code);
        ivCode.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            	//加载图形验证码
                loadCapture();
            }
        });
        loadCapture();
        final EditText etCode = view.findViewById(R.id.et_code);
        ivDelete.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            	//关闭图形验证码弹窗
                dismiss();
            }
        });
        Button ivSure = view.findViewById(R.id.iv_login);
        ivSure.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (TextUtils.isEmpty(etCode.getText().toString())) {
                    RnToast.showToast(getContext(),"请输入图形验证码");
                    return;
                }
                //图形验证码输入完成后,发送短信验证码请求
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                    	//去请求发送短信验证码
                        getSmsCode(account,phone,etCode.getText().toString());
                    }
                }).start();

            }
        });
        return view;
    }


    /**
     * 加载显示图形验证码URL
     */
    private void loadCapture(){
        if (getContext() != null) {
            Log.e("mylog","执行loadCapture请求");
            String url = UserService.getImageCodeURL();
            Glide.with(getContext())
                    .load(url)
                    .skipMemoryCache(true)
                    .diskCacheStrategy(DiskCacheStrategy.NONE)
                    .into(ivCode);
        }
    }

    /**
     * 请求短信验证码
     * @param account 账户
     * @param phone 手机号码
     * @param imageCode 图片验证码
     */
    private void getSmsCode(String account,String phone,String imageCode){
        Map map = new HashMap<>();
        map.put("userName",account);
        map.put("telephone",phone);
        map.put("captchaCheckCode",imageCode);
        JSONObject jsonObject = new JSONObject(map);

        MediaType JSON = MediaType.parse("application/json; charset=utf-8");
        RequestBody body = RequestBody.create(jsonObject.toString(),JSON);

        String url = "网络请求地址......";
        Log.d("mylog_sms: ","短信验证码获取请求参数:"+"_账号:"+account+"_手机号:"+phone+"_验证码:"+imageCode);
        Request request = new Request.Builder()
                .url(url)
                .post(body)
                .build();
        MyAppGlideModule.okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                Log.d("mylog_sms: ","短信验证码接口请求失败"+e.toString());
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                Log.d("mylog_sms: ","短信验证码请求成功"+response.toString());
                if (response == null){
                    Log.d("mylog_sms: ","请求失败!");
                    checkCallback.onGetCodeFailed(getString(R.string.send_fail));
                    dismiss();
                    return;
                }
                if (response.body() == null){
                    Log.d("mylog_sms: ","请求失败!");
                    checkCallback.onGetCodeFailed(getString(R.string.send_fail));
                    dismiss();
                    return;
                }
                String result = response.body().string();

                JSONObject object = (JSONObject) JSONObject.parse(result);
                Log.d("mylog_sms: ","接受短信验证码接口返回数据:"+object);
                if ((int)object.get("code") == 0){
                    Log.d("mylog_sms: ","验证成功!");
                    checkCallback.onGetCode();
                }else{
                    Log.d("mylog_sms: ","验证错误");
                    checkCallback.onGetCodeFailed(object.get("msg").toString());
                }
                dismiss();
            }
        });

    }

    public interface SMSCheckCallback {
        void onGetCode();
        void onGetCodeFailed(String msg);
    }
}

4、相关布局文件

styles.xml文件中放入如下自定义Style


Dialog图形验证码验证弹窗的布局文件




    

        

        

        

        
        

三、使用

图形验证码输入弹窗的调用

//图形验证码校验
SMSCheckDialog checkDialog = new SMSCheckDialog(new SMSCheckDialog.SMSCheckCallback() {
        @Override
        public void onGetCode() {
            //短信验证码接口请求成功
            countdown();
        }

        @Override
        public void onGetCodeFailed(String msg) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    //短信验证码接口请求失败
                }
            });
        }
    }, phone,account);
    checkDialog.show(getSupportFragmentManager(), "SMSCheckDialog");

发送短信验证码成功后等待间隙的60s倒计时文字显示

 private void countdown() {
        final long count = 60L;
        Observable.intervalRange(0, 61, 0, 1, TimeUnit.SECONDS)
                .map(new Function() {
                    @Override
                    public Long apply(Long aLong) throws Exception {
                        return count - aLong;
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer() {
                    @Override
                    public void onSubscribe(Disposable d) {
//                        addSubscribe(d);
                    }

                    @SuppressLint("SetTextI18n")
                    @Override
                    public void onNext(Long aLong) {
                        mTvGetCode.setText(aLong + "s");
                        mTvGetCode.setEnabled(false);
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {
                        mTvGetCode.setText(getString(R.string.change_phone9));
                        mTvGetCode.setEnabled(true);
                    }
                });
    }

附:参考Glide结合Okhttp做cookie管理实现注册需求的图片验证码短信验证码功能

四、完成,Nice!

你可能感兴趣的:(Android,安卓控件,网络请求,glide,okhttp,网络,android,安卓控件)