app/build.gradle
@@ -128,12 +128,12 @@ implementation 'com.android.support:multidex:1.0.3' implementation 'androidx.webkit:webkit:1.3.0'//3.6.15版本之后 必须集成,用来支持暗黑模式 //********UniSDK必须添加的依赖 end******** //NanoHTTPD搭建服务器 implementation 'org.nanohttpd:nanohttpd:2.3.1' //Apache FileUtils 第三方工具类 implementation 'commons-io:commons-io:2.11.0' //权限请求框架 implementation 'com.github.getActivity:XXPermissions:12.8' } app/src/main/AndroidManifest.xml
@@ -68,13 +68,13 @@ android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:requestLegacyExternalStorage="true" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.PhotovoltaicDebug"> <activity android:name=".ui.me.PersonalDataActivity" android:exported="false" /> android:exported="false" /> <service android:name=".widget.apkwgtupload.ApkDownLoadService" /> @@ -128,6 +128,11 @@ <meta-data android:name="design_width_in_dp" android:value="375" /> <!--不加这个作用域上去打开相册的是闪退--> <meta-data android:name="ScopedStorage" android:value="true" /> </application> </manifest> app/src/main/java/com/hdl/photovoltaic/HDLApp.java
@@ -66,12 +66,13 @@ super.onCreate(); mHDLApp = this; SharedPreUtils.init(this); getAppLanguage(); initThirdSDK(); } public void getAppLanguage() { String language = SharedPreUtils.getSharedPreferencesKey("language", this); String language = SharedPreUtils.getSharedPreferencesKey("language"); if (TextUtils.isEmpty(language)) { //从内存里面获取不到语言,获取当前系统的; String str = getResources().getConfiguration().locale.getCountry(); app/src/main/java/com/hdl/photovoltaic/other/HdlDeviceLogic.java
@@ -564,7 +564,7 @@ /** * 获取逆变器列表(整合云端和本地列表) * 注意:有外网以云端设备为准,本地存在,云端没有则删除;内网以本地为主,搜索多少个设备就显示多少个; * 注意:有外网,以云端设备为准,本地存在,云端没有则删除;内网,以本地为主,搜索多少个设备就显示多少个; * * @param cloudCallBeak 返回逆变器列表 */ app/src/main/java/com/hdl/photovoltaic/ui/MyPowerStationActivity.java
@@ -1,10 +1,12 @@ package com.hdl.photovoltaic.ui; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.content.res.AppCompatResources; import android.Manifest; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; import android.content.pm.PackageManager; import android.os.Bundle; @@ -324,6 +326,8 @@ } /** * 点击返回键的事件 */ app/src/main/java/com/hdl/photovoltaic/ui/me/AsRegardsActivity.java
@@ -27,7 +27,7 @@ import com.hdl.photovoltaic.widget.UpdateConfirmationCancelDialog; /** * 关于界面 * 关于界面(app更新) */ public class AsRegardsActivity extends CustomBaseActivity { app/src/main/java/com/hdl/photovoltaic/ui/me/MeFragment.java
@@ -5,6 +5,8 @@ import android.view.View; import androidx.annotation.Nullable; import com.bumptech.glide.load.resource.bitmap.RoundedCorners; import com.hdl.linkpm.sdk.core.exception.HDLException; import com.hdl.photovoltaic.R; @@ -131,7 +133,7 @@ Intent intent = new Intent(); intent.setClass(_mActivity, PersonalDataActivity.class); intent.putExtra("memberHeadIcon", mC_UserInfo.getMemberHeadIcon()); startActivity(intent); startActivityForResult(intent, 10); } }); viewBinding.fragmentMeLineSetIl.fragmentMeLineRightIconClickIv.setOnClickListener(new View.OnClickListener() { @@ -176,7 +178,7 @@ if (cUserInfo != null) { //C端 userName = cUserInfo.getMemberName(); GlideUtils.getRoundedCornersImage(_mActivity, cUserInfo.getMemberHeadIcon(), viewBinding.fragmentMeIconIv, new RoundedCorners(4)); setMemberHeadIcon(cUserInfo.getMemberHeadIcon()); } viewBinding.fragmentMeUserNameIv.setText(userName); UserConfigManage.getInstance().setUserName(userName); @@ -222,4 +224,25 @@ } public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == 10 && resultCode == 10) { if (data != null) { String url = data.getStringExtra("memberHeadIcon"); setMemberHeadIcon(url); } } } /** * 显示用户头像 */ private void setMemberHeadIcon(String memberHeadIconUrl) { if (mC_UserInfo != null) { mC_UserInfo.setMemberHeadIcon(memberHeadIconUrl); } GlideUtils.getRoundedCornersImage(_mActivity, memberHeadIconUrl, viewBinding.fragmentMeIconIv, new RoundedCorners(4)); } } app/src/main/java/com/hdl/photovoltaic/ui/me/PersonalDataActivity.java
@@ -1,11 +1,19 @@ package com.hdl.photovoltaic.ui.me; import android.app.AppComponentFactory; import android.Manifest; import android.content.Intent; import android.os.Build; import android.os.Bundle; import android.view.Gravity; import android.view.View; import com.bumptech.glide.load.resource.bitmap.RoundedCorners; import com.google.gson.JsonObject; import com.hdl.linkpm.sdk.core.callback.IDefaultCallBack; import com.hdl.linkpm.sdk.core.callback.IResponseCallBack; import com.hdl.linkpm.sdk.core.exception.HDLException; import com.hdl.linkpm.sdk.user.HDLLinkPMUser; import com.hdl.linkpm.sdk.user.bean.ImageSubmitInfo; import com.hdl.photovoltaic.R; import com.hdl.photovoltaic.base.CustomBaseActivity; @@ -13,9 +21,14 @@ import com.hdl.photovoltaic.databinding.ActivityPersonalDataBinding; import com.hdl.photovoltaic.listener.CloudCallBeak; import com.hdl.photovoltaic.other.HdlAccountLogic; import com.hdl.photovoltaic.other.HdlLogLogic; import com.hdl.photovoltaic.other.HdlThreadLogic; import com.hdl.photovoltaic.utils.GlideUtils; import com.hdl.photovoltaic.utils.PermissionUtils; import com.hdl.photovoltaic.widget.ConfirmationInputDialog; import com.hdl.photovoltaic.widget.popupview.CameraAlbumPopWindow; import java.io.File; /** @@ -23,8 +36,11 @@ */ public class PersonalDataActivity extends CustomBaseActivity { private ActivityPersonalDataBinding viewBinding; private CameraAlbumPopWindow cameraAlbumPopWindow; //头像地址 private String mMemberHeadIcon; private String mMemberHeadIconUrl; @Override public Object getContentView() { @@ -36,7 +52,7 @@ public void onBindView(Bundle savedInstanceState) { setNotificationBarBackgroundColor(CustomColor.white); setStatusBarTextColor(); mMemberHeadIcon = getIntent().getStringExtra("memberHeadIcon"); mMemberHeadIconUrl = getIntent().getStringExtra("memberHeadIcon"); //初始化 initView(); //初始化界面监听器 @@ -46,16 +62,40 @@ } private void initData() { viewBinding.toolbarTopFragmentMeRl.topBackBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { finish(); } }); } private void initEvent() { viewBinding.toolbarTopFragmentMeRl.topBackBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //数据是使用Intent返回 Intent intent = new Intent(); //把返回数据存入Intent intent.putExtra("memberHeadIcon", mMemberHeadIconUrl); //设置返回数据 setResult(10, intent); finish(); } }); viewBinding.personalDataUserPortraitIl.getRoot().setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //Manifest.permission.WRITE_EXTERNAL_STORAGE 读写设备上的照片以及文件 PermissionUtils.applyForRight(_mActivity, Manifest.permission.WRITE_EXTERNAL_STORAGE, new PermissionUtils.PermissionState() { @Override public void Success(int value) { if (value == PermissionUtils.STATUS_REFUSE_PERMANENT) { HdlThreadLogic.toast(_mActivity, R.string.permission_open); return; } changedUserAvatar(); } }); } }); viewBinding.personalDataUserNameIl.getRoot().setOnClickListener(new View.OnClickListener() { @Override @@ -63,6 +103,7 @@ changedNickname(); } }); } @@ -74,9 +115,53 @@ viewBinding.personalDataUserPortraitIl.sllLlRlNameTv.setText(R.string.me_personal_data_portrait); viewBinding.personalDataUserNameIl.sllLlRlNameTv.setText(R.string.me_personal_data_user_name); viewBinding.personalDataUserPortraitIl.sllLlRlRightContentIv.setVisibility(View.VISIBLE); GlideUtils.getRoundedCornersImage(_mActivity, this.mMemberHeadIcon, viewBinding.personalDataUserPortraitIl.sllLlRlRightContentIv, new RoundedCorners(4)); viewBinding.personalDataUserNameIl.sllLlRlRightContentTv.setVisibility(View.VISIBLE); viewBinding.personalDataUserNameIl.sllLlRlRightContentTv.setText(UserConfigManage.getInstance().getUserName()); setMemberHeadIcon(); } /** * 更改用户头像; */ private void changedUserAvatar() { if (UserConfigManage.getInstance().isBAccount()) { //todo B端不支持更改昵称 HdlThreadLogic.toast(_mActivity, R.string.loading_not_supported); } else { cameraAlbumPopWindow = new CameraAlbumPopWindow(_mActivity, new CameraAlbumPopWindow.CameraAlbumListener() { @Override public void successCallBack(final File a) { HDLLinkPMUser.getInstance().uploadUserHeadImage(a, new IResponseCallBack<ImageSubmitInfo>() { @Override public void onSuccess(ImageSubmitInfo imageKey) { JsonObject imageInfo = new JsonObject(); imageInfo.addProperty("memberHeadIcon", imageKey.getUrl()); HDLLinkPMUser.getInstance().updateMemberInfo(imageInfo, new IDefaultCallBack() { @Override public void onSuccess() { mMemberHeadIconUrl = imageKey.getUrl(); setMemberHeadIcon(); } @Override public void onFailure(HDLException error) { HdlLogLogic.print("uploadUserHeadImage error:" + error.getMsg()); // hideLoading(); } }); } @Override public void onFailure(HDLException error) { HdlLogLogic.print("uploadUserHeadImage error:" + error.getMsg()); } }); } }); cameraAlbumPopWindow.show(viewBinding.getRoot(), Gravity.BOTTOM, 0, 0); } } @@ -86,6 +171,7 @@ private void changedNickname() { if (UserConfigManage.getInstance().isBAccount()) { //todo B端不支持更改昵称 HdlThreadLogic.toast(_mActivity, R.string.loading_not_supported); } else { ConfirmationInputDialog confirmationInputDialog = new ConfirmationInputDialog(_mActivity); confirmationInputDialog.setTitle(getString(R.string.set_nickname_modification)); @@ -121,4 +207,46 @@ } } /** * 显示用户头像 */ private void setMemberHeadIcon() { GlideUtils.getRoundedCornersImage(_mActivity, mMemberHeadIconUrl, viewBinding.personalDataUserPortraitIl.sllLlRlRightContentIv, new RoundedCorners(4)); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == CameraAlbumPopWindow.TAKE_PHOTO || requestCode == CameraAlbumPopWindow.SELECT_PHOTO) { if (cameraAlbumPopWindow == null) { return; } switch (requestCode) { //打开相机后返回 case CameraAlbumPopWindow.TAKE_PHOTO: if (resultCode == RESULT_OK) { //这种方法是通过内存卡的路径进行读取图片,所以的到的图片是拍摄的原图 cameraAlbumPopWindow.displayImage(); } break; //打开相册后返回 case CameraAlbumPopWindow.SELECT_PHOTO: if (resultCode == RESULT_OK) { //判断手机系统版本号 if (Build.VERSION.SDK_INT > 19) { //4.4及以上系统使用这个方法处理图片 cameraAlbumPopWindow.handleImgeOnKitKat(data); } else { cameraAlbumPopWindow.handleImageBeforeKitKat(data); } } break; default: break; } } } } app/src/main/java/com/hdl/photovoltaic/utils/LocalManageUtil.java
@@ -125,7 +125,7 @@ * @param context 上下文 */ private static void setCurrLanguageMode(Context context) { String language = SharedPreUtils.getSharedPreferencesKey("languege", context); String language = SharedPreUtils.getSharedPreferencesKey("languege"); Locale local = getLocale(language); Resources res = context.getResources(); DisplayMetrics dm = res.getDisplayMetrics(); app/src/main/java/com/hdl/photovoltaic/utils/PermissionUtils.java
@@ -1,24 +1,40 @@ package com.hdl.photovoltaic.utils; import android.Manifest; import android.app.Activity; import android.content.Context; import android.content.pm.PackageManager; import android.os.Build; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import androidx.fragment.app.Fragment; import com.hdl.photovoltaic.R; import com.hdl.photovoltaic.other.HdlThreadLogic; import com.hjq.permissions.OnPermissionCallback; import com.hjq.permissions.XXPermissions; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class PermissionUtils { /** * 获取权限成功 */ public static final int STATUS_SUCCESS = 1; public static final int STATUS_SUCCESS = 0; /** * 申请权限拒绝, 但是下次申请权限还会弹窗 */ public static final int STATUS_REFUSE = 1; /** * 申请权限拒绝,并且是永久,不会再弹窗 */ public static final int STATUS_REFUSE_PERMANENT = 2; /** * 默认未请求授权状态 */ public static final int STATUS_DEFAULT = 3; /** * 只有activity才可以申请 @@ -74,5 +90,73 @@ return new String[]{}; } /** * 获取权限状态 */ public static int getAuthorizeStaus(Activity activity, String authorize) { int flag = ActivityCompat.checkSelfPermission(activity, authorize); Boolean isShould = ActivityCompat.shouldShowRequestPermissionRationale(activity, authorize); if (isShould) { return STATUS_REFUSE; } if (flag == PackageManager.PERMISSION_GRANTED) { //获取到权限 return STATUS_SUCCESS; } if (!SharedPreUtils.contains(authorize)) { return STATUS_DEFAULT; } return STATUS_REFUSE_PERMANENT; } /** * 申请权限有回调 * * @param activity - * @param permission - * @param permissionStateCallback - */ public static void applyForRight(Activity activity, String permission, PermissionState permissionStateCallback) { // String permission = Manifest.permission.WRITE_EXTERNAL_STORAGE; int status = PermissionUtils.getAuthorizeStaus(activity, permission); switch (status) { case PermissionUtils.STATUS_SUCCESS: if (permissionStateCallback != null) { permissionStateCallback.Success(STATUS_SUCCESS); } break; case PermissionUtils.STATUS_REFUSE: case PermissionUtils.STATUS_DEFAULT: XXPermissions.with(activity) .permission(permission) .request(new OnPermissionCallback() { @Override public void onGranted(List<String> permissions, boolean all) { SharedPreUtils.putBoolean(permission, true); if (permissionStateCallback != null) { permissionStateCallback.Success(STATUS_REFUSE); } } @Override public void onDenied(List<String> permissions, boolean never) { SharedPreUtils.putBoolean(permission, true); } }); break; case PermissionUtils.STATUS_REFUSE_PERMANENT: if (permissionStateCallback != null) { permissionStateCallback.Success(STATUS_REFUSE_PERMANENT); } break; } } public interface PermissionState { void Success(int value); } } app/src/main/java/com/hdl/photovoltaic/utils/SharedPreUtils.java
@@ -3,21 +3,28 @@ import android.content.Context; import android.content.SharedPreferences; import com.hdl.photovoltaic.HDLApp; public class SharedPreUtils { private static final String FILE_NAME = "MyData"; private static SharedPreferences sp; public static void init(Context context) { sp = context.getApplicationContext().getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE); } /** * 用户数据的存储 * * @param key 键名 * @param value 键值 * @param context 上下文 * @return - */ public static boolean saveMyDataInfo(String key, String value, Context context) { public static boolean putString(String key, String value) { // 获取SharedPreferences对象,同时指定文件名称和访问权限 SharedPreferences sp = context.getSharedPreferences("MyData", Context.MODE_PRIVATE); // SharedPreferences sp = context.getSharedPreferences("MyData", Context.MODE_PRIVATE); // 获取获取SharedPreferences的编辑器对象 SharedPreferences.Editor edit = sp.edit(); // 通过编辑器进行数据的存储 @@ -30,12 +37,34 @@ * 读取用户数据 * * @param key 键名 * @param context 上下文 * @return -value */ public static String getSharedPreferencesKey(String key, Context context) { public static String getSharedPreferencesKey(String key) { // 获取SharedPreferences对象,同时指定文件名称和访问权限 SharedPreferences sp = context.getSharedPreferences("MyData", Context.MODE_PRIVATE); return sp.getString(key, ""); } /** * 添加boolean值 */ public static void putBoolean(String key, Boolean value) { sp.edit().putBoolean(key, value).apply(); } /** * 获取boolean值 */ public static Boolean getBoolean(String key) { // 获取SharedPreferences对象,同时指定文件名称和访问权限 return sp.getBoolean(key, false); } /** * 判断是否存在 */ public static Boolean contains(String key) { // 获取SharedPreferences对象,同时指定文件名称和访问权限 return sp.contains(key); } } app/src/main/java/com/hdl/photovoltaic/widget/ChangeAvatarDialog.java
New file @@ -0,0 +1,198 @@ package com.hdl.photovoltaic.widget; import android.app.Dialog; import android.content.Context; import android.os.Bundle; import android.text.TextUtils; import android.view.View; import androidx.annotation.NonNull; import com.hdl.photovoltaic.R; import com.hdl.photovoltaic.databinding.DialogChangeAvatarBinding; /** * 修改头像专用弹窗 */ public class ChangeAvatarDialog extends Dialog { private final Context mContext; private onCancelOnclickListener cancelOnclickListener;//取消按钮被点击了的监听器 private onLine1OnclickListener line1OnclickListener;// private onLine2OnclickListener line2OnclickListener;// private DialogChangeAvatarBinding viewBinding; private String line1Text, line2Text, cancelText; public ChangeAvatarDialog(@NonNull Context context) { super(context, R.style.Custom_Dialog); this.mContext = context; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); viewBinding = DialogChangeAvatarBinding.inflate(getLayoutInflater()); setContentView(viewBinding.getRoot()); //空白处不能取消动画 setCanceledOnTouchOutside(false); //初始化界面控件 initView(); //初始化界面数据 initData(); //初始化界面控件的事件 initEvent(); } private void initView() { } /** * 自定义"第一行"文本 * * @param content 内容 */ public void setLine1Text(String content) { if (TextUtils.isEmpty(content)) { return; } line1Text = content; if (viewBinding != null) { viewBinding.dialogChangePhotographTv.setText(content); } } /** * 自定义"第二行"文本 * * @param content 内容 */ public void setLine2Text(String content) { if (TextUtils.isEmpty(content)) { return; } line2Text = content; if (viewBinding != null) { viewBinding.dialogChangeAvatarSelectAlbumTv.setText(content); } } /** * 自定义"取消"文本 * * @param cancel 内容 */ public void setCancel(String cancel) { if (TextUtils.isEmpty(cancel)) { return; } cancelText = cancel; if (viewBinding != null) { viewBinding.dialogChangeAvatarCancelTv.setText(cancel); } } private void initEvent() { viewBinding.dialogChangePhotograph.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (line1OnclickListener != null) { line1OnclickListener.Line1(); } } }); viewBinding.dialogChangeAvatarSelectAlbumLl.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (line2OnclickListener != null) { line2OnclickListener.Line2(); } } }); viewBinding.dialogChangeAvatarCancelLl.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (cancelOnclickListener != null) { cancelOnclickListener.Cancel(); } } }); } private void initData() { //如果设置按钮文字 if (!TextUtils.isEmpty(line1Text)) { viewBinding.dialogChangePhotographTv.setText(line1Text); } if (!TextUtils.isEmpty(line2Text)) { viewBinding.dialogChangeAvatarSelectAlbumTv.setText(line2Text); } if (!TextUtils.isEmpty(cancelText)) { viewBinding.dialogChangeAvatarCancelTv.setText(cancelText); } } /** * 设置取消按钮监听 * * @param onCancelOnclickListener - */ public void setCancelOnclickListener(onCancelOnclickListener onCancelOnclickListener) { if (onCancelOnclickListener != null) { this.cancelOnclickListener = onCancelOnclickListener; } } /** * 设置按钮1监听 * * @param onLine1OnclickListener - */ public void setLine1OnclickListener(onLine1OnclickListener onLine1OnclickListener) { if (onLine1OnclickListener != null) { this.line1OnclickListener = onLine1OnclickListener; } } /** * 设置按钮2监听 * * @param onLine2OnclickListener - */ public void setLine2OnclickListener(onLine2OnclickListener onLine2OnclickListener) { if (onLine2OnclickListener != null) { this.line2OnclickListener = onLine2OnclickListener; } } public interface onCancelOnclickListener { void Cancel(); } public interface onLine1OnclickListener { void Line1(); } public interface onLine2OnclickListener { void Line2(); } } app/src/main/java/com/hdl/photovoltaic/widget/popupview/BasePopView.java
New file @@ -0,0 +1,68 @@ package com.hdl.photovoltaic.widget.popupview; import android.content.Context; import android.graphics.drawable.ColorDrawable; import android.view.LayoutInflater; import android.view.View; import android.view.WindowManager; import android.widget.PopupWindow; /** * Author: Zoro * Date: 2018/11/23 * Description: This is BasePopView */ public abstract class BasePopView extends PopupWindow { public View mView; public Context mContext; public BasePopView(Context context, int layout) { super(context); this.mContext = context; initPopView(layout); } public BasePopView(Context context, int layout, int w, int h) { super(context); this.mContext = context; initPopView(layout, w, h); } public void initPopView(int layout, int w, int h) { mView = LayoutInflater.from(mContext).inflate(layout, null, false); setContentView(mView); setWidth(w); setHeight(h); this.setFocusable(true); this.setTouchable(true); this.setOutsideTouchable(true); this.setBackgroundDrawable(new ColorDrawable(0)); initContentView(mView); } public void initPopView(int layout) { initPopView(layout, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT); } // public void showPopView(View view) { // showAsDropDown(view, 0, 0); // } // // public void showPopView(View view, int x, int y) { // showPopView(view, x, y, Gravity.BOTTOM); // } // // public void showPopView(View view, int x, int y, int gravity) { // if (this.isShowing()) { // this.dismiss(); // } else { // this.showPopView(view, x, y, gravity); // } // } protected abstract void initContentView(View parent); } app/src/main/java/com/hdl/photovoltaic/widget/popupview/CameraAlbumPopWindow.java
New file @@ -0,0 +1,532 @@ package com.hdl.photovoltaic.widget.popupview; import android.Manifest; import android.annotation.TargetApi; import android.app.Activity; import android.content.ContentUris; import android.content.ContentValues; import android.content.Intent; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Matrix; import android.graphics.drawable.ColorDrawable; import android.media.ExifInterface; import android.net.Uri; import android.os.Build; import android.os.Environment; import android.provider.DocumentsContract; import android.provider.MediaStore; import android.text.TextUtils; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.WindowManager; import android.widget.PopupWindow; import android.widget.RelativeLayout; import android.widget.TextView; import com.hdl.photovoltaic.R; import com.hdl.photovoltaic.other.HdlThreadLogic; import com.hdl.photovoltaic.utils.PermissionUtils; import com.hdl.photovoltaic.utils.SharedPreUtils; import com.hjq.permissions.OnPermissionCallback; import com.hjq.permissions.XXPermissions; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; import java.util.Locale; /** * @Author : Zoro. * @Date : 2018/11/22. * @Describe :这个View中处理了很多异常捕获,直接结束就可以了,UI上面都已经处理好了 */ public class CameraAlbumPopWindow extends PopupWindow { public static final int TAKE_PHOTO = 100;//启动相机标识 public static final int SELECT_PHOTO = 200;//启动相册标识 private View mView; private Activity mContext; private TextView tv_mCamera; private TextView tv_Album; private TextView tv_mCancel; //默认图片最大为200k private int photo_Size = 200; private File hdl_Dir; private File outputImagepath;//存储拍完照后的图片 private Bitmap orc_bitmap;//拍照和相册获取图片的Bitmap private int MAX_WIDTH = 800, MAX_HEIGHT = 800; // private CameraAlbumListener cameraListener; public CameraAlbumPopWindow(Activity context, CameraAlbumListener cameraListener) { super(context); this.cameraListener = cameraListener; initView(context); } public CameraAlbumPopWindow(Activity context, int width, int height, CameraAlbumListener cameraListener) { super(context); this.cameraListener = cameraListener; this.MAX_HEIGHT = height; this.MAX_WIDTH = width; initView(context); } public CameraAlbumPopWindow(Activity context, int photo_Size, CameraAlbumListener cameraListener) { super(context); this.photo_Size = photo_Size; this.cameraListener = cameraListener; initView(context); } /** * @param context 上下文 * @param tag 0:拍照 1:相册 */ private void checkPermission_After(final Activity context, final int tag) { String permission = Manifest.permission.CAMERA; int status = PermissionUtils.getAuthorizeStaus(context, permission); switch (status) { case PermissionUtils.STATUS_SUCCESS: dismiss(); if (0 == tag) { take_photo(); } else { select_photo(); } break; case PermissionUtils.STATUS_REFUSE: case PermissionUtils.STATUS_DEFAULT: XXPermissions.with(context) .permission(permission) .request(new OnPermissionCallback() { @Override public void onGranted(List<String> permissions, boolean all) { dismiss(); SharedPreUtils.putBoolean(permission, true); if (0 == tag) { take_photo(); } else { select_photo(); } } @Override public void onDenied(List<String> permissions, boolean never) { dismiss(); SharedPreUtils.putBoolean(permission, true); } }); break; case PermissionUtils.STATUS_REFUSE_PERMANENT: HdlThreadLogic.toast(mContext, R.string.permission_open); break; } } private void initView(Activity context) { hdl_Dir = context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS); System.out.println("===========" + hdl_Dir.getAbsolutePath()); if (!hdl_Dir.exists()) { boolean mkdirs = hdl_Dir.mkdirs(); if (!mkdirs) { HdlThreadLogic.toast(mContext, R.string.camera_album_file_create_fial); } } mContext = context; mView = LayoutInflater.from(mContext).inflate(R.layout.view_camera_album, null); setContentView(mView); tv_mCamera = mView.findViewById(R.id.tv_Camera); tv_Album = mView.findViewById(R.id.tv_Album); tv_mCancel = mView.findViewById(R.id.tv_Cancel); this.setWidth(RelativeLayout.LayoutParams.MATCH_PARENT); this.setHeight(RelativeLayout.LayoutParams.WRAP_CONTENT); //点击空白地方关闭弹窗(3个要一起隐藏) this.setFocusable(true); this.setTouchable(true); this.setOutsideTouchable(true); this.setBackgroundDrawable(new ColorDrawable(0)); mView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { int height = mView.findViewById(R.id.ll_Pop).getTop(); int y = (int) event.getY(); if (event.getAction() == MotionEvent.ACTION_UP) { if (y < height) { dismiss(); } } return true; } }); tv_mCancel.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { dismiss(); } }); tv_mCamera.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { checkPermission_After(mContext, 0); } }); tv_Album.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { checkPermission_After(mContext, 1); } }); } /** * 拍照获取图片 **/ private void take_photo() { //获取系統版本 int currentapiVersion = Build.VERSION.SDK_INT; // 激活相机 Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); // 判断存储卡是否可以用,可用进行存储 SimpleDateFormat timeStampFormat = new SimpleDateFormat( "yyyy_MM_dd_HH_mm_ss", Locale.ENGLISH); String filename = timeStampFormat.format(new Date()); outputImagepath = new File(hdl_Dir, filename + ".jpg"); if (currentapiVersion < 24) { // 从文件中创建uri Uri uri = Uri.fromFile(outputImagepath); intent.putExtra(MediaStore.EXTRA_OUTPUT, uri); } else { //兼容android7.0 使用共享文件的形式 ContentValues contentValues = new ContentValues(1); contentValues.put(MediaStore.Images.Media.DATA, outputImagepath.getAbsolutePath()); Uri uri = mContext.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues); intent.putExtra(MediaStore.EXTRA_OUTPUT, uri); // Uri photoURI= FileProvider.getUriForFile(mContext,"com.hdl.debugtreasure.dc.fileprovider",outputImagepath); // intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); // intent.putExtra(MediaStore.EXTRA_OUTPUT,photoURI); } // 开启一个带有返回值的Activity,请求码为PHOTO_REQUEST_CAREMA ((Activity) mContext).startActivityForResult(intent, TAKE_PHOTO); } /** * 拍照获取完图片要执行的方法(根据图片路径显示图片) */ public void displayImage() { if (null == outputImagepath) { HdlThreadLogic.toast(mContext, R.string.camera_album_file_save_fial); } else { if (!TextUtils.isEmpty(outputImagepath.getAbsolutePath())) { orc_bitmap = BitmapFactory.decodeFile(outputImagepath.getAbsolutePath());//获取图片 saveBitmap(comp(ImgUpdateDirection(outputImagepath.getAbsolutePath()))); //压缩图片 } else { HdlThreadLogic.toast(mContext, R.string.camera_album_file_get_fial); } } } /** * 相册获取完图片要执行的方法(根据图片路径显示图片) */ private void displayImage(String imagePath) { if (!TextUtils.isEmpty(imagePath)) { orc_bitmap = BitmapFactory.decodeFile(imagePath);//获取图片 saveBitmap(comp(ImgUpdateDirection(imagePath))); //压缩图片 } else { HdlThreadLogic.toast(mContext, R.string.camera_album_file_get_fial); } } //比例压缩 private Bitmap comp(Bitmap image) { if (null == image) { HdlThreadLogic.toast(mContext, R.string.camera_album_system_fial); return null; } else { ByteArrayOutputStream baos = new ByteArrayOutputStream(); image.compress(Bitmap.CompressFormat.JPEG, 100, baos); // if (baos.toByteArray().length / 1024 > 1024) {//判断如果图片大于1M,进行压缩避免在生成图片(BitmapFactory.decodeStream)时溢出 // baos.reset();//重置baos即清空baos // image.compress(Bitmap.CompressFormat.JPEG, 50, baos);//这里压缩50%,把压缩后的数据存放到baos中 // } ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray()); BitmapFactory.Options newOpts = new BitmapFactory.Options(); //开始读入图片,此时把options.inJustDecodeBounds 设回true了 newOpts.inJustDecodeBounds = true; Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, newOpts); newOpts.inJustDecodeBounds = false; int w = newOpts.outWidth; int h = newOpts.outHeight; //现在主流手机比较多是800*480分辨率,所以高和宽我们设置为 //缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可 int be = 1;//be=1表示不缩放 while (((int) w / be) > MAX_WIDTH || ((int) h / be) > MAX_HEIGHT) { be++; } if (be <= 0) be = 1; newOpts.inSampleSize = be;//设置缩放比例 System.out.println("--------newOpts.inSampleSize==" + newOpts.inSampleSize); newOpts.inPreferredConfig = Bitmap.Config.RGB_565;//降低图片从ARGB888到RGB565 //重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了 isBm = new ByteArrayInputStream(baos.toByteArray()); bitmap = BitmapFactory.decodeStream(isBm, null, newOpts); return bitmap;//压缩好比例大小后再进行质量压缩 } } /** * 质量压缩方法 * * @param image * @return */ private Bitmap compressImage(Bitmap image) { if (image != null) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); image.compress(Bitmap.CompressFormat.JPEG, 100, baos);//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中 int options = 100; while (baos.toByteArray().length / 1024 > 100) { //循环判断如果压缩后图片是否大于100kb,大于继续压缩 baos.reset();//重置baos即清空baos options -= 10;//每次都减少10 image.compress(Bitmap.CompressFormat.JPEG, options, baos);//这里压缩options%,把压缩后的数据存放到baos中 } ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());//把压缩后的数据baos存放到ByteArrayInputStream中 Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);//把ByteArrayInputStream数据生成图片 return bitmap; } else { return null; } } /** * 保存方法 */ private void saveBitmap(Bitmap bitmap) { if (null == bitmap) { HdlThreadLogic.toast(mContext, mContext.getResources().getString(R.string.camera_album_system_fial)); } else { SimpleDateFormat timeStampFormat = new SimpleDateFormat( "yyyy_MM_dd_HH_mm_ss", Locale.CHINESE); String filename = timeStampFormat.format(new Date()); File f = new File(hdl_Dir, filename + ".jpg"); if (f.exists()) { f.delete(); } try { FileOutputStream out = new FileOutputStream(f); bitmap.compress(Bitmap.CompressFormat.JPEG, 60, out); //进行数据的处理 out.flush(); out.close(); //保存好小图以后删除大图(拍照需要) deleteBigPhoto(); cameraListener.successCallBack(f); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } /** * 压缩图片保存之后需要删除原图 */ private void deleteBigPhoto() { if (null != outputImagepath) { outputImagepath.delete(); } } //改变拍完照后图片方向不正的问题 private Bitmap ImgUpdateDirection(String filepath) { int digree = 0;//图片旋转的角度 //根据图片的URI获取图片的绝对路径 //String filepath = ImgUriDoString.getRealFilePath(getApplicationContext(), uri); //根据图片的filepath获取到一个ExifInterface的对象 ExifInterface exif = null; try { exif = new ExifInterface(filepath); if (exif != null) { // 读取图片中相机方向信息 int ori = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED); // 计算旋转角度 switch (ori) { case ExifInterface.ORIENTATION_ROTATE_90: digree = 90; break; case ExifInterface.ORIENTATION_ROTATE_180: digree = 180; break; case ExifInterface.ORIENTATION_ROTATE_270: digree = 270; break; default: digree = 0; break; } } //如果图片不为0 if (digree != 0) { // 旋转图片 Matrix m = new Matrix(); m.postRotate(digree); orc_bitmap = Bitmap.createBitmap(orc_bitmap, 0, 0, orc_bitmap.getWidth(), orc_bitmap.getHeight(), m, true); } } catch (IOException e) { e.printStackTrace(); exif = null; } return orc_bitmap; } /** * 从相册中获取图片 */ private void select_photo() { String permission = Manifest.permission.WRITE_EXTERNAL_STORAGE; int status = PermissionUtils.getAuthorizeStaus(mContext, permission); switch (status) { case PermissionUtils.STATUS_SUCCESS: openAlbum(); break; case PermissionUtils.STATUS_REFUSE: case PermissionUtils.STATUS_DEFAULT: XXPermissions.with(mContext) .permission(permission) .request(new OnPermissionCallback() { @Override public void onGranted(List<String> permissions, boolean all) { SharedPreUtils.putBoolean(permission, true); openAlbum(); } @Override public void onDenied(List<String> permissions, boolean never) { SharedPreUtils.putBoolean(permission, true); } }); break; case PermissionUtils.STATUS_REFUSE_PERMANENT: HdlThreadLogic.toast(mContext, R.string.permission_open); break; } } /** * 打开相册的方法 */ private void openAlbum() { Intent intent = new Intent(Intent.ACTION_GET_CONTENT); intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*"); ((Activity) mContext).startActivityForResult(intent, SELECT_PHOTO); } /** * 4.4以下系统处理图片的方法 */ public void handleImageBeforeKitKat(Intent data) { Uri uri = data.getData(); String imagePath = getImagePath(uri, null); displayImage(imagePath); } /** * 4.4及以上系统处理图片的方法 */ @TargetApi(Build.VERSION_CODES.KITKAT) public void handleImgeOnKitKat(Intent data) { String imagePath = null; Uri uri = data.getData(); if (DocumentsContract.isDocumentUri(mContext, uri)) { String docId = DocumentsContract.getDocumentId(uri); //数据表里指定的行 if ("com.android.providers.media.documents".equals(uri.getAuthority())) { String id = docId.split(":")[1]; String selection = MediaStore.Images.Media._ID + "=" + id; imagePath = getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection); } else if ("com.android.providers.downloads.documents".equals(uri.getAuthority())) { Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(docId)); imagePath = getImagePath(contentUri, null); } } else if ("content".equalsIgnoreCase(uri.getScheme())) { imagePath = getImagePath(uri, null); } else if ("file".equalsIgnoreCase(uri.getScheme())) { imagePath = uri.getPath(); } displayImage(imagePath); } /** * 通过uri和selection来获取真实的图片路径,从相册获取图片时要用 */ private String getImagePath(Uri uri, String selection) { String path = null; Cursor cursor = mContext.getContentResolver().query(uri, null, selection, null, null); if (cursor != null) { if (cursor.moveToFirst()) { int columnIndex = cursor.getColumnIndex(MediaStore.Images.Media.DATA); path = cursor.getString(columnIndex); } cursor.close(); } return path; } @Override public void dismiss() { super.dismiss(); backgroundAlpha(1f); } //用于popwindow显示隐藏时候背景的颜色更换 public void backgroundAlpha(float bgAlpha) { WindowManager.LayoutParams lp = ((Activity) mContext).getWindow().getAttributes(); ((Activity) mContext).getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND); lp.alpha = bgAlpha; //0.0-1.0 ((Activity) mContext).getWindow().setAttributes(lp); } public void show(View view, int mode, int x, int y) { showAtLocation(view, mode, x, y); backgroundAlpha(0.5f); } public interface CameraAlbumListener { void successCallBack(File a); } } app/src/main/res/layout/dialog_change_avatar.xml
New file @@ -0,0 +1,88 @@ <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:id="@+id/dialog_change_photograph" android:layout_width="match_parent" android:layout_height="@dimen/dp_54" android:background="@color/text_FFFFFFFF" android:gravity="center" android:orientation="horizontal" app:layout_constraintBottom_toTopOf="@+id/line" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent"> <TextView android:id="@+id/dialog_change_photograph_tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/me_personal_data_photograph" android:textColor="@color/text_222222" android:textSize="16sp" /> </LinearLayout> <View android:id="@+id/line" android:layout_width="match_parent" android:layout_height="0.5dp" android:background="@color/text_E1E1E1" app:layout_constraintBottom_toTopOf="@+id/dialog_change_avatar_select_album_ll" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" /> <LinearLayout android:id="@+id/dialog_change_avatar_select_album_ll" android:layout_width="match_parent" android:layout_height="@dimen/dp_54" android:layout_marginBottom="8dp" android:background="@color/text_FFFFFFFF" android:gravity="center" android:orientation="horizontal" app:layout_constraintBottom_toTopOf="@+id/dialog_change_avatar_cancel_ll" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" > <TextView android:id="@+id/dialog_change_avatar_select_album_tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/me_personal_data_select_album" android:textColor="@color/text_222222" android:textSize="16sp" /> </LinearLayout> <LinearLayout android:id="@+id/dialog_change_avatar_cancel_ll" android:layout_width="match_parent" android:layout_height="@dimen/dp_54" android:background="@color/text_FFFFFFFF" android:gravity="center" android:orientation="horizontal" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent"> <TextView android:id="@+id/dialog_change_avatar_cancel_tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/loading_cancel" android:textColor="@color/text_FF5757" android:textSize="16sp" /> </LinearLayout> </androidx.constraintlayout.widget.ConstraintLayout> app/src/main/res/layout/view_camera_album.xml
New file @@ -0,0 +1,53 @@ <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <LinearLayout android:id="@+id/ll_Pop" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:id="@+id/tv_Camera" android:layout_width="match_parent" android:layout_height="@dimen/dp_54" android:background="@color/white" android:gravity="center" android:text="@string/me_personal_data_photograph" android:textColor="@color/text_222222" android:textSize="16sp" /> <View android:layout_width="match_parent" android:layout_height="@dimen/dp_0_5" android:background="@color/text_E1E1E1" /> <TextView android:id="@+id/tv_Album" android:layout_width="match_parent" android:layout_height="@dimen/dp_54" android:background="@color/white" android:gravity="center" android:text="@string/me_personal_data_select_album" android:textColor="@color/text_222222" android:textSize="16sp" /> <View android:layout_width="match_parent" android:layout_height="@dimen/dp_8" /> <TextView android:id="@+id/tv_Cancel" android:layout_width="match_parent" android:layout_height="@dimen/dp_54" android:background="@color/white" android:gravity="center" android:text="@string/loading_cancel" android:textColor="@color/text_FF5757" android:textSize="16sp" /> </LinearLayout> </LinearLayout> app/src/main/res/values/colors.xml
@@ -39,6 +39,7 @@ <color name="text_F5F7FA">#F5F7FA</color> <color name="text_FF5757">#FF5757</color> <color name="text_565758">#565758</color> <color name="text_222222">#222222</color> </resources> app/src/main/res/values/strings.xml
@@ -112,6 +112,8 @@ <string name="me_personal_data_user_name">用户名</string> <string name="me_personal_data_role">角色</string> <string name="me_personal_data_super_admin">超级管理员</string> <string name="me_personal_data_photograph">拍照</string> <string name="me_personal_data_select_album">从相册中选择</string> <!--app更新--> <string name="app_version_number">版本号</string> @@ -146,6 +148,20 @@ <string name="loading_privacy">隐私权政策及服务条款</string> <string name="loading_privacy_server">为了更好的保障您的合法权益,请您阅读并同意以下协议《隐私权政策》和《服务条款》</string> <string name="kill_app">再按一次退出应用</string> <string name="loading_not_supported">抱歉,暂不支持.</string> <!-- 权限 --> <string name="camera_album_file_create_fial">文件创建失败</string> <string name="camera_album_file_save_fial">保存路径异常,请重试</string> <!-- 权限 --> <!-- 图片上传 --> <string name="camera_album_file_get_fial">图片获取失败</string> <string name="camera_album_system_fial">系统处理图片失败,请重试</string> <string name="apk_update_content">为了正常升级河东APP,请点击设置按钮,允许安装未知来源应用,本功能只限用于河东APP版本升级,Android 11版本及以上需要在授权之后重新下载安装。</string> <string name="apk_update_sure">设置</string> <string name="permission_open">请到设置中打开权限</string> </resources>