기존에 작성한 퍼미션 체크 커스텀 리스트 뷰(링크)가 자잘한 오류가 발생했고 또한 상세한 설명이 붙여지지 않았다.
아래에 새로 리팩토링한 코드로 다시 쓴다.(기존 XML은 동일함)
* RecyclerView로 적용하고자 하는 사람을 위해 기존 소스에 ViewHolder 패턴을 추가하였다.
1. Adapter
public class PermissionAdapter extends BaseAdapter { private ArrayList<Permission> permissionItems = new ArrayList<>(); public PermissionAdapter(Context context) { for (PermissionType permissionType : PermissionType.values()) { Permission permission = new Permission(); switch (permissionType.getPermissionValue()) { case Manifest.permission.READ_PHONE_STATE: permission.setIcon(context.getResources().getDrawable(R.drawable.baseline_call_white_18)); permission.setName("전화"); permission.setContent("출, 퇴근 기록 시 전화번호를 저장하기 위해 해당 권한이 필요합니다."); break; case Manifest.permission.WRITE_EXTERNAL_STORAGE: permission.setIcon(context.getResources().getDrawable(R.drawable.baseline_storage_white_18)); permission.setName("저장소"); permission.setContent("프로필 사진을 등록하기 위해 해당 권한이 필요합니다."); break; case Manifest.permission.RECORD_AUDIO: permission.setIcon(context.getResources().getDrawable(R.drawable.baseline_record_voice_over_white_18)); permission.setName("녹음"); permission.setContent("인증 등록 데이터 송신을 위해 해당 권한이 필요합니다."); break; } permissionItems.add(permission); } } @Override public int getCount() { return permissionItems.size(); } @Override public Permission getItem(int position) { return permissionItems.get(position); } @Override public long getItemId(int position) { return 0; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; Context context = parent.getContext(); if (convertView != null) { holder = (ViewHolder) convertView.getTag(); } else { LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = inflater.inflate(R.layout.list_view_permission, parent, false); holder = new ViewHolder(convertView); convertView.setTag(holder); } String permissionValue = PermissionType.values()[position].getPermissionValue(); // 퍼미션 체크에 따른 이벤트 리스너 PermissionListener permissionListener = new PermissionListener() { @Override public void onPermissionGranted() { // 해당 퍼미션 권한이 허용된 경우 // 허용된 경우 체크박스 체크 및 클릭 잠금 holder.mCbPermissionCheck.setChecked(true); holder.mCbPermissionCheck.setClickable(false); //허용된 경우 퍼미션 영역 클릭 잠금 holder.mClWrap.setClickable(false); // 퍼미션이 전부 허용된 경우 if (permissionCheck(context)) { // 화면 전환 Intent intent = new Intent(context, MainActivity.class); context.startActivity(intent); ((Activity) context).finish(); } } @Override public void onPermissionDenied(List<String> deniedPermissions) { // 퍼미션 권한이 허용되지 않은 경우 // 체크 해제 holder.mCbPermissionCheck.setChecked(false); } }; // 퍼미션 권한이 허용되지 않은 경우 if (!PermissionType.values()[position].permissionCheck(context)) { // 체크박스 체크 해제 holder.mCbPermissionCheck.setChecked(false); // 해당 체크박스를 클릭한 경우 퍼미션 다이얼로그 호출 holder.mCbPermissionCheck.setOnClickListener(v -> showPermission(context, permissionListener, permissionValue)); // 해당 퍼미션 영역을 클릭한 경우 퍼미션 다이얼로그 호출 holder.mClWrap.setOnClickListener(v -> showPermission(context, permissionListener, permissionValue)); } else { // 허용된 경우 체크박스 체크 및 클릭 잠금 holder.mCbPermissionCheck.setChecked(true); holder.mCbPermissionCheck.setClickable(false); //허용된 경우 퍼미션 영역 클릭 잠금 holder.mClWrap.setClickable(false); } Permission permission = permissionItems.get(position); Glide.with(context) .load(permission.getIcon()) .into(holder.mIvPermission); holder.mTvPermissionName.setText(permission.getName()); holder.mTvPermissionContent.setText(permission.getContent()); return convertView; } static class ViewHolder { @BindView(R.id.cl_wrap) ConstraintLayout mClWrap; @BindView(R.id.iv_permission) ImageView mIvPermission; @BindView(R.id.tv_permission_name) TextView mTvPermissionName; @BindView(R.id.tv_permission_content) TextView mTvPermissionContent; @BindView(R.id.cb_permission_check) CheckBox mCbPermissionCheck; ViewHolder(View view) { ButterKnife.bind(this, view); } } private void showPermission(Context context, PermissionListener permissionListener, String permission) { TedPermission.with(context) .setPermissionListener(permissionListener) .setDeniedMessage("모든 권한이 승인되지 않은 경우, 근태관리 앱을 사용할 수 없습니다.") .setPermissions(permission) .check(); } private boolean permissionCheck(Context context) { for (PermissionType permissionType : PermissionType.values()) { if (!permissionType.permissionCheck(context)) { return false; } } return true; } }2. Model
// 코틀린 data class로 기존 모델 대체 data class Permission( var icon: Drawable? = null, var name: String = "", var content: String = "" )
3. Enum(Permission 열거형)
// 재사용을 위해 코틀린 열거형으로 퍼미션 상수 및 퍼미션 체크 함수 작성 enum class PermissionType(val permissionValue: String) { READ_PHONE_STATE(Manifest.permission.READ_PHONE_STATE), // 전화 WRITE_EXTERNAL_STORAGE(Manifest.permission.WRITE_EXTERNAL_STORAGE), // 저장소 RECORD_AUDIO(Manifest.permission.RECORD_AUDIO); // 녹음 // 퍼미션 체크 fun permissionCheck(context: Context) = ContextCompat.checkSelfPermission(context, permissionValue) == PackageManager.PERMISSION_GRANTED }
4. Activity
public class PermissionActivity extends Activity { @BindView(R.id.lv_permission) ListView mLvPermission; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_permission); ButterKnife.bind(this); PermissionAdapter permissionAdapter = new PermissionAdapter(this); mLvPermission.setAdapter(permissionAdapter); } }
'Before 2022 > Android' 카테고리의 다른 글
Event Bus (0) | 2019.05.20 |
---|---|
FCM 푸시 구현하기 - 준비 작업 (0) | 2019.04.09 |
퍼미션 Enum으로 관리하기 (0) | 2019.03.13 |
안드로이드 사운드 기기 및 상태 관리(Kotlin) (0) | 2019.03.13 |
안드로이드 고음질 녹음 (0) | 2019.01.31 |