本文介绍: 自定义Okhttp的cookie管理,在Okhttp初始化的时候设置进去。并在Glide中注册请求对象。因为发送短信的请求需要利用图形验证码请求的cookie,所以cookie管理的逻辑就是,保存上一次请求的cookie,下一次请求的时候利用上一次请求的cookie。大概业务流程原理如图所示://……@Override.build();@Override/*** Cookie管理类*///保存每个url的cookie。
一、实现效果
二、步骤
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。
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<HttpUrl, List<Cookie>> cookieStore = new HashMap<>();
//上一个请求url
private HttpUrl url;
@Override
public void saveFromResponse(HttpUrl httpUrl, List<Cookie> list) {
//保存链接的cookie
cookieStore.put(httpUrl, list);
//保存上一次的url,供给下一次cookie的提取。
url = httpUrl;
}
@Override
public List<Cookie> loadForRequest(HttpUrl httpUrl) {
//加载上一个链接的cookie
List<Cookie> cookies = cookieStore.get(url);
return cookies != null ? cookies : new ArrayList<Cookie>();
}
}
}
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<String,Object> 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、相关布局文件
<style name="CustomDialog" parent="android:style/Theme.Dialog">
<!--背景颜色及和透明程度-->
<item name="android:windowBackground">@android:color/transparent</item>
<!--是否去除标题 -->
<item name="android:windowNoTitle">true</item>
<!--是否去除边框-->
<item name="android:windowFrame">@null</item>
<!--是否浮现在activity之上-->
<item name="android:windowIsFloating">true</item>
<!--是否模糊-->
<item name="android:backgroundDimEnabled">true</item>
</style>
Dialog图形验证码验证弹窗的布局文件
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="300dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="@drawable/shape_white_8">
<ImageView
android:id="@+id/iv_delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="12dp"
android:src="@drawable/close"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="10dp"
android:text="请输入图形验证码"
android:textColor="#999999"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/iv_delete" />
<ImageView
android:id="@+id/iv_code"
android:layout_width="70dp"
android:layout_height="28dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="24dp"
android:scaleType="fitXY"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_text" />
<EditText
android:id="@+id/et_code"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginEnd="8dp"
android:textColor="@color/color_222222"
android:textSize="16sp"
android:hint="@string/enter_image_code"
android:paddingTop="10dp"
android:paddingBottom="5dp"
android:background="@drawable/edittext_bg"
android:textCursorDrawable="@drawable/edit_text_cursor"
android:textColorHint="@color/color_D5D5D5"
android:inputType="text"
android:maxLength="4"
app:layout_constraintBottom_toBottomOf="@+id/iv_code"
app:layout_constraintEnd_toStartOf="@id/iv_code"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/iv_code" />
<Button
android:id="@+id/iv_login"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_marginTop="36dp"
android:layout_marginBottom="36dp"
android:layout_marginStart="36dp"
android:layout_marginEnd="36dp"
android:background="@drawable/shape_jfrb_login_button"
android:textColor="@color/white"
android:text="@string/login_confirm"
android:textSize="@dimen/sp_16"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/iv_code" />
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>
三、使用
//图形验证码校验
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");
private void countdown() {
final long count = 60L;
Observable.intervalRange(0, 61, 0, 1, TimeUnit.SECONDS)
.map(new Function<Long, Long>() {
@Override
public Long apply(Long aLong) throws Exception {
return count - aLong;
}
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Long>() {
@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!
原文地址:https://blog.csdn.net/qq_46269365/article/details/134667059
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_5375.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。