Android 电子词典个人信息设置功能详细设计 - 基于代码示例

本文将以一个基于 Android 系统的电子词典为基础,根据以下代码示例,详细介绍个人信息设置功能的设计思路。代码示例中使用了 LitePalMatisseLubanGlide 等库,并涉及动态权限申请等内容。

代码示例

public class UpdateInfoActivity extends BaseActivity {
    public static final String SD_APP_DIR_NAME = "GYDir"; //存储程序在外部SD卡上的根目录的名字
    public static final String PHOTO_DIR_NAME = "photo";    //存储照片在根目录下的文件夹名字
    private static final int REQUEST_PERMISSIONS = 1001;
    private final int REQUEST_CODE_CHOOSE_PHOTO_ALBUM = 1;
    private String headerUrl;
    private CircleImageView iv_header;
    private EditText etusername; // 用户名输入框
    private EditText etpassword; // 密码输入框
    private RelativeLayout btn_save; // 注册按钮

    final String items[] = {"拍照", "从手机相册选择"};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_update_info);

        init();

        btn_save.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(TextUtils.isEmpty(headerUrl)){
                    Toast.makeText(UpdateInfoActivity.this, "请设置头像", Toast.LENGTH_SHORT).show();
                    return;
                }
                String user_name = etusername.getText().toString();
                String password = etpassword.getText().toString();
                // 校验用户名和密码是否为空
                if (TextUtils.isEmpty(user_name) || TextUtils.isEmpty(password)) {
                    Toast.makeText(UpdateInfoActivity.this, "用户名或密码不能为空", Toast.LENGTH_SHORT).show();
                } else {
                    User user = LitePal.where("userId = ?", ConfigData.getSinaNumLogged()).findFirst(User.class);
                    user.setUserName(user_name);
                    user.setPassword(password);
                    user.setUserProfile(headerUrl);
                    boolean result = user.save();
                    if (result) {
                        Toast.makeText(UpdateInfoActivity.this, "保存成功", Toast.LENGTH_SHORT).show();
                        finish();
                    } else {
                        Toast.makeText(UpdateInfoActivity.this, "保存失败", Toast.LENGTH_SHORT).show();
                    }
                }
            }
        });

        iv_header.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // 通过builder 构建器来构造
                takePicture();
            }
        });
    }

    private void init() {
        iv_header = findViewById(R.id.iv_header);
        etusername = findViewById(R.id.et_username);
        etpassword = findViewById(R.id.et_password);
        btn_save = findViewById(R.id.btn_save);
        List<User> userList = LitePal.where("userId = ?", ConfigData.getSinaNumLogged() + "").find(User.class);
        etusername.setText(userList.get(0).getUserName());
        etpassword.setText(userList.get(0).getPassword());
        if(!TextUtils.isEmpty(userList.get(0).getUserProfile())){
            headerUrl = userList.get(0).getUserProfile();
            Glide.with(UpdateInfoActivity.this).load(headerUrl).into(iv_header);
        }
    }

    /**
     * 检查用户名是否重复
     *
     * @param phone 手机号
     * @return 是否重复
     */
    private boolean checkUsername(String phone) {
        // 查询在用户表中,是否存在该用户
        User user = LitePal.where("userId = ?", phone).findFirst(User.class);
        if (user != null) {
            return false;
        } else {
            return true;
        }
    }

    /**
     * 获取照片
     */
    private void takePicture() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {//6.0才用动态权限
            getPermissions();
        } else {
            //在这里跳转到手机系统相册里面
            takePicFromSystem();
        }
    }

    /**
     * cong 相册多选
     */
    private void takePicFromSystem() {
        Matisse.from(this)
                .choose(MimeType.ofImage(), false)
                .capture(true)  // 使用相机,和 captureStrategy 一起使用
                .captureStrategy(new CaptureStrategy(true, getPackageName() + ".FileProvider"))
                .theme(R.style.Matisse_Dracula)
                .countable(true)
                .maxSelectable(1)
                .addFilter(new Filter() {
                    @Override
                    protected Set<MimeType> constraintTypes() {
                        return new HashSet<MimeType>() {{ add(MimeType.PNG); }};
                    }

                    @Override
                    public IncapableCause filter(Context context, Item item) {
                        try {
                            InputStream inputStream = getContentResolver().openInputStream(item.getContentUri());
                            BitmapFactory.Options options = new BitmapFactory.Options();
                            options.inJustDecodeBounds = true;
                            BitmapFactory.decodeStream(inputStream, null, options);
                            int width = options.outWidth;
                            int height = options.outHeight;

//                            if (width >= 500)
//                                return new IncapableCause("宽度超过500px");

                        } catch (FileNotFoundException e) {
                            e.printStackTrace();
                        }


                        return null;
                    }
                })
//                .gridExpectedSize((int) getResources().getDimension(R.dimen.imageSelectDimen))
                .restrictOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
                .thumbnailScale(0.87f)
                .imageEngine(new GlideLoadEngine())
                .forResult(REQUEST_CODE_CHOOSE_PHOTO_ALBUM);
    }

    List<String> mPermissionList = new ArrayList<>();

    /**
     * 获取动态权限(only  拍照需要的)
     */
    private void getPermissions() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {//6.0才用动态权限
            String[] permissions = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA,};
            mPermissionList.clear();//清空没有通过的权限
            //逐个判断你要的权限是否已经通过
            for (int i = 0; i < permissions.length; i++) {
                if (ContextCompat.checkSelfPermission(this, permissions[i]) != PackageManager.PERMISSION_GRANTED) {
                    mPermissionList.add(permissions[i]);//添加还未授予的权限
                }
            }
            //申请权限
            if (mPermissionList.size() > 0) {//有权限没有通过,需要申请
                ActivityCompat.requestPermissions(this, permissions, REQUEST_PERMISSIONS);
            } else {
                takePicFromSystem();
            }
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode) {
            case REQUEST_PERMISSIONS:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    //成功
                    //Toast.makeText(this, "用户授权相机权限", Toast.LENGTH_SHORT).show();
                    takePicFromSystem();
                } else {
                    // 勾选了不再询问
                    Toast.makeText(UpdateInfoActivity.this, "您已拒绝相机权限,无法上传头像,请手动在设置中打开", Toast.LENGTH_SHORT).show();
                    /**
                     * 跳转到 APP 详情的权限设置页
                     *
                     * 可根据自己的需求定制对话框,点击某个按钮在执行下面的代码
                     */
                    Intent intent = getAppDetailSettingIntent(this);
                    startActivity(intent);
                }
                break;
        }
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK) {
            Uri result = null;
            if (requestCode == REQUEST_CODE_CHOOSE_PHOTO_ALBUM && resultCode == RESULT_OK) {
                //图片路径 同样视频地址也是这个 根据requestCode
                List<Uri> pathList = Matisse.obtainResult(data);
                List<String> _List = new ArrayList<>();
                for (Uri _Uri : pathList) {
                    String _Path = getRealFilePath(this, _Uri);
                    File _File = new File(_Path);
                    System.out.println("lsh_lsh压缩前图片大小->" + _File.length() / 1024 + "k");
                    _List.add(_Path);
                }
                compress(_List);
                //Toast.makeText(ComplainActivity.this, "" + pathList.size(), Toast.LENGTH_SHORT).show();
            }
        }
    }
}

