添加从相册选择头像功能

0515
panqihua 4 years ago
parent 01e74fcc55
commit 7d6b1d47ac
  1. 3
      app/src/main/AndroidManifest.xml
  2. 4
      app/src/main/java/com/community/pocket/data/main/forum/ForumDataRequest.java
  3. 16
      app/src/main/java/com/community/pocket/data/main/forum/ForumPostRequest.java
  4. 29
      app/src/main/java/com/community/pocket/data/main/info/InfoRequest.java
  5. 4
      app/src/main/java/com/community/pocket/data/main/visitor/VisitorMyRequest.java
  6. 4
      app/src/main/java/com/community/pocket/data/main/visitor/VisitorRequest.java
  7. 4
      app/src/main/java/com/community/pocket/data/main/visitor/VisitorReservationRequest.java
  8. 15
      app/src/main/java/com/community/pocket/data/model/LocalToken.java
  9. 5
      app/src/main/java/com/community/pocket/ui/login/LoginActivity.java
  10. 344
      app/src/main/java/com/community/pocket/ui/main/ui/info/InfoFragment.java
  11. 29
      app/src/main/java/com/community/pocket/ui/main/ui/info/InfoViewModel.java
  12. 52
      app/src/main/java/com/community/pocket/util/HttpFileResponse.java
  13. 12
      app/src/main/java/com/community/pocket/util/HttpJSONResponse.java
  14. 23
      app/src/main/java/com/community/pocket/util/HttpUtil.java
  15. 139
      app/src/main/java/com/community/pocket/util/PermissionsUtils.java
  16. 4
      app/src/main/java/com/community/pocket/util/SimpleHttpParse.java
  17. 29
      app/src/main/res/layout/main/layout/info/layout/info_fragment.xml
  18. 6
      app/src/main/res/values-en-rUS/strings.xml
  19. 6
      app/src/main/res/values-zh-rCN/strings.xml
  20. 4
      app/src/main/res/values/boolean.xml
  21. 1
      app/src/main/res/values/integers.xml
  22. 6
      app/src/main/res/values/strings.xml

@ -3,6 +3,9 @@
package="com.community.pocket">
<!-- 添加网络访问权限-->
<uses-permission android:name="android.permission.INTERNET" />
<!-- 文件读写权限-->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:name=".util.InitApp"
android:allowBackup="true"

