From http://www.jwz.org/xscreensaver/xscreensaver-5.40.tar.gz
[xscreensaver] / android / xscreensaver / src / org / jwz / xscreensaver / Activity.java
index 1209c1b7da49a2d1c4f84096ed9758641100880f..ac0ab4c10b13cc9a713a8594897dda6ce5ca54db 100644 (file)
@@ -24,15 +24,25 @@ import android.os.Build;
 import android.os.Bundle;
 import android.view.View;
 import android.provider.Settings;
+import android.Manifest;
+import android.support.v4.app.ActivityCompat;
+import android.support.v4.content.ContextCompat;
+import android.os.Build;
+import android.content.pm.PackageManager;
 
 public class Activity extends android.app.Activity
   implements View.OnClickListener {
 
+  private boolean wallpaperButtonClicked, daydreamButtonClicked;
+  private final static int MY_REQ_READ_EXTERNAL_STORAGE = 271828;
+
   @Override
   protected void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     // openList();
     setContentView(R.layout.activity_xscreensaver);
+    wallpaperButtonClicked = false;
+    daydreamButtonClicked = false;
 
     findViewById(R.id.apply_wallpaper).setOnClickListener(this);
     findViewById(R.id.apply_daydream).setOnClickListener(this);
@@ -42,10 +52,18 @@ public class Activity extends android.app.Activity
   public void onClick(View v) {
     switch (v.getId()) {
     case R.id.apply_wallpaper:
-      startActivity(new Intent(WallpaperManager.ACTION_LIVE_WALLPAPER_CHOOSER));
+      wallpaperButtonClicked();
       break;
-
     case R.id.apply_daydream:
+      daydreamButtonClicked();
+      break;
+    }
+  }
+
+  // synchronized when dealing with wallpaper state - perhaps can
+  // narrow down more
+  private synchronized void withProceed() {
+    if (daydreamButtonClicked) {
       String action;
       if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
         action = Settings.ACTION_DREAM_SETTINGS;
@@ -53,7 +71,99 @@ public class Activity extends android.app.Activity
         action = Settings.ACTION_DISPLAY_SETTINGS;
       }
       startActivity(new Intent(action));
-      break;
+    } else if (wallpaperButtonClicked) {
+      startActivity(new Intent(WallpaperManager.ACTION_LIVE_WALLPAPER_CHOOSER));
+    }
+  }
+
+  private void wallpaperButtonClicked() {
+      wallpaperButtonClicked = true;
+      checkPermission();
+  }
+
+  private void daydreamButtonClicked() {
+      daydreamButtonClicked = true;
+      checkPermission();
+  }
+
+  void checkPermission() {
+      // RES introduced in API 16
+      String permission = Manifest.permission.READ_EXTERNAL_STORAGE;
+      if (havePermission(permission)) {
+          withProceed();
+      } else {
+          noPermission(permission);
+      }
+  }
+
+  private void noPermission(String permission) {
+      int myRequestCode;
+      myRequestCode = MY_REQ_READ_EXTERNAL_STORAGE;
+
+      if (permissionsDeniedRationale(permission)) {
+          showDeniedRationale();
+      } else {
+          requestPermission(permission, myRequestCode);
+      }
+  }
+
+  private boolean permissionsDeniedRationale(String permission) {
+      boolean rationale = ActivityCompat.shouldShowRequestPermissionRationale(this,
+                permission);
+      return rationale;
+  }
+
+  private void requestPermission(String permission, int myRequestCode) {
+      ActivityCompat.requestPermissions(this,
+              new String[]{permission},
+              myRequestCode);
+
+      // myRequestCode is an app-defined int constant.
+      // The callback method gets the result of the request.
+  }
+
+  // TODO: This method should be asynchronous, and not block the thread
+  private void showDeniedRationale() {
+    withProceed();
+  }
+
+  boolean havePermission(String permission) {
+
+      if (Build.VERSION.SDK_INT < 16) {
+          return true;
+      }
+
+      if (permissionGranted(permission)) {
+          return true;
+      }
+
+      return false;
+  }
+
+  private boolean permissionGranted(String permission) {
+        boolean check = ContextCompat.checkSelfPermission(this, permission) ==
+                PackageManager.PERMISSION_GRANTED;
+      return check;
+  }
+
+  public void proceedIfPermissionGranted(int[] grantResults) {
+
+      // If request is cancelled, the result arrays are empty.
+      if (grantResults.length > 0
+              && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+          withProceed();
+      } else if (grantResults.length > 0) {
+          withProceed();
+      }
+  }
+
+  @Override
+  public void onRequestPermissionsResult(int requestCode,
+        String permissions[], int[] grantResults) {
+    switch (requestCode) {
+      case MY_REQ_READ_EXTERNAL_STORAGE:
+          proceedIfPermissionGranted(grantResults);
     }
   }
+
 }