添加从相册选择头像功能

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"> package="com.community.pocket">
<!-- 添加网络访问权限--> <!-- 添加网络访问权限-->
<uses-permission android:name="android.permission.INTERNET" /> <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 <application
android:name=".util.InitApp" android:name=".util.InitApp"
android:allowBackup="true" android:allowBackup="true"

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

@ -1,15 +1,21 @@
package com.community.pocket.data.main.info; package com.community.pocket.data.main.info;
import android.graphics.Bitmap;
import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.MutableLiveData;
import com.community.pocket.data.model.LocalToken; import com.community.pocket.data.model.LocalToken;
import com.community.pocket.ui.main.ui.info.InfoResponse; 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.HttpRequest;
import com.community.pocket.util.HttpUtil; import com.community.pocket.util.HttpUtil;
import com.community.pocket.util.SimpleHttpParse; 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) { public void modifyPwd(MutableLiveData<InfoResponse> liveData, String oldPassword, String newPassword) {
HttpUtil.getRequest(HttpUtil.Method.POST, HttpUtil.getRequest(HttpUtil.Method.POST,
new SimpleHttpParse<InfoResponse>(liveData).getInterface(InfoResponse.class), new SimpleHttpParse<InfoResponse>(liveData).getInterface(InfoResponse.class),
new FormBody.Builder() LocalToken.create()
.add("oldPassword", oldPassword) .add("oldPassword", oldPassword)
.add("newPassword", newPassword) .add("newPassword", newPassword)
.add("token", LocalToken.getToken())
.add("username", LocalToken.getUsername())
.build()); .build());
} }
@ -45,9 +49,20 @@ public class InfoRequest {
public void loadInfo(MutableLiveData<InfoResponse> liveData) { public void loadInfo(MutableLiveData<InfoResponse> liveData) {
HttpUtil.getRequest(HttpUtil.Method.GET, HttpUtil.getRequest(HttpUtil.Method.GET,
new SimpleHttpParse<InfoResponse>(liveData).getInterface(InfoResponse.class), new SimpleHttpParse<InfoResponse>(liveData).getInterface(InfoResponse.class),
new FormBody.Builder() LocalToken.create().build());
.add("token", LocalToken.getToken()) }
.add("username", LocalToken.getUsername())
//上传头像
@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()); .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") @HttpRequest("/visitor/my")
public void loadMy(MutableLiveData<VisitorMyResponse> liveData, String startDate, String endDate, Long page) { public void loadMy(MutableLiveData<VisitorMyResponse> liveData, String startDate, String endDate, Long page) {
FormBody.Builder builder = new FormBody.Builder() FormBody.Builder builder = LocalToken.create();
.add("username", LocalToken.getUsername())
.add("token", LocalToken.getToken());
if (startDate != null && !startDate.isEmpty()) { if (startDate != null && !startDate.isEmpty()) {
builder.add("startDate", startDate); 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) { public void appointment(MutableLiveData<VisitorResponse> liveData, String appointment, String chooseDate, String chooseTime, String notes, boolean checked) {
HttpUtil.getRequest(HttpUtil.Method.POST, HttpUtil.getRequest(HttpUtil.Method.POST,
new SimpleHttpParse<VisitorResponse>(liveData).getInterface(VisitorResponse.class), new SimpleHttpParse<VisitorResponse>(liveData).getInterface(VisitorResponse.class),
new FormBody.Builder() LocalToken.create()
.add("appointment", appointment) .add("appointment", appointment)
.add("chooseDate", chooseDate) .add("chooseDate", chooseDate)
.add("chooseTime", chooseTime) .add("chooseTime", chooseTime)
.add("notes", notes) .add("notes", notes)
.add("isOutPeople", String.valueOf(checked)) .add("isOutPeople", String.valueOf(checked))
.add("token", LocalToken.getToken())
.add("username", LocalToken.getUsername())
.build()); .build());
} }

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

@ -1,5 +1,8 @@
package com.community.pocket.data.model; package com.community.pocket.data.model;
import okhttp3.FormBody;
import okhttp3.MultipartBody;
public class LocalToken { public class LocalToken {
private final String token; private final String token;
private final Long time; private final Long time;
@ -47,4 +50,16 @@ public class LocalToken {
public static Token getTokenInstance() { public static Token getTokenInstance() {
return tokenInstance; 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.register.RegisterActivity;
import com.community.pocket.ui.resetpwd.ResetPwdActivity; import com.community.pocket.ui.resetpwd.ResetPwdActivity;
import com.community.pocket.util.AppDatabase; import com.community.pocket.util.AppDatabase;
import com.community.pocket.util.HttpJSONResponse;
import com.community.pocket.util.HttpRequest; import com.community.pocket.util.HttpRequest;
import com.community.pocket.util.HttpResponse;
import com.community.pocket.util.HttpUtil; import com.community.pocket.util.HttpUtil;
import com.community.pocket.util.PropertiesUtil; import com.community.pocket.util.PropertiesUtil;
@ -188,9 +188,10 @@ public class LoginActivity extends BaseActivity {
List<Token> tokenList = sInstance.tokenDao().queryAll(); List<Token> tokenList = sInstance.tokenDao().queryAll();
if (tokenList != null && tokenList.size() == 1) { if (tokenList != null && tokenList.size() == 1) {
Token currentToken = tokenList.get(0); 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() new FormBody.Builder()
.add("token", currentToken.getToken()) .add("token", currentToken.getToken())
.add("username", currentToken.getUsername())
.build() .build()
); );
} else if (tokenList != null && tokenList.size() > 1) { } else if (tokenList != null && tokenList.size() > 1) {

@ -1,27 +1,36 @@
package com.community.pocket.ui.main.ui.info; package com.community.pocket.ui.main.ui.info;
import android.Manifest;
import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.Rect; import android.graphics.Rect;
import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.Environment;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.os.Message; import android.os.Message;
import android.provider.MediaStore;
import android.text.Editable; import android.text.Editable;
import android.text.TextWatcher; import android.text.TextWatcher;
import android.util.Log;
import android.view.Gravity;
import android.view.View; import android.view.View;
import android.widget.Button; import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi; import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.lifecycle.Observer; import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
import com.community.pocket.R; 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.ui.main.ui.share.Response;
import com.community.pocket.util.AppDatabase; import com.community.pocket.util.AppDatabase;
import com.community.pocket.util.Param; import com.community.pocket.util.Param;
import com.community.pocket.util.PermissionsUtils;
import com.community.pocket.util.PropertiesUtil; import com.community.pocket.util.PropertiesUtil;
import com.github.mikephil.charting.charts.LineChart; import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.Legend; 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.Event;
import org.xutils.view.annotation.ViewInject; 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.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
@ -100,6 +113,7 @@ public class InfoFragment extends BaseFragment {
//确认新密码 //确认新密码
private EditText confirmNewPwd; private EditText confirmNewPwd;
//打开修改密码弹窗 //打开修改密码弹窗
@ViewInject(R.id.open_modify_password) @ViewInject(R.id.open_modify_password)
private Button openModify; private Button openModify;
@ -110,7 +124,15 @@ public class InfoFragment extends BaseFragment {
@ViewInject(R.id.logout) @ViewInject(R.id.logout)
private Button 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) @RequiresApi(api = Build.VERSION_CODES.KITKAT)
@Override @Override
@ -124,82 +146,85 @@ public class InfoFragment extends BaseFragment {
viewModel.loadInfo(); viewModel.loadInfo();
//监听修改密码表单状态 //监听修改密码表单状态
viewModel.getModifyFormState().observe(getViewLifecycleOwner(), new Observer<InfoFormState>() { viewModel.getModifyFormState().observe(getViewLifecycleOwner(), infoFormState -> {
@Override if (infoFormState == null) {
public void onChanged(InfoFormState infoFormState) { return;
if (infoFormState == null) { }
return; if (infoFormState.getOldPwdError() != null) {
} oldPwd.setError(getString(infoFormState.getOldPwdError(), PropertiesUtil.getIntValue("password.length")));
if (infoFormState.getOldPwdError() != null) { }
oldPwd.setError(getString(infoFormState.getOldPwdError(), PropertiesUtil.getIntValue("password.length")));
}
if (infoFormState.getNewPwdError() != null) { if (infoFormState.getNewPwdError() != null) {
if (infoFormState.getNewPwdError() == R.string.invalid_password) { if (infoFormState.getNewPwdError() == R.string.invalid_password) {
newPwd.setError(getString(infoFormState.getNewPwdError(), PropertiesUtil.getIntValue("password.length"))); newPwd.setError(getString(infoFormState.getNewPwdError(), PropertiesUtil.getIntValue("password.length")));
} else { } else {
newPwd.setError(getString(infoFormState.getNewPwdError())); newPwd.setError(getString(infoFormState.getNewPwdError()));
}
} }
}
if (infoFormState.getConfirmNewPwdError() != null) { if (infoFormState.getConfirmNewPwdError() != null) {
if (infoFormState.getConfirmNewPwdError() == R.string.invalid_password) { if (infoFormState.getConfirmNewPwdError() == R.string.invalid_password) {
confirmNewPwd.setError(getString(infoFormState.getConfirmNewPwdError(), PropertiesUtil.getIntValue("password.length"))); confirmNewPwd.setError(getString(infoFormState.getConfirmNewPwdError(), PropertiesUtil.getIntValue("password.length")));
} else { } else {
confirmNewPwd.setError(getString(infoFormState.getConfirmNewPwdError())); confirmNewPwd.setError(getString(infoFormState.getConfirmNewPwdError()));
}
} }
}
Message message = new Message(); Message message = new Message();
Bundle bundle = new Bundle(); Bundle bundle = new Bundle();
bundle.putBoolean(Param.enable.name(), infoFormState.isDataValid()); bundle.putBoolean(Param.enable.name(), infoFormState.isDataValid());
message.setData(bundle); message.setData(bundle);
handler.sendMessage(message); modifyPwdHandler.sendMessage(message);
}
}); });
//监听修改密码的请求状态 //监听修改密码的请求状态
viewModel.getModifyResponse().observe(getViewLifecycleOwner(), new Observer<InfoResponse>() { viewModel.getModifyResponse().observe(getViewLifecycleOwner(), infoResponse -> {
@Override if (infoResponse == null) {
public void onChanged(InfoResponse infoResponse) { return;
if (infoResponse == null) { }
return;
}
infoResponse.toast(getContext());
if (infoResponse.getResult() == Response.Result.OK) { infoResponse.toast(getContext());
logout(logout);
}
if (infoResponse.getResult() == Response.Result.OK) {
logout(logout);
} }
}); });
//监听个人信息请求状态 //监听个人信息请求状态
viewModel.getInfoResponse().observe(getViewLifecycleOwner(), new Observer<InfoResponse>() { viewModel.getInfoResponse().observe(getViewLifecycleOwner(), myInfoInfoResponse -> {
@Override if (myInfoInfoResponse == null) {
public void onChanged(InfoResponse myInfoInfoResponse) { return;
if (myInfoInfoResponse == null) { }
return;
}
myInfoInfoResponse.toast(getContext()); myInfoInfoResponse.toast(getContext());
if (myInfoInfoResponse.getResult() == Response.Result.OK) { if (myInfoInfoResponse.getResult() == Response.Result.OK) {
loadInfo(myInfoInfoResponse.getMyInfo()); loadInfo(myInfoInfoResponse.getMyInfo());
}
} }
}); });
//打开修改密码弹窗 //打开修改密码弹窗
openModify.setOnClickListener(new View.OnClickListener() { openModify.setOnClickListener(v -> openModifyPassword());
@Override
public void onClick(View v) { checkPermissions();
openModifyPassword();
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())); recentPosts.setText(getString(R.string.recent_posts, myInfo.getPosts()));
mobie.setText(myInfo.getMobie()); mobie.setText(myInfo.getMobie());
email.setText(myInfo.getEmail()); email.setText(myInfo.getEmail());
if (myInfo.getHeadImg() != null && !myInfo.getHeadImg().isEmpty()) {
viewModel.getImg(myInfo.getHeadImg());
}
if (myInfo.getScoreHistory() != null && myInfo.getScoreHistory().size() >= 2) { if (myInfo.getScoreHistory() != null && myInfo.getScoreHistory().size() >= 2) {
loadChart(myInfo.getScoreHistory()); 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())); AlertDialog.Builder alert = new AlertDialog.Builder(Objects.requireNonNull(getContext()));
final AlertDialog alertDialog = alert.setTitle(R.string.modify_password).setView(view) final AlertDialog alertDialog = alert.setTitle(R.string.modify_password).setView(view)
.setNegativeButton(R.string.modify_password, new DialogInterface.OnClickListener() { .setNegativeButton(R.string.modify_password, (dialog, which) -> {
@Override viewModel.modifyPwd(oldPwd.getText().toString(), newPwd.getText().toString());
public void onClick(DialogInterface dialog, int which) { dialog.dismiss();
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();
}
}) })
.setNeutralButton(R.string.action_close, (dialog, which) -> dialog.dismiss())
.create(); .create();
handler = new Handler(Looper.getMainLooper()) { modifyPwdHandler = new Handler(Looper.getMainLooper()) {
@Override @Override
public void handleMessage(@NonNull Message msg) { public void handleMessage(@NonNull Message msg) {
alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE).setEnabled(msg.getData().getBoolean(Param.enable.name())); 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) @RequiresApi(api = Build.VERSION_CODES.KITKAT)
@Event(value = R.id.logout) @Event(value = R.id.logout)
private void logout(final View view) { private void logout(final View view) {
new Thread(new Runnable() { new Thread(() -> {
@Override AppDatabase.getInstance(getContext()).tokenDao().delete(LocalToken.getTokenInstance());
public void run() { LocalToken.logout();
AppDatabase.getInstance(getContext()).tokenDao().delete(LocalToken.getTokenInstance()); startActivity(new Intent(view.getContext(), LoginActivity.class));
LocalToken.logout();
startActivity(new Intent(view.getContext(), LoginActivity.class));
}
}).start(); }).start();
} }

@ -1,5 +1,7 @@
package com.community.pocket.ui.main.ui.info; package com.community.pocket.ui.main.ui.info;
import android.graphics.Bitmap;
import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.MutableLiveData;
import com.community.pocket.R; 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.ui.main.ui.share.BaseViewModel;
import com.community.pocket.util.ValidUtil; import com.community.pocket.util.ValidUtil;
import java.io.File;
//个人信息UI数据管理 //个人信息UI数据管理
public class InfoViewModel extends BaseViewModel<InfoRequest> { 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> modifyResponse = new MutableLiveData<>();
//上传头像状态
private MutableLiveData<InfoResponse> uploadImg = new MutableLiveData<>();
//获取头像
private MutableLiveData<Bitmap> getImg = new MutableLiveData<>();
//个人信息请求状态 //个人信息请求状态
private MutableLiveData<InfoResponse> infoResponse = new MutableLiveData<>(); private MutableLiveData<InfoResponse> infoResponse = new MutableLiveData<>();
@ -31,6 +41,14 @@ public class InfoViewModel extends BaseViewModel<InfoRequest> {
return infoResponse; return infoResponse;
} }
MutableLiveData<Bitmap> getGetImg() {
return getImg;
}
MutableLiveData<InfoResponse> getUploadImg() {
return uploadImg;
}
//修改密码表单校验状态 //修改密码表单校验状态
void modifyPwdChanged(String oldpwd, String newpwd, String confirmNewPwd) { void modifyPwdChanged(String oldpwd, String newpwd, String confirmNewPwd) {
if (!ValidUtil.passwordvalid(oldpwd)) { 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) { void modifyPwd(String oldpwd, String newpwd) {
getRequest().modifyPwd(modifyResponse, oldpwd, newpwd); getRequest().modifyPwd(modifyResponse, oldpwd, newpwd);
@ -58,6 +81,12 @@ public class InfoViewModel extends BaseViewModel<InfoRequest> {
getRequest().loadInfo(infoResponse); getRequest().loadInfo(infoResponse);
} }
//获取头像
void getImg(String url) {
getRequest().getImg(getImg, url);
}
@Override @Override
protected InfoRequest getRequest() { protected InfoRequest getRequest() {
return InfoRequest.getInstance(); 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> 响应实体类型 * @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; 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"; 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.tClass = tClass;
this.httpParse = httpParse; this.httpParse = httpParse;
} }
@ -35,7 +35,7 @@ public class HttpResponse<T extends com.community.pocket.ui.main.ui.share.Respon
@Override @Override
public void onFailure(@NotNull Call call, @NotNull IOException e) { public void onFailure(@NotNull Call call, @NotNull IOException e) {
e.printStackTrace(); e.printStackTrace();
Log.e(HttpResponse.class.getName(), e.toString()); Log.e(HttpJSONResponse.class.getName(), e.toString());
} }
@Override @Override
@ -54,9 +54,7 @@ public class HttpResponse<T extends com.community.pocket.ui.main.ui.share.Respon
} else { } else {
onParseError(call, response, "无法把数据" + message + "解析为" + tClass + "类型"); onParseError(call, response, "无法把数据" + message + "解析为" + tClass + "类型");
} }
} catch (JsonSyntaxException e) { } catch (JsonSyntaxException | IOException e) {
onParseError(call, response, "解析异常" + e);
} catch (IOException e) {
onParseError(call, response, "解析异常" + e); onParseError(call, response, "解析异常" + e);
} }
} else { } 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) { 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); throw new RuntimeException(err);
} }

@ -36,6 +36,7 @@ import okhttp3.Callback;
import okhttp3.FormBody; import okhttp3.FormBody;
import okhttp3.OkHttpClient; import okhttp3.OkHttpClient;
import okhttp3.Request; import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response; import okhttp3.Response;
public class HttpUtil { public class HttpUtil {
@ -66,6 +67,28 @@ public class HttpUtil {
call.enqueue(callback); 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) { private static AlertDialog.Builder getBuilder(Context context) {
AlertDialog.Builder builder = new AlertDialog.Builder(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; this.liveData = liveData;
} }
public HttpResponse<T> getInterface(Class<T> tClass) { public HttpJSONResponse<T> getInterface(Class<T> tClass) {
return new HttpResponse<>(tClass, this); return new HttpJSONResponse<>(tClass, this);
} }
@Override @Override

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

@ -230,4 +230,10 @@
<string name="load_more_forum_ok">load more forum OK</string> <string name="load_more_forum_ok">load more forum OK</string>
<string name="no_more_data">no more data</string> <string name="no_more_data">no more data</string>
<string name="load_more_data_ok">load more data OK</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> </resources>

@ -230,4 +230,10 @@
<string name="load_more_forum_ok">成功加载更多帖子</string> <string name="load_more_forum_ok">成功加载更多帖子</string>
<string name="no_more_data">没有更多数据</string> <string name="no_more_data">没有更多数据</string>
<string name="load_more_data_ok">成功加载更多数据</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> </resources>

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

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

@ -231,6 +231,12 @@
<string name="load_more_forum_ok">load more forum OK</string> <string name="load_more_forum_ok">load more forum OK</string>
<string name="no_more_data">no more data</string> <string name="no_more_data">no more data</string>
<string name="load_more_data_ok">load more data OK</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 -->
<!-- Strings used for fragments for navigation --> <!-- Strings used for fragments for navigation -->

Loading…
Cancel
Save