@ -31,11 +31,9 @@ public class ForumDataRequest {
public void sendReply(MutableLiveData<ForumDataResponse> liveData, String forumId, String content) {
HttpUtil.getRequest(HttpUtil.Method.POST,
new SimpleHttpParse<ForumDataResponse>(liveData).getInterface(ForumDataResponse.class),
new FormBody.Builder()
LocalToken.create()
.add("forumId", forumId)
.add("content", content)
.add("token", LocalToken.getToken())
.add("username", LocalToken.getUsername())
.build()
);
}

@ -34,15 +34,13 @@ public class ForumPostRequest {
public void sendActive(MutableLiveData<ForumPostResponse> liveData, String title, String content, String activeStartTime, String activeEndTime, String activeScore, String registrationDeadline) {
HttpUtil.getRequest(HttpUtil.Method.POST,
new SimpleHttpParse<ForumPostResponse>(liveData).getInterface(ForumPostResponse.class),
new FormBody.Builder()
LocalToken.create()
.add("title", title)
.add("content", content)
.add("registrationDeadline", registrationDeadline)
.add("activeStartTime", activeStartTime)
.add("activeEndTime", activeEndTime)
.add("activeScore", activeScore)
.add("token", LocalToken.getToken())
.add("username", LocalToken.getUsername())
.add("forumType", ForumType.active.name())
.build());
}
@ -52,12 +50,10 @@ public class ForumPostRequest {
public void sendComplain(MutableLiveData<ForumPostResponse> liveData, String title, String content, String complain) {
HttpUtil.getRequest(HttpUtil.Method.POST,
new SimpleHttpParse<ForumPostResponse>(liveData).getInterface(ForumPostResponse.class),
new FormBody.Builder()
LocalToken.create()
.add("title", title)
.add("content", content)
.add("complain", complain)
.add("token", LocalToken.getToken())
.add("username", LocalToken.getUsername())
.add("forumType", ForumType.complan.name())
.build());
}
@ -67,11 +63,9 @@ public class ForumPostRequest {
public void sendTopic(MutableLiveData<ForumPostResponse> liveData, String title, String content) {
HttpUtil.getRequest(HttpUtil.Method.POST,
new SimpleHttpParse<ForumPostResponse>(liveData).getInterface(ForumPostResponse.class),
new FormBody.Builder()
LocalToken.create()
.add("title", title)
.add("content", content)
.add("token", LocalToken.getToken())
.add("username", LocalToken.getUsername())
.add("forumType", ForumType.topic.name())
.build());
}
@ -92,12 +86,10 @@ public class ForumPostRequest {
public void sendScore(MutableLiveData<ForumPostResponse> liveData, String title, String content, String activeScore) {
HttpUtil.getRequest(HttpUtil.Method.POST,
new SimpleHttpParse<ForumPostResponse>(liveData).getInterface(ForumPostResponse.class),
new FormBody.Builder()
LocalToken.create()
.add("title", title)
.add("content", content)
.add("activeScore", activeScore)
.add("token", LocalToken.getToken())
.add("username", LocalToken.getUsername())
.add("forumType", ForumType.score.name())
.build());
}

@ -1,15 +1,21 @@
package com.community.pocket.data.main.info;
import android.graphics.Bitmap;
import androidx.lifecycle.MutableLiveData;
import com.community.pocket.data.model.LocalToken;
import com.community.pocket.ui.main.ui.info.InfoResponse;
import com.community.pocket.util.HttpFileResponse;
import com.community.pocket.util.HttpRequest;
import com.community.pocket.util.HttpUtil;
import com.community.pocket.util.SimpleHttpParse;
import okhttp3.FormBody;
import java.io.File;
import okhttp3.MediaType;
import okhttp3.RequestBody;
/**
* 个人信息请求接口
@ -32,11 +38,9 @@ public class InfoRequest {
public void modifyPwd(MutableLiveData<InfoResponse> liveData, String oldPassword, String newPassword) {
HttpUtil.getRequest(HttpUtil.Method.POST,
new SimpleHttpParse<InfoResponse>(liveData).getInterface(InfoResponse.class),
new FormBody.Builder()
LocalToken.create()
.add("oldPassword", oldPassword)
.add("newPassword", newPassword)
.add("token", LocalToken.getToken())
.add("username", LocalToken.getUsername())
.build());
}
@ -45,9 +49,20 @@ public class InfoRequest {
public void loadInfo(MutableLiveData<InfoResponse> liveData) {
HttpUtil.getRequest(HttpUtil.Method.GET,
new SimpleHttpParse<InfoResponse>(liveData).getInterface(InfoResponse.class),
new FormBody.Builder()
.add("token", LocalToken.getToken())
.add("username", LocalToken.getUsername())
LocalToken.create().build());
}
//上传头像
@HttpRequest("/uploadHeadImg")
public void uploadImg(MutableLiveData<InfoResponse> liveData, File picFile) {
HttpUtil.getRequest(new SimpleHttpParse<InfoResponse>(liveData).getInterface(InfoResponse.class),
LocalToken.createM()
.addFormDataPart("file", picFile.getName(), RequestBody.create(picFile, MediaType.parse("image/png")))
.build());
}
//获取头像
public void getImg(MutableLiveData<Bitmap> liveData, String url) {
HttpUtil.getRequest(new HttpFileResponse(liveData), url);
}
}

@ -31,9 +31,7 @@ public class VisitorMyRequest {
*/
@HttpRequest("/visitor/my")
public void loadMy(MutableLiveData<VisitorMyResponse> liveData, String startDate, String endDate, Long page) {
FormBody.Builder builder = new FormBody.Builder()
.add("username", LocalToken.getUsername())
.add("token", LocalToken.getToken());
FormBody.Builder builder = LocalToken.create();
if (startDate != null && !startDate.isEmpty()) {
builder.add("startDate", startDate);
}

@ -33,14 +33,12 @@ public class VisitorRequest {
public void appointment(MutableLiveData<VisitorResponse> liveData, String appointment, String chooseDate, String chooseTime, String notes, boolean checked) {
HttpUtil.getRequest(HttpUtil.Method.POST,
new SimpleHttpParse<VisitorResponse>(liveData).getInterface(VisitorResponse.class),
new FormBody.Builder()
LocalToken.create()
.add("appointment", appointment)
.add("chooseDate", chooseDate)
.add("chooseTime", chooseTime)
.add("notes", notes)
.add("isOutPeople", String.valueOf(checked))
.add("token", LocalToken.getToken())
.add("username", LocalToken.getUsername())
.build());
}

@ -31,9 +31,7 @@ public class VisitorReservationRequest {
*/
@HttpRequest("/visitor/reservation")
public void loadReservation(MutableLiveData<VisitorReservationResponse> liveData, String startDate, String endDate, Long currentPage) {
FormBody.Builder builder = new FormBody.Builder()
.add("username", LocalToken.getUsername())
.add("token", LocalToken.getToken());
FormBody.Builder builder = LocalToken.create();
if (startDate != null && !startDate.isEmpty()) {
builder.add("startDate", startDate);
}

@ -1,5 +1,8 @@
package com.community.pocket.data.model;
import okhttp3.FormBody;
import okhttp3.MultipartBody;
public class LocalToken {
private final String token;
private final Long time;
@ -47,4 +50,16 @@ public class LocalToken {
public static Token getTokenInstance() {
return tokenInstance;
}
public static FormBody.Builder create() {
return new FormBody.Builder()
.add("token", LocalToken.getToken())
.add("username", LocalToken.getUsername());
}
public static MultipartBody.Builder createM() {
return new MultipartBody.Builder()
.addFormDataPart("token", LocalToken.getToken())
.addFormDataPart("username", LocalToken.getUsername());
}
}

@ -27,8 +27,8 @@ import com.community.pocket.ui.main.ui.share.Response;
import com.community.pocket.ui.register.RegisterActivity;
import com.community.pocket.ui.resetpwd.ResetPwdActivity;
import com.community.pocket.util.AppDatabase;
import com.community.pocket.util.HttpJSONResponse;
import com.community.pocket.util.HttpRequest;
import com.community.pocket.util.HttpResponse;
import com.community.pocket.util.HttpUtil;
import com.community.pocket.util.PropertiesUtil;
@ -188,9 +188,10 @@ public class LoginActivity extends BaseActivity {
List<Token> tokenList = sInstance.tokenDao().queryAll();
if (tokenList != null && tokenList.size() == 1) {
Token currentToken = tokenList.get(0);
HttpUtil.getRequest(HttpUtil.Method.POST, new HttpResponse<>(LoginResponse.class, (call, response, loginResponse) -> loginViewModel.getCheckToken().postValue(loginResponse)),
HttpUtil.getRequest(HttpUtil.Method.POST, new HttpJSONResponse<>(LoginResponse.class, (call, response, loginResponse) -> loginViewModel.getCheckToken().postValue(loginResponse)),
new FormBody.Builder()
.add("token", currentToken.getToken())
.add("username", currentToken.getUsername())
.build()
);
} else if (tokenList != null && tokenList.size() > 1) {

@ -1,27 +1,36 @@
package com.community.pocket.ui.main.ui.info;
import android.Manifest;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Paint;
import android.graphics.Rect;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.provider.MediaStore;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AlertDialog;
import androidx.lifecycle.Observer;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModelProvider;
import com.community.pocket.R;
@ -34,6 +43,7 @@ import com.community.pocket.ui.login.LoginActivity;
import com.community.pocket.ui.main.ui.share.Response;
import com.community.pocket.util.AppDatabase;
import com.community.pocket.util.Param;
import com.community.pocket.util.PermissionsUtils;
import com.community.pocket.util.PropertiesUtil;
import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.Legend;
@ -49,6 +59,9 @@ import org.xutils.view.annotation.ContentView;
import org.xutils.view.annotation.Event;
import org.xutils.view.annotation.ViewInject;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@ -100,6 +113,7 @@ public class InfoFragment extends BaseFragment {
//确认新密码
private EditText confirmNewPwd;
//打开修改密码弹窗
@ViewInject(R.id.open_modify_password)
private Button openModify;
@ -110,7 +124,15 @@ public class InfoFragment extends BaseFragment {
@ViewInject(R.id.logout)
private Button logout;
private Handler handler;
//修改密码
private Handler modifyPwdHandler;
//上传头像
private Handler uploadImgHandler;
//检测是否有读写文件权限
private MutableLiveData<Boolean> bool = new MutableLiveData<>();
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
@Override
@ -124,82 +146,85 @@ public class InfoFragment extends BaseFragment {
viewModel.loadInfo();
//监听修改密码表单状态
viewModel.getModifyFormState().observe(getViewLifecycleOwner(), new Observer<InfoFormState>() {
@Override
public void onChanged(InfoFormState infoFormState) {
if (infoFormState == null) {
return;
}
if (infoFormState.getOldPwdError() != null) {
oldPwd.setError(getString(infoFormState.getOldPwdError(), PropertiesUtil.getIntValue("password.length")));
}
viewModel.getModifyFormState().observe(getViewLifecycleOwner(), infoFormState -> {
if (infoFormState == null) {
return;
}
if (infoFormState.getOldPwdError() != null) {
oldPwd.setError(getString(infoFormState.getOldPwdError(), PropertiesUtil.getIntValue("password.length")));
}
if (infoFormState.getNewPwdError() != null) {
if (infoFormState.getNewPwdError() == R.string.invalid_password) {
newPwd.setError(getString(infoFormState.getNewPwdError(), PropertiesUtil.getIntValue("password.length")));
} else {
newPwd.setError(getString(infoFormState.getNewPwdError()));
}
if (infoFormState.getNewPwdError() != null) {
if (infoFormState.getNewPwdError() == R.string.invalid_password) {
newPwd.setError(getString(infoFormState.getNewPwdError(), PropertiesUtil.getIntValue("password.length")));
} else {
newPwd.setError(getString(infoFormState.getNewPwdError()));
}
}
if (infoFormState.getConfirmNewPwdError() != null) {
if (infoFormState.getConfirmNewPwdError() == R.string.invalid_password) {
confirmNewPwd.setError(getString(infoFormState.getConfirmNewPwdError(), PropertiesUtil.getIntValue("password.length")));
} else {
confirmNewPwd.setError(getString(infoFormState.getConfirmNewPwdError()));
}
if (infoFormState.getConfirmNewPwdError() != null) {
if (infoFormState.getConfirmNewPwdError() == R.string.invalid_password) {
confirmNewPwd.setError(getString(infoFormState.getConfirmNewPwdError(), PropertiesUtil.getIntValue("password.length")));
} else {
confirmNewPwd.setError(getString(infoFormState.getConfirmNewPwdError()));
}
}
Message message = new Message();
Bundle bundle = new Bundle();
bundle.putBoolean(Param.enable.name(), infoFormState.isDataValid());
message.setData(bundle);
handler.sendMessage(message);
Message message = new Message();
Bundle bundle = new Bundle();
bundle.putBoolean(Param.enable.name(), infoFormState.isDataValid());
message.setData(bundle);
modifyPwdHandler.sendMessage(message);
}
});
//监听修改密码的请求状态
viewModel.getModifyResponse().observe(getViewLifecycleOwner(), new Observer<InfoResponse>() {
@Override
public void onChanged(InfoResponse infoResponse) {
if (infoResponse == null) {
return;
}
infoResponse.toast(getContext());
viewModel.getModifyResponse().observe(getViewLifecycleOwner(), infoResponse -> {
if (infoResponse == null) {
return;
}
if (infoResponse.getResult() == Response.Result.OK) {
logout(logout);
}
infoResponse.toast(getContext());
if (infoResponse.getResult() == Response.Result.OK) {
logout(logout);
}
});
//监听个人信息请求状态
viewModel.getInfoResponse().observe(getViewLifecycleOwner(), new Observer<InfoResponse>() {
@Override
public void onChanged(InfoResponse myInfoInfoResponse) {
if (myInfoInfoResponse == null) {
return;
}
viewModel.getInfoResponse().observe(getViewLifecycleOwner(), myInfoInfoResponse -> {
if (myInfoInfoResponse == null) {
return;
}
myInfoInfoResponse.toast(getContext());
myInfoInfoResponse.toast(getContext());
if (myInfoInfoResponse.getResult() == Response.Result.OK) {
loadInfo(myInfoInfoResponse.getMyInfo());
}
if (myInfoInfoResponse.getResult() == Response.Result.OK) {
loadInfo(myInfoInfoResponse.getMyInfo());
}
});
//打开修改密码弹窗
openModify.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
openModifyPassword();
openModify.setOnClickListener(v -> openModifyPassword());
checkPermissions();
clickHeadImg();
//监听上传头像状态
viewModel.getUploadImg().observe(getViewLifecycleOwner(), infoResponse -> {
if (infoResponse == null) {
return;
}
uploadImgHandler.sendEmptyMessage(infoResponse.getResult().ordinal());
infoResponse.toast(getContext());
});
//监听获取头像状态
viewModel.getGetImg().observe(getViewLifecycleOwner(), bitmap -> headimg.setImageBitmap(bitmap));
}
/**
@ -214,12 +239,194 @@ public class InfoFragment extends BaseFragment {
recentPosts.setText(getString(R.string.recent_posts, myInfo.getPosts()));
mobie.setText(myInfo.getMobie());
email.setText(myInfo.getEmail());
if (myInfo.getHeadImg() != null && !myInfo.getHeadImg().isEmpty()) {
viewModel.getImg(myInfo.getHeadImg());
}
if (myInfo.getScoreHistory() != null && myInfo.getScoreHistory().size() >= 2) {
loadChart(myInfo.getScoreHistory());
}
}
private enum Action {
//打开相册
OPEN_GALLERY,
//打开相机
OPEN_CAMERA,
//裁剪
CROP
}
/**
* 检查读写权限
*/
private void checkPermissions() {
PermissionsUtils.getInstance().checkPermissions(getActivity(), new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE},
new PermissionsUtils.IPermissionsResult() {
@Override
public void passPermissons() {
File file = getPhotoDir();
if (file.exists()) {
bool.postValue(true);
} else {
bool.postValue(false);
String msg = "无法创建照片目录";
Log.e(InfoFragment.class.getName(), msg);
throw new RuntimeException(msg);
}
}
@Override
public void forbitPermissons() {
bool.postValue(false);
}
});
}
/**
* 点击头像操作
*/
private void clickHeadImg() {
bool.observe(getViewLifecycleOwner(), aBoolean -> {
if (aBoolean) {
headimg.setOnClickListener(v -> new AlertDialog.Builder(Objects.requireNonNull(getContext()))
.setNegativeButton(R.string.open_photo_album, (dialog, which) -> {
// 打开相册
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
startActivityForResult(intent, Action.OPEN_GALLERY.ordinal());
})
.setNeutralButton(R.string.take_photo, (dialog, which) -> {
//定义图片存储的位置
File file = getPhotoDir();
File photoFile = new File(file, System.currentTimeMillis() + "origin.png");
Log.i(InfoFragment.class.getName(), "图片存储到" + photoFile.getAbsolutePath());
// 隐式意图打开系统界面 --要求回传
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// 存到什么位置
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
intent.putExtra(Action.OPEN_CAMERA.name(), photoFile);
startActivityForResult(intent, Action.OPEN_CAMERA.ordinal());
})
.setPositiveButton(R.string.action_close, (dialog, which) -> dialog.dismiss()).show());
} else {
headimg.setOnClickListener(v -> Toast.makeText(getContext(), R.string.not_permissions, Toast.LENGTH_LONG).show());
}
});
}
private File getPhotoDir() {
return new File(Environment.getExternalStorageDirectory(),
getString(R.string.app_name));
}
//打开裁剪应用
private Intent getCropIntent() {
return new Intent("com.android.camera.action.CROP");
}
//判断是否有裁剪应用
private boolean hasCrop() {
Context context = getContext();
return context != null && getCropIntent().resolveActivity(getContext().getPackageManager()) != null;
}
//设置头像
private void setHeadImg(Bitmap bitmap) {
File picFile = new File(getPhotoDir(), System.currentTimeMillis() + ".png");
try {
if (picFile.createNewFile()) {
bitmap.compress(Bitmap.CompressFormat.PNG, 100, new FileOutputStream(
picFile));
Context context = Objects.requireNonNull(getContext());
TextView textView = new TextView(context);
textView.setTextSize(18);
textView.setGravity(Gravity.CENTER | Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL);
textView.setText(R.string.upload_img);
AlertDialog alertDialog = new AlertDialog.Builder(context)
.setView(textView).show();
uploadImgHandler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(@NonNull Message msg) {
alertDialog.dismiss();
if (msg.what == Response.Result.OK.ordinal()) {
headimg.setImageBitmap(bitmap);
}
}
};
viewModel.uploadImg(picFile);
}
} catch (IOException e) {
e.printStackTrace();
Log.e(InfoFragment.class.getName(), e.toString());
}
}
// 手机自带裁剪功能--调用系统裁剪的意图
private void crop(Uri uri) {
// 定义图片裁剪意图
Intent intent = getCropIntent();
intent.setDataAndType(uri, "image/*");
// 设置是否裁剪
intent.putExtra("crop", "true");
// 裁剪框的比例
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
// 设置输出图片的尺寸大小
int size = getResources().getInteger(R.integer.photo_size);
intent.putExtra("outputX", size);
intent.putExtra("outputY", size);
// 设置图片格式
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.name());
//是否返回数据
intent.putExtra("return-data", true);
startActivityForResult(intent, Action.CROP.ordinal());
}
@Override
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
Log.i(InfoFragment.class.getName(), "requestCode:" + requestCode + ",resultCode:" + resultCode);
if (data != null) {
//获取路径
if (requestCode == Action.OPEN_GALLERY.ordinal() || requestCode == Action.OPEN_CAMERA.ordinal()) {
if (hasCrop()) {
crop(data.getData());
} else {
Context context = getContext();
if (context != null) {
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContext().getContentResolver(), data.getData());
setHeadImg(bitmap);
} catch (IOException e) {
e.printStackTrace();
Log.e(InfoFragment.class.getName(), e.toString());
}
} else {
Log.e(InfoFragment.class.getName(), "无法获取Context");
}
}
} else if (requestCode == Action.CROP.ordinal()) {
//直接拿到一张图片
Bitmap bitmap = data.getParcelableExtra("data");
if (bitmap != null) {
setHeadImg(bitmap);
} else {
Log.e(InfoFragment.class.getName(), "无法获取裁剪图片");
}
}
}
}
/**
* 打开修改密码弹窗
*/
@ -245,21 +452,13 @@ public class InfoFragment extends BaseFragment {
AlertDialog.Builder alert = new AlertDialog.Builder(Objects.requireNonNull(getContext()));
final AlertDialog alertDialog = alert.setTitle(R.string.modify_password).setView(view)
.setNegativeButton(R.string.modify_password, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
viewModel.modifyPwd(oldPwd.getText().toString(), newPwd.getText().toString());
dialog.dismiss();
}
})
.setNeutralButton(R.string.action_close, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
.setNegativeButton(R.string.modify_password, (dialog, which) -> {
viewModel.modifyPwd(oldPwd.getText().toString(), newPwd.getText().toString());
dialog.dismiss();
})
.setNeutralButton(R.string.action_close, (dialog, which) -> dialog.dismiss())
.create();
handler = new Handler(Looper.getMainLooper()) {
modifyPwdHandler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(@NonNull Message msg) {
alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE).setEnabled(msg.getData().getBoolean(Param.enable.name()));
@ -276,13 +475,10 @@ public class InfoFragment extends BaseFragment {
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
@Event(value = R.id.logout)
private void logout(final View view) {
new Thread(new Runnable() {
@Override
public void run() {
AppDatabase.getInstance(getContext()).tokenDao().delete(LocalToken.getTokenInstance());
LocalToken.logout();
startActivity(new Intent(view.getContext(), LoginActivity.class));
}
new Thread(() -> {
AppDatabase.getInstance(getContext()).tokenDao().delete(LocalToken.getTokenInstance());
LocalToken.logout();
startActivity(new Intent(view.getContext(), LoginActivity.class));
}).start();
}

@ -1,5 +1,7 @@
package com.community.pocket.ui.main.ui.info;
import android.graphics.Bitmap;
import androidx.lifecycle.MutableLiveData;
import com.community.pocket.R;
@ -7,6 +9,8 @@ import com.community.pocket.data.main.info.InfoRequest;
import com.community.pocket.ui.main.ui.share.BaseViewModel;
import com.community.pocket.util.ValidUtil;
import java.io.File;
//个人信息UI数据管理
public class InfoViewModel extends BaseViewModel<InfoRequest> {
@ -16,6 +20,12 @@ public class InfoViewModel extends BaseViewModel<InfoRequest> {
//修改密码请求状态
private MutableLiveData<InfoResponse> modifyResponse = new MutableLiveData<>();
//上传头像状态
private MutableLiveData<InfoResponse> uploadImg = new MutableLiveData<>();
//获取头像
private MutableLiveData<Bitmap> getImg = new MutableLiveData<>();
//个人信息请求状态
private MutableLiveData<InfoResponse> infoResponse = new MutableLiveData<>();
@ -31,6 +41,14 @@ public class InfoViewModel extends BaseViewModel<InfoRequest> {
return infoResponse;
}
MutableLiveData<Bitmap> getGetImg() {
return getImg;
}
MutableLiveData<InfoResponse> getUploadImg() {
return uploadImg;
}
//修改密码表单校验状态
void modifyPwdChanged(String oldpwd, String newpwd, String confirmNewPwd) {
if (!ValidUtil.passwordvalid(oldpwd)) {
@ -48,6 +66,11 @@ public class InfoViewModel extends BaseViewModel<InfoRequest> {
}
}
//上传头像
void uploadImg(File picFile) {
getRequest().uploadImg(uploadImg, picFile);
}
//修改密码
void modifyPwd(String oldpwd, String newpwd) {
getRequest().modifyPwd(modifyResponse, oldpwd, newpwd);
@ -58,6 +81,12 @@ public class InfoViewModel extends BaseViewModel<InfoRequest> {
getRequest().loadInfo(infoResponse);
}
//获取头像
void getImg(String url) {
getRequest().getImg(getImg, url);
}
@Override
protected InfoRequest getRequest() {
return InfoRequest.getInstance();

@ -0,0 +1,52 @@
package com.community.pocket.util;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import androidx.lifecycle.MutableLiveData;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Response;
import okhttp3.ResponseBody;
public class HttpFileResponse implements Callback {
private static final String header = "Content-Type";
private final MutableLiveData<Bitmap> image;
public HttpFileResponse(MutableLiveData<Bitmap> image) {
this.image = image;
}
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
e.printStackTrace();
Log.e(HttpJSONResponse.class.getName(), e.toString());
}
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) {
String contentType = response.header(header);
if ("image/png".equals(contentType)) {
ResponseBody responseBody = response.body();
if (responseBody != null) {
Bitmap bitmap = BitmapFactory.decodeStream(responseBody.byteStream());
image.postValue(bitmap);
}
} else {
onParseError(call, response, "接口不是响应图片数据,非法响应头" + header + "=" + contentType);
}
}
private void onParseError(@NotNull Call call, @NotNull Response response, String err) {
Log.e(HttpJSONResponse.class.getName(), err);
throw new RuntimeException(err);
}
}

@ -19,7 +19,7 @@ import okhttp3.ResponseBody;
*
* @param <T> 响应实体类型
*/
public class HttpResponse<T extends com.community.pocket.ui.main.ui.share.Response> implements Callback {
public class HttpJSONResponse<T extends com.community.pocket.ui.main.ui.share.Response> implements Callback {
private Class<T> tClass;
@ -27,7 +27,7 @@ public class HttpResponse<T extends com.community.pocket.ui.main.ui.share.Respon
private static final String header = "Content-Type";
public HttpResponse(Class<T> tClass, HttpParse<T> httpParse) {
public HttpJSONResponse(Class<T> tClass, HttpParse<T> httpParse) {
this.tClass = tClass;
this.httpParse = httpParse;
}
@ -35,7 +35,7 @@ public class HttpResponse<T extends com.community.pocket.ui.main.ui.share.Respon
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
e.printStackTrace();
Log.e(HttpResponse.class.getName(), e.toString());
Log.e(HttpJSONResponse.class.getName(), e.toString());
}
@Override
@ -54,9 +54,7 @@ public class HttpResponse<T extends com.community.pocket.ui.main.ui.share.Respon
} else {
onParseError(call, response, "无法把数据" + message + "解析为" + tClass + "类型");
}
} catch (JsonSyntaxException e) {
onParseError(call, response, "解析异常" + e);
} catch (IOException e) {
} catch (JsonSyntaxException | IOException e) {
onParseError(call, response, "解析异常" + e);
}
} else {
@ -69,7 +67,7 @@ public class HttpResponse<T extends com.community.pocket.ui.main.ui.share.Respon
private void onParseError(@NotNull Call call, @NotNull Response response, String err) {
Log.e(HttpResponse.class.getName(), err);
Log.e(HttpJSONResponse.class.getName(), err);
throw new RuntimeException(err);
}

@ -36,6 +36,7 @@ import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
public class HttpUtil {
@ -66,6 +67,28 @@ public class HttpUtil {
call.enqueue(callback);
}
public static void getRequest(Callback callback, RequestBody body) {
//1.创建OkHttpClient对象
OkHttpClient okHttpClient = new OkHttpClient();
//2.创建Request对象,设置一个url地址(百度地址),设置请求方式。
Request.Builder builder = new Request.Builder().url(BuildConfig.API_HOST + getUrl()).method(Method.POST.name(), body);
//3.创建一个call对象,参数就是Request请求对象
Call call = okHttpClient.newCall(builder.build());
//4.请求加入调度,重写回调方法
call.enqueue(callback);
}
public static void getRequest(Callback callback, String url) {
//1.创建OkHttpClient对象
OkHttpClient okHttpClient = new OkHttpClient();
//2.创建Request对象,设置一个url地址(百度地址),设置请求方式。
Request.Builder builder = new Request.Builder().url(BuildConfig.API_HOST + url).method(Method.GET.name(), null);
//3.创建一个call对象,参数就是Request请求对象
Call call = okHttpClient.newCall(builder.build());
//4.请求加入调度,重写回调方法
call.enqueue(callback);
}
//关闭弹窗
private static AlertDialog.Builder getBuilder(Context context) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);

@ -0,0 +1,139 @@
package com.community.pocket.util;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.provider.Settings;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import com.community.pocket.R;
import java.util.ArrayList;
import java.util.List;
public class PermissionsUtils<T> {
private final int mRequestCode = 100;//权限请求码
private PermissionsUtils() {
}
private static PermissionsUtils permissionsUtils;
private IPermissionsResult mPermissionsResult;
public static PermissionsUtils getInstance() {
if (permissionsUtils == null) {
permissionsUtils = new PermissionsUtils();
}
return permissionsUtils;
}
public void checkPermissions(Activity context, String[] permissions, @NonNull IPermissionsResult permissionsResult) {
mPermissionsResult = permissionsResult;
if (Build.VERSION.SDK_INT < 23) {//6.0才用动态权限
permissionsResult.passPermissons();
return;
}
//创建一个mPermissionList,逐个判断哪些权限未授予,未授予的权限存储到mPerrrmissionList中
List<String> mPermissionList = new ArrayList<>();
//逐个判断你要的权限是否已经通过
for (String permission : permissions) {
if (ContextCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
mPermissionList.add(permission);//添加还未授予的权限
}
}
//申请权限
if (mPermissionList.size() > 0) {//有权限没有通过,需要申请
ActivityCompat.requestPermissions(context, permissions, mRequestCode);
} else {
//说明权限都已经通过,可以做你想做的事情去
permissionsResult.passPermissons();
}
}
//请求权限后回调的方法
//参数: requestCode 是我们自己定义的权限请求码
//参数: permissions 是我们请求的权限名称数组
//参数: grantResults 是我们在弹出页面后是否允许权限的标识数组,数组的长度对应的是权限名称数组的长度,数组的数据0表示允许权限,-1表示我们点击了禁止权限
public void onRequestPermissionsResult(Activity context, int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
boolean hasPermissionDismiss = false;//有权限没有通过
if (mRequestCode == requestCode) {
for (int grantResult : grantResults) {
if (grantResult == -1) {
hasPermissionDismiss = true;
break;
}
}
//如果有权限没有被允许
if (hasPermissionDismiss) {
if (context.getResources().getBoolean(R.bool.showSystemSetting)) {
showSystemPermissionsSettingDialog(context);//跳转到系统设置权限页面,或者直接关闭页面,不让他继续访问
} else {
mPermissionsResult.forbitPermissons();
}
} else {
//全部权限通过,可以进行下一步操作。。。
mPermissionsResult.passPermissons();
}
}
}
/**
* 不再提示权限时的展示对话框
*/
private AlertDialog mPermissionDialog;
private void showSystemPermissionsSettingDialog(final Activity context) {
final String mPackName = context.getPackageName();
if (mPermissionDialog == null) {
mPermissionDialog = new AlertDialog.Builder(context)
.setMessage("已禁用权限,请手动授予")
.setPositiveButton("设置", (dialog, which) -> {
cancelPermissionDialog();
Uri packageURI = Uri.parse("package:" + mPackName);
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, packageURI);
context.startActivity(intent);
context.finish();
})
.setNegativeButton("取消", (dialog, which) -> {
//关闭页面或者做其他操作
cancelPermissionDialog();
//mContext.finish();
mPermissionsResult.forbitPermissons();
})
.create();
}
mPermissionDialog.show();
}
//关闭对话框
private void cancelPermissionDialog() {
if (mPermissionDialog != null) {
mPermissionDialog.cancel();
mPermissionDialog = null;
}
}
public interface IPermissionsResult {
void passPermissons();
void forbitPermissons();
}
}

@ -20,8 +20,8 @@ public class SimpleHttpParse<T extends com.community.pocket.ui.main.ui.share.Res
this.liveData = liveData;
}
public HttpResponse<T> getInterface(Class<T> tClass) {
return new HttpResponse<>(tClass, this);
public HttpJSONResponse<T> getInterface(Class<T> tClass) {
return new HttpJSONResponse<>(tClass, this);
}
@Override

@ -50,6 +50,17 @@
android:textSize="24sp"
app:layout_constraintStart_toEndOf="@id/headimg"
app:layout_constraintTop_toBottomOf="@id/nickname" />
<TextView
android:id="@+id/check_headimg"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/set_headimg"
android:textSize="24sp"
app:layout_constraintEnd_toEndOf="@id/headimg"
app:layout_constraintStart_toStartOf="@id/headimg"
app:layout_constraintTop_toBottomOf="@id/headimg" />
</androidx.constraintlayout.widget.ConstraintLayout>
<LinearLayout
@ -64,7 +75,8 @@
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/border"
android:gravity="center" />
android:gravity="center"
android:textSize="18sp" />
<TextView
android:id="@+id/recentVisitors"
@ -72,7 +84,8 @@
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/border"
android:gravity="center" />
android:gravity="center"
android:textSize="18sp" />
</LinearLayout>
<LinearLayout
@ -86,7 +99,8 @@
android:layout_weight="1"
android:background="@drawable/border"
android:gravity="center"
android:text="@string/mobie" />
android:text="@string/mobie"
android:textSize="18sp" />
<TextView
android:id="@+id/mobie"
@ -94,7 +108,8 @@
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/border"
android:gravity="center" />
android:gravity="center"
android:textSize="18sp" />
</LinearLayout>
<LinearLayout
@ -108,7 +123,8 @@
android:layout_weight="1"
android:background="@drawable/border"
android:gravity="center"
android:text="@string/email" />
android:text="@string/email"
android:textSize="18sp" />
<TextView
android:id="@+id/email"
@ -116,7 +132,8 @@
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/border"
android:gravity="center" />
android:gravity="center"
android:textSize="18sp" />
</LinearLayout>
<TextView

@ -230,4 +230,10 @@
<string name="load_more_forum_ok">load more forum OK</string>
<string name="no_more_data">no more data</string>
<string name="load_more_data_ok">load more data OK</string>
<string name="open_photo_album">open photo album</string>
<string name="take_photo">take photo</string>
<string name="unselected_photo">unselected any photo</string>
<string name="not_permissions">not permissions</string>
<string name="set_headimg">click to set headimg</string>
<string name="upload_img">upload img....</string>
</resources>

@ -230,4 +230,10 @@
<string name="load_more_forum_ok">成功加载更多帖子</string>
<string name="no_more_data">没有更多数据</string>
<string name="load_more_data_ok">成功加载更多数据</string>
<string name="open_photo_album">打开相册</string>
<string name="take_photo">拍照上传</string>
<string name="unselected_photo">没有选中任何照片</string>
<string name="not_permissions">你当前没有文件读写权限执行此操作</string>
<string name="set_headimg">点击上方设置头像</string>
<string name="upload_img">上传头像中。。。。</string>
</resources>

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="showSystemSetting">true</bool>
</resources>

@ -2,4 +2,5 @@
<resources>
<integer name="post_content">200</integer>
<integer name="post_content_maxLines">10</integer>
<integer name="photo_size">100</integer>
</resources>

@ -231,6 +231,12 @@
<string name="load_more_forum_ok">load more forum OK</string>
<string name="no_more_data">no more data</string>
<string name="load_more_data_ok">load more data OK</string>
<string name="open_photo_album">open photo album</string>
<string name="take_photo">take photo</string>
<string name="unselected_photo">unselected any photo</string>
<string name="not_permissions">not permissions</string>
<string name="set_headimg">click to set headimg</string>
<string name="upload_img">upload img....</string>
<!-- Strings used for fragments for navigation -->
<!-- Strings used for fragments for navigation -->

Loading…
Cancel
Save