功能设计思路

  1. 界面设计

    • 在界面上设计头像、用户名、密码和保存按钮等控件。
    • 使用 CircleImageView 实现头像的圆形显示。
  2. 初始化

    • 通过 findViewById() 方法获取界面控件。
    • 从数据库中读取当前用户信息,并显示在对应的控件中。
    • 读取用户头像并使用 Glide 加载到 CircleImageView 中。
  3. 保存用户信息

    • 获取用户输入的用户名和密码。
    • 校验用户名和密码是否为空。
    • 将用户信息保存到数据库中。
    • 使用 Toast 提示用户保存结果。
  4. 设置头像

    • 点击头像控件时,调用 takePicture() 方法。
    • 判断系统版本,选择合适的图片获取方式:
      • 版本 >= 6.0:调用 getPermissions() 获取权限。
      • 版本 < 6.0:直接调用 takePicFromSystem() 打开相册。
  5. 获取照片

    • 使用 Matisse 库打开相册,设置相关参数,例如只能选择图片、最多选择一张、可以拍照、图片大小限制、压缩比例等。
    • 获取选择的图片路径并保存到列表中。
    • 调用 compress() 方法压缩图片。
  6. 压缩图片

    • 使用 Luban 库压缩选择的图片。
    • 获取压缩后的图片路径并保存到 headerUrl 变量中。
    • 使用 Glide 将压缩后的图片显示到 CircleImageView 中。
  7. 权限申请

    • getPermissions() 方法中遍历需要申请的权限。
    • 若有未授权的权限,则调用 ActivityCompat.requestPermissions() 申请权限。
    • onRequestPermissionsResult() 方法中处理权限申请结果,并提示用户手动打开权限。

功能设计流程图

  1. 开始
  2. 初始化: 获取界面控件,并显示当前用户信息。
  3. 保存用户信息: 判断头像是否已设置,获取用户名和密码,校验是否为空,保存到数据库。
  4. 设置头像: 调用 takePicture() 方法打开相册或相机。
  5. 获取照片: 使用 Matisse 获取图片路径,并调用 compress() 方法压缩。
  6. 压缩图片: 使用 Luban 压缩图片,获取压缩后的路径,保存到 headerUrl
  7. 权限申请: 判断系统版本,获取相机和存储权限。
  8. 结束

文字内容

  1. 开始
  2. 初始化: 获取界面控件并显示当前用户信息。
  3. 保存用户信息: 判断头像是否已设置,获取用户名和密码的输入内容,校验是否为空,若不为空则将用户信息保存到数据库中。
  4. 设置头像: 调用 takePicture() 方法打开相册或相机。
  5. 获取照片: 使用 Matisse 库获取选择的图片路径,并调用 compress() 方法进行压缩。
  6. 压缩图片: 使用 Luban 库对选择的图片进行压缩,获取压缩后的图片路径,并将路径保存到 headerUrl 变量中。
  7. 权限申请: 判断当前系统版本是否大于等于 6.0,若是则调用 getPermissions() 方法获取相机和存储权限,否则直接调用 takePicFromSystem() 方法打开相册。
  8. 结束

总结

该代码示例展示了 Android 电子词典个人信息设置功能的设计思路,从界面设计、初始化、保存用户信息、设置头像、获取照片、图片压缩、权限申请等多个方面进行了详细的阐述。希望这篇文章能帮助开发者理解和实现类似的功能。

注意:

  • 代码示例中使用了多个库,需要在项目的 build.gradle 文件中添加依赖。
  • 代码示例仅供参考,开发者可以根据实际需求进行修改和扩展。
  • 请注意代码中的注释,以便更好地理解代码的功能。
Android 电子词典个人信息设置功能详细设计 - 基于代码示例

原文地址: https://www.cveoy.top/t/topic/jTXw 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录