فهرست منبع

[스플래시][New] 첫 실행 퍼미션 체크 완료

hyodong.min 6 سال پیش
والد
کامیت
4ae1d4e309

+ 0 - 3
.idea/gradle.xml

@@ -3,9 +3,6 @@
   <component name="GradleSettings">
     <option name="linkedExternalProjectsSettings">
       <GradleProjectSettings>
-        <compositeConfiguration>
-          <compositeBuild compositeDefinitionSource="SCRIPT" />
-        </compositeConfiguration>
         <option name="distributionType" value="DEFAULT_WRAPPED" />
         <option name="externalProjectPath" value="$PROJECT_DIR$" />
         <option name="modules">

+ 3 - 0
app/src/main/java/kr/co/zumo/app/lifeplus/activity/ActivityBase.java

@@ -200,9 +200,12 @@ public abstract class ActivityBase extends AppCompatActivity implements IHelperP
   @Override
   protected final void onResume() {
     Log.w("APP# ActivityBase | onResume", "| >>>>>> " + this.getClass().getSimpleName() + " HC: " + this.hashCode());
+    onResumeInternal();
     super.onResume();
   }
 
+  protected void onResumeInternal() {}
+
   @Override
   protected final void onPause() {
 

+ 57 - 11
app/src/main/java/kr/co/zumo/app/lifeplus/activity/ISplashContract.java

@@ -3,6 +3,8 @@
  */
 package kr.co.zumo.app.lifeplus.activity;
 
+import android.content.Context;
+import android.support.annotation.NonNull;
 import android.support.v4.app.FragmentActivity;
 
 /**
@@ -19,17 +21,39 @@ public interface ISplashContract {
 
   interface View {
     FragmentActivity getActivity();
+
+    /**
+     * 권한 획득 완룐
+     */
+    void onPermissionCompleted();
+
+    /**
+     * 위치 앱 권환 요청
+     *
+     * @param permissions
+     */
+    void requestLocationPermissions(@NonNull String[] permissions);
   }
 
   interface Presenter {
 
-    void launchLocationPermission(Runnable runnable);
-
-    void launchDeviceLocationPermission(Runnable runnable);
+    /**
+     * 전체 퍼미션 확인
+     */
+    void launchAllPermission();
 
-    void launchPushPermission(Runnable runnable);
+    /**
+     * 디바이스 위치 서비스 설정 후 재시작
+     */
+    void onResume();
 
-    void launchAllPermission(Runnable runnable);
+    /**
+     * 권한 확인 결과
+     *
+     * @param permissions
+     * @param grantResults
+     */
+    void onRequestPermissionsResult(String[] permissions, int[] grantResults);
   }
 
   interface Model {
@@ -38,8 +62,6 @@ public interface ISplashContract {
      *
      * @return
      */
-    boolean isPushContentsAndService();
-
     void setPushContentsAndService(boolean isEnabled);
 
     /**
@@ -47,8 +69,6 @@ public interface ISplashContract {
      *
      * @return
      */
-    boolean isPushEventEnabled();
-
     void setPushEventEnabled(boolean isEnabled);
 
     /**
@@ -56,8 +76,34 @@ public interface ISplashContract {
      *
      * @return
      */
-    boolean isLocationServiceEnabled();
-
     void setLocationServiceEnabled(boolean isEnabled);
+
+    /**
+     * 퍼미션 확인 완료
+     */
+    boolean getFirstPermissionCompleted();
+
+    void setFirstPermissionCompleted();
+
+    /**
+     * 장치 위치 서비스 사용 가능
+     *
+     * @return
+     */
+    boolean canAccessDeviceLocating(Context context);
+
+    /**
+     * 위치 서비스 앱 권한 확인
+     *
+     * @return
+     */
+    boolean hasLocationPermissions(Context context);
+
+    /**
+     * 위치 서비스 앱 권한
+     *
+     * @return
+     */
+    String getPermissionsString();
   }
 }

+ 37 - 4
app/src/main/java/kr/co/zumo/app/lifeplus/activity/SplashActivity.java

@@ -3,11 +3,15 @@ package kr.co.zumo.app.lifeplus.activity;
 import android.content.Context;
 import android.content.Intent;
 import android.net.Uri;
+import android.support.annotation.NonNull;
+import android.support.v4.app.ActivityCompat;
 import android.support.v4.app.FragmentActivity;
 import android.util.Log;
 
 import com.google.firebase.dynamiclinks.FirebaseDynamicLinks;
 
+import java.util.Arrays;
+
 import io.reactivex.android.schedulers.AndroidSchedulers;
 import io.reactivex.disposables.CompositeDisposable;
 import io.reactivex.schedulers.Schedulers;
@@ -46,10 +50,12 @@ public class SplashActivity extends ActivityBaseSetup implements ISplashContract
     SuperModelInit.instant(getApplicationContext());
     presenter = new SplashPresenter(new SplashModel(), this);
 
-    presenter.launchAllPermission(() -> {
-      // 권한 처리 종료
-      controlDynamicLink();
-    });
+    presenter.launchAllPermission();
+  }
+
+  @Override
+  protected void onResumeInternal() {
+    presenter.onResume();
   }
 
   private void controlDynamicLink() {
@@ -180,9 +186,36 @@ public class SplashActivity extends ActivityBaseSetup implements ISplashContract
     doOnLink();
   }
 
+  /***********************************
+   * ISplashContract.View
+   ***********************************/
   @Override
   public FragmentActivity getActivity() {
     return this;
   }
+
+  @Override
+  public void onPermissionCompleted() {
+    // 권한 처리 종료
+    controlDynamicLink();
+  }
+
+  @Override
+  public void requestLocationPermissions(@NonNull String[] permissions) {
+    Log.i("APP# MainFragment | requestLocationPermissions", "|" + " permissions: " + Arrays.toString(permissions));
+    ActivityCompat.requestPermissions(this, permissions, 9909);
+  }
+
+  @Override
+  public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
+    switch (requestCode) {
+      case 9909: {
+        presenter.onRequestPermissionsResult(permissions, grantResults);
+        break;
+      }
+      default:
+        break;
+    }
+  }
 }
 

+ 38 - 15
app/src/main/java/kr/co/zumo/app/lifeplus/activity/SplashModel.java

@@ -3,6 +3,12 @@
  */
 package kr.co.zumo.app.lifeplus.activity;
 
+import android.Manifest;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.location.LocationManager;
+import android.support.v4.app.ActivityCompat;
+
 import kr.co.zumo.app.lifeplus.model.SuperModel;
 
 /**
@@ -23,12 +29,8 @@ class SplashModel implements ISplashContract.Model {
   /**
    * 푸쉬 알림 설정
    *
-   * @return
    */
-  public boolean isPushContentsAndService() {
-    return SuperModel.getInstance().getPreferences().isPushContentsAndService();
-  }
-
+  @Override
   public void setPushContentsAndService(boolean isEnabled) {
     SuperModel.getInstance().getPreferences().setPushContentsAndService(isEnabled);
   }
@@ -36,12 +38,8 @@ class SplashModel implements ISplashContract.Model {
   /**
    * 푸쉬 마케팅 알림 설정
    *
-   * @return
    */
-  public boolean isPushEventEnabled() {
-    return SuperModel.getInstance().getPreferences().isPushEventEnabled();
-  }
-
+  @Override
   public void setPushEventEnabled(boolean isEnabled) {
     SuperModel.getInstance().getPreferences().setPushEventEnabled(isEnabled);
   }
@@ -49,13 +47,38 @@ class SplashModel implements ISplashContract.Model {
   /**
    * 위치 서비스 설정
    *
-   * @return
    */
-  public boolean isLocationServiceEnabled() {
-    return SuperModel.getInstance().getPreferences().isLocationServiceEnabled();
-  }
-
+  @Override
   public void setLocationServiceEnabled(boolean isEnabled) {
     SuperModel.getInstance().getPreferences().setLocationServiceEnabled(isEnabled);
   }
+
+  @Override
+  public boolean getFirstPermissionCompleted() {
+    return SuperModel.getInstance().getPreferences().getFirstPermissionCompleted();
+  }
+
+  @Override
+  public void setFirstPermissionCompleted() {
+    SuperModel.getInstance().getPreferences().setFirstPermissionCompleted();
+  }
+
+  @Override
+  public boolean canAccessDeviceLocating(Context context) {
+    LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
+    if (locationManager != null) {
+      return locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
+    }
+    return false;
+  }
+
+  @Override
+  public boolean hasLocationPermissions(Context context) {
+    return ActivityCompat.checkSelfPermission(context, getPermissionsString()) == PackageManager.PERMISSION_GRANTED;
+  }
+
+  @Override
+  public String getPermissionsString() {
+    return Manifest.permission.ACCESS_FINE_LOCATION;
+  }
 }

+ 100 - 36
app/src/main/java/kr/co/zumo/app/lifeplus/activity/SplashPresenter.java

@@ -3,9 +3,14 @@
  */
 package kr.co.zumo.app.lifeplus.activity;
 
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.provider.Settings;
+import android.util.Log;
+
+import java.util.Arrays;
+
 import kr.co.zumo.app.R;
-import kr.co.zumo.app.lifeplus.model.SuperModel;
-import kr.co.zumo.app.lifeplus.util.ResourceUtil;
 import kr.co.zumo.app.lifeplus.view.Event;
 import kr.co.zumo.app.lifeplus.view.dialog.ConfirmDialog;
 import kr.co.zumo.app.lifeplus.view.dialog.DialogBuilder;
@@ -27,76 +32,135 @@ public class SplashPresenter implements ISplashContract.Presenter {
   private ISplashContract.Model model;
   private ISplashContract.View view;
 
+  private boolean isRequestingLocationService = false;
+
   public SplashPresenter(ISplashContract.Model model, ISplashContract.View view) {
     this.model = model;
     this.view = view;
   }
 
-  @Override
-  public void launchLocationPermission(Runnable runnable) {
-    runnable.run();
-  }
-
-  @Override
-  public void launchDeviceLocationPermission(Runnable runnable) {
-    runnable.run();
+  private void launchLocationPermission(Runnable runnable) {
+    if (model.hasLocationPermissions(view.getActivity())) {
+      // 위치 앱 권한
+      runnable.run();
+    }
+    else {
+      view.requestLocationPermissions(new String[]{model.getPermissionsString()});
+    }
   }
 
-  @Override
-  public void launchPushPermission(Runnable runnable) {
-
-    if (SuperModel.getInstance().getPreferences().getFirstPermissionCompleted()) {
-      // 이미 설정했다면 다음으로 이동
+  private void launchDeviceLocationPermission(Runnable runnable) {
+    if (model.canAccessDeviceLocating(view.getActivity())) {
+      // 위치 서비스 이용 가능하다면 다음으로  이동
       runnable.run();
     }
     else {
-      SuperModel.getInstance().getPreferences().setFirstPermissionCompleted();
-      // 설정 창 표시
-      launchPushPermissionInternal(runnable);
+      launchInternal(() -> {
+
+        isRequestingLocationService = true;
+        Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
+        view.getActivity().startActivity(intent);
+
+      }, runnable, R.string.splash_permission_device_location_title, R.string.splash_permission_device_location_contents, R.string.cancel, R.string.splash_permission_device_location_accept);
     }
   }
 
-  private void launchPushPermissionInternal(Runnable runnable) {
+  private void launchPushPermission(Runnable runnable) {
+    // 설정 창 표시
+    launchInternal(() -> {
+
+      model.setPushContentsAndService(true);
+      model.setPushEventEnabled(true);
+      runnable.run();
+
+    }, runnable, R.string.splash_permission_push_title, R.string.splash_permission_push_contents, R.string.splash_permission_do_not_accept, R.string.splash_permission_accept);
+
+  }
+
+  private void launchInternal(Runnable runnableConfirm, Runnable runnableNext, int titleId, int contentsId, int negativeId, int positiveId) {
     new DialogBuilder<ConfirmDialog, ICustomConfirmListener>(view.getActivity().getSupportFragmentManager(), DialogID.CONFIRM)
       .listener(new ICustomConfirmListener<ConfirmDialog>() {
         @Override
         public void onPositiveResult(ConfirmDialog dialog, Event event) {
-          model.setPushContentsAndService(true);
-          model.setPushEventEnabled(true);
-
-          this.onDialogCanceled(dialog);
+          runnableConfirm.run();
         }
 
         @Override
         public void onNegativeResult(ConfirmDialog dialog, Event event) {
-          this.onDialogCanceled(dialog);
+          dialog.dispose();
+          runnableNext.run();
         }
 
         @Override
         public void onDialogCanceled(ConfirmDialog dialog) {
           dialog.dispose();
-          runnable.run();
+          runnableNext.run();
         }
       })
       .attribute(dialog -> {
-        dialog.setTitleId(R.string.splash_permission_push_title);
-        dialog.setText(ResourceUtil.getString(R.string.splash_permission_push_contents));
-        dialog.setNegativeButtonLabelId(R.string.splash_permission_do_not_accept);
-        dialog.setPositiveButtonLabelId(R.string.splash_permission_accept);
+        dialog.setCancelable(false);
+        dialog.setTitleId(titleId);
+        dialog.setText(contentsId);
+        dialog.setNegativeButtonLabelId(negativeId);
+        dialog.setPositiveButtonLabelId(positiveId);
       })
       .show();
   }
 
   @Override
-  public void launchAllPermission(Runnable runnable) {
+  public void launchAllPermission() {
+    // 앱 첫 실행시에만 실행한다.
+    if (model.getFirstPermissionCompleted()) {
+      // 이미 처리 완료했음.
+      view.onPermissionCompleted();
+    }
+    else {
+      model.setFirstPermissionCompleted();
 
-    launchPushPermission(() -> {
-      launchDeviceLocationPermission(() -> {
-        launchLocationPermission(() -> {
-          // 권한 처리 종료
-          runnable.run();
+      launchPushPermission(() -> {
+        launchDeviceLocationPermission(() -> {
+          launchLocationPermission(() -> {
+            // 권한 처리 종료
+            view.onPermissionCompleted();
+          });
         });
       });
-    });
+    }
+  }
+
+  @Override
+  public void onResume() {
+    if (isRequestingLocationService) {
+      isRequestingLocationService = false;
+
+      launchLocationPermission(() -> {
+        // 권한 처리 종료
+        view.onPermissionCompleted();
+      });
+    }
+  }
+
+  @Override
+  public void onRequestPermissionsResult(String[] permissions, int[] grantResults) {
+    Log.i("APP# SplashPresenter | onRequestPermissionsResult", "|" + " grantResults: " + Arrays.toString(grantResults));
+    // If request is cancelled, the result arrays are empty.
+    if (grantResults.length > 0) {
+      // permission was granted
+      boolean granted = true;
+      for (int grantResult : grantResults) {
+        if (grantResult != PackageManager.PERMISSION_GRANTED) {
+          granted = false;
+          break;
+        }
+      }
+
+      if (granted) {
+        // 모두 허용
+        model.setLocationServiceEnabled(true);
+
+        // 권한 처리 종료
+        view.onPermissionCompleted();
+      }
+    }
   }
 }

+ 18 - 1
app/src/main/java/kr/co/zumo/app/lifeplus/view/dialog/ConfirmDialog.java

@@ -24,6 +24,7 @@ import kr.co.zumo.app.lifeplus.view.Event;
  */
 public class ConfirmDialog extends TextDialog<ICustomConfirmListener<ConfirmDialog>> {
 
+  protected boolean isCancelable = true;
   @StringRes
   protected int positiveButtonLabel = R.string.empty_string;
   @StringRes
@@ -31,6 +32,17 @@ public class ConfirmDialog extends TextDialog<ICustomConfirmListener<ConfirmDial
   @StringRes
   protected int titleStringId = R.string.empty_string;
 
+  /**
+   * back key 가능 여부 설정
+   *
+   * @param cancelable
+   */
+  @Override
+  public void setCancelable(boolean cancelable) {
+    super.setCancelable(cancelable);
+    isCancelable = cancelable;
+  }
+
   /**
    * 표시할 positiveButtonLabel 지정
    *
@@ -87,11 +99,16 @@ public class ConfirmDialog extends TextDialog<ICustomConfirmListener<ConfirmDial
           }
         }
       });
+
     if (titleStringId != R.string.empty_string) {
       builder.setTitle(titleStringId);
     }
+    builder.setCancelable(isCancelable);
+    android.support.v7.app.AlertDialog alert = builder.create();
+    alert.setCancelable(isCancelable);
+    alert.setCanceledOnTouchOutside(isCancelable);
     // Create the AlertDialog object and return it
-    return builder.create();
+    return alert;
 
   }
 

+ 1 - 0
app/src/main/res/values/strings.xml

@@ -18,6 +18,7 @@
   <string name="splash_permission_location_contents">날씨 정보를 받기 위해 앱을 사용하는 동안에만 현재 위치에 접근합니다.</string>
   <string name="splash_permission_accept">허용</string>
   <string name="splash_permission_do_not_accept">허용 안 함</string>
+  <string name="splash_permission_device_location_accept">설정으로 이동</string>
 
   <!--공유 관련 설정 -->
   <string name="lifeplus_www_url">"https://www.lifeplus.co.kr/"</string>