Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
NoNews committed Nov 5, 2017
2 parents dc4fd44 + 6fc38f6 commit ff49933
Show file tree
Hide file tree
Showing 13 changed files with 467 additions and 116 deletions.
4 changes: 2 additions & 2 deletions library/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ android {
minSdkVersion 15
targetSdkVersion 25
versionCode 1
versionName "1.0"
versionName "1.1.1"

testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

Expand Down Expand Up @@ -42,7 +42,7 @@ dependencies {
publish {
groupId = 'ru.alexbykov'
artifactId = 'nopermission'
publishVersion = '1.1.0'
publishVersion = '1.1.1'
desc = 'Permission library for Android'
licences = ['Apache-2.0']
website = 'https://github.com/NoNews/NoPermission'
Expand Down
158 changes: 126 additions & 32 deletions library/src/main/java/ru/alexbykov/nopermission/PermissionHelper.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
package ru.alexbykov.nopermission;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.provider.Settings;
import android.support.annotation.RequiresApi;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.support.v7.app.AppCompatActivity;

import java.util.ArrayList;
import java.util.List;
Expand All @@ -16,25 +23,31 @@
*
* @author Mike Antipiev @nindzyago
* @author Alex Bykov @NoNews
* @version 1.0.8
* @version 1.1.1
*/
public class PermissionHelper {


private static final int PERMISSION_REQUEST_CODE = 1005001;
private static final int PERMISSION_REQUEST_CODE = 98;
private Activity activity;
private Fragment fragment;
private String[] permissions;
private Runnable successListener;
private Runnable failureListener;
private Runnable deniedListener;
private Runnable neverAskAgainListener;

public PermissionHelper(Activity activity) {
this.activity = activity;
}

public PermissionHelper(Fragment fragment) {
this.fragment = fragment;
}


/**
* @param permission is single permission, which you want to ask
* @return current object
*/
public PermissionHelper check(String permission) {
this.permissions = new String[1];
Expand All @@ -45,6 +58,7 @@ public PermissionHelper check(String permission) {

/**
* @param permissions is array of permissions, which you want to ask
* @return current object
*/
public PermissionHelper check(String... permissions) {
this.permissions = permissions;
Expand All @@ -56,6 +70,7 @@ public PermissionHelper check(String... permissions) {
* Setup failure callback
*
* @param listener called when user deny permission
* @return current object
*/
public PermissionHelper onSuccess(Runnable listener) {
this.successListener = listener;
Expand All @@ -66,17 +81,28 @@ public PermissionHelper onSuccess(Runnable listener) {
* Setup failure callback
*
* @param listener called when user deny permission
* @return current object
*/
public PermissionHelper onFailure(Runnable listener) {
this.failureListener = listener;
public PermissionHelper onDenied(Runnable listener) {
this.deniedListener = listener;
return this;
}

/**
* @deprecated use method onFailure instead that
*
*/
@Deprecated
public PermissionHelper onFailure(Runnable listener) {
this.deniedListener = listener;
return this;
}

/**
* Setup never ask again callback
* This method setup never ask again callback
*
* @param listener called when permission in status "never ask again"
* @return current object
*/
public PermissionHelper onNeverAskAgain(Runnable listener) {
this.neverAskAgainListener = listener;
Expand All @@ -85,48 +111,76 @@ public PermissionHelper onNeverAskAgain(Runnable listener) {


/**
* Check API-version and listeners
* This method check API-version and listeners
*
* @throws RuntimeException if one of the listeners null
* @throws RuntimeException if isListenersCorrect return false
*/
public void run() {
if (isListenersCorrect()) {
if (isNeedToAskPermissions()) {
checkPermissions();
} else {
successListener.run();
}
runSuccessOrAskPermissions();
} else {
throw new RuntimeException("OnPermissionSuccessListener or OnPermissionFailureListener not installed. Please, use onSuccess and onFailure methods");
throw new RuntimeException("permissionSuccessListener or permissionDeniedListener have null reference. You must realize onSuccess and onDenied methods");
}
}


/**
* Request only those permissions that are not granted.
* If all are granted, the success method is triggered
* This method run successListener if all permissions granted,
* and run method checkPermissions, if needToAskPermissions return false
*/
private void runSuccessOrAskPermissions() {
if (isNeedToAskPermissions()) {
checkPermissions();
} else {
successListener.run();
}
}


/**
* This method request only those permissions that are not granted.
* If all are granted, success callback called
*/
@RequiresApi(api = Build.VERSION_CODES.M)
private void checkPermissions() {
final String[] permissionsForRequest = getPermissionsForRequest();
if (permissionsForRequest.length > 0) {
activity.requestPermissions(permissionsForRequest, PERMISSION_REQUEST_CODE);
askPermissions(permissionsForRequest);
} else {
successListener.run();
}
}


/**
* Check listeners for null
* This method ask permission
* @param permissionsForRequest array of permissions which you want to ask
*/

@SuppressLint("NewApi")
private void askPermissions(String[] permissionsForRequest) {
if (activity != null) {
activity.requestPermissions(permissionsForRequest, PERMISSION_REQUEST_CODE);
} else {
fragment.requestPermissions(permissionsForRequest, PERMISSION_REQUEST_CODE);
}
}


/**
* This method check listeners for null
*
* @return true if you realized method onSuccess and onDenied
*/
private boolean isListenersCorrect() {
return successListener != null && failureListener != null;
return successListener != null && deniedListener != null;
}


/**
* We need to ask permission only if API >=23
* This method ckeck api version
*
* @return true if API >=23
*/
private boolean isNeedToAskPermissions() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M;
Expand Down Expand Up @@ -159,21 +213,32 @@ public void onRequestPermissionsResult(int requestCode, String[] permissions, in
if (requestCode == PERMISSION_REQUEST_CODE && isNeedToAskPermissions()) {
for (String permission : permissions) {
if (isPermissionNotGranted(permission)) {
if (isNeverAskAgain(permission)) {
runNeverAskAgain();
} else {
failureListener.run();
}
runDeniedOrNeverAskAgain(permission);
return;
}
}
}
successListener.run();
}

/**
* This method run denied or neverAskAgain callbacks
*
* @param permission Permissions, which granted
*/

@SuppressLint("NewApi")
private void runDeniedOrNeverAskAgain(String permission) {
if (isNeverAskAgain(permission)) {
runNeverAskAgain();
} else {
deniedListener.run();
}
}


/**
* run never ask again callback
* This method run neverAskAgain callback if neverAskAgainListener not null
*/
private void runNeverAskAgain() {
if (neverAskAgainListener != null) {
Expand All @@ -187,25 +252,54 @@ private void runNeverAskAgain() {
* @return true if permission granted and false if permission not granted
*/
private boolean isPermissionNotGranted(String permission) {
return ActivityCompat.checkSelfPermission(activity, permission) != PackageManager.PERMISSION_GRANTED;
if (activity != null) {
return ActivityCompat.checkSelfPermission(activity, permission) != PackageManager.PERMISSION_GRANTED;
} else {
return ActivityCompat.checkSelfPermission(fragment.getContext(), permission) != PackageManager.PERMISSION_GRANTED;
}
}


/**
* Check neverAskAgain
* @param permission for check neverAskAgain
* @return true if user checked "Never Ask Again"
*/
@RequiresApi(api = Build.VERSION_CODES.M)
private boolean isNeverAskAgain(String permission) {
return !activity.shouldShowRequestPermissionRationale(permission);
if (activity != null) {
return !activity.shouldShowRequestPermissionRationale(permission);
} else {
return !fragment.shouldShowRequestPermissionRationale(permission);
}
}


/**
* This method start application settings activity
* Note: is not possible to open at once screen with application permissions.
*/
public void startApplicationSettingsActivity() {
final Context context = activity == null ? fragment.getContext() : activity;
final Intent intent = new Intent();
final Uri uri = Uri.fromParts("package", context.getPackageName(), null);
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setData(uri);
context.startActivity(intent);
}

/**
* To avoid memory leaks, you must change reference to null
* This method change listeners reference to avoid memory leaks
*/
public void unsubscribe() {
activity = null;
failureListener = null;
deniedListener = null;
successListener = null;

if (activity != null) {
activity = null;
}
if (fragment != null) {
fragment = null;
}
if (neverAskAgainListener != null) {
neverAskAgainListener = null;
}
Expand Down
10 changes: 10 additions & 0 deletions sample/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,27 @@ android {

testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

jackOptions {
enabled true
}
}


buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
compileOptions {
targetCompatibility 1.8
sourceCompatibility 1.8
}
}

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:support-v4:26.1.0'
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
Expand Down
21 changes: 15 additions & 6 deletions sample/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="ru.alexbykov.permissionssample">
package="ru.alexbykov.permissionssample">

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.READ_CONTACTS" />

<application
android:allowBackup="true"
Expand All @@ -13,12 +13,21 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".activities.LocationSampleActivity">
<!--<intent-filter>-->
<!--<action android:name="android.intent.action.MAIN" />-->

<!--<category android:name="android.intent.category.LAUNCHER" />-->
<!--</intent-filter>-->
</activity>
<activity android:name=".MainActivity">

<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER"/>
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>

</activity>
</application>

Expand Down
Loading

0 comments on commit ff49933

Please sign in to comment.