/* * Copyright 2015. Appsi Mobile * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package com.appsimobile.appsii.permissions; import android.app.Activity; import android.app.Fragment; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.os.Build; import android.provider.Settings; import android.support.annotation.NonNull; import android.support.annotation.StringRes; import android.util.Log; import com.appsimobile.appsii.BuildConfig; import com.appsimobile.appsii.PermissionDeniedException; import com.appsimobile.appsii.RequestPermissionActivity; import com.appsimobile.appsii.SidebarContext; import javax.inject.Inject; import javax.inject.Singleton; /** * Created by nick on 10/06/15. */ @Singleton public class PermissionUtils { public static final String EXTRA_PERMISSIONS = BuildConfig.APPLICATION_ID + ".PERMISSION_NAMES"; public static final String EXTRA_REQUEST_CODE = BuildConfig.APPLICATION_ID + ".REQ_CODE"; public static final String ACTION_PERMISSION_RESULT = BuildConfig.APPLICATION_ID + ".ACTION_PERMISSION_RESULT"; public static final String EXTRA_GRANT_RESULTS = BuildConfig.APPLICATION_ID + ".GRANT_RESULT"; public static final int REQUEST_CODE_PERMISSION_READ_CALENDAR = 100; public static final int REQUEST_CODE_PERMISSION_READ_CALL_LOG = 101; public static final int REQUEST_CODE_PERMISSION_READ_CONTACTS = 102; SharedPreferences mSharedPreferences; @Inject public PermissionUtils(SharedPreferences preferences) { mSharedPreferences = preferences; } /** * Throws an exception if a permission is not available. Does nothing if runtime * permissions are not available. * * @throws PermissionDeniedException */ public void throwIfNotPermitted(Context context, String permissionName) throws PermissionDeniedException { if (!runtimePermissionsAvailable()) return; int result = context.checkSelfPermission(permissionName); if (result != PackageManager.PERMISSION_GRANTED) { throw new PermissionDeniedException(permissionName); } } /** * Returns true when runtime permissions are available. This means, when running on * Android M */ public boolean runtimePermissionsAvailable() { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M; } /** * Returns true when the app holds the given permission. Always returns true on * devices that do not have runtime permissions (pre-M). */ public boolean holdsPermission(Context context, String permissionName) { if (!runtimePermissionsAvailable()) return true; int result = context.checkSelfPermission(permissionName); return result == PackageManager.PERMISSION_GRANTED; } public boolean holdsAllPermissions(Context context, String... permissionNames) { if (!runtimePermissionsAvailable()) return true; for (String permissionName : permissionNames) { if (context.checkSelfPermission(permissionName) != PackageManager.PERMISSION_GRANTED) { return false; } } return true; } /** * Removes a notification shown for a missing permission. Used in case * a permission that is absolutely required has been detected as granted. * Such as draw over other apps. */ public void cancelPermissionNotificationIfNeeded(Context context, int notificationId) { if (!runtimePermissionsAvailable()) return; } /** * Shows a notification for a missing permission. Used for permissions that are * absolutely required such as draw over other apps. These are checked the first * time the app starts. */ public void showPermissionNotification(Context context, int notificationId, String permissionName, @StringRes int permissionDescriptionResId) { if (!runtimePermissionsAvailable()) return; Log.w("PermissionHelper", "show permission denied: " + permissionName); } public void requestPermission( Activity activity, int requestCode, String... permissions) { if (!runtimePermissionsAvailable()) return; activity.requestPermissions(permissions, requestCode); } public void requestPermission( Fragment fragment, int requestCode, String... permissions) { if (!runtimePermissionsAvailable()) return; fragment.requestPermissions(permissions, requestCode); } /** * Returns an {@link android.content.Intent} suitable for passing to * {@link android.app.Activity#startActivity(Intent)} * which prompts the user to grant permissions to this application. * * @throws NullPointerException if {@code permissions} is {@code null} or empty. */ public Intent buildRequestPermissionsIntent(Context context, int requestCode, @NonNull String... permissions) { if (permissions.length == 0) { throw new NullPointerException("permission cannot be null or empty"); } Intent intent = new Intent(context, RequestPermissionActivity.class); intent.putExtra(EXTRA_PERMISSIONS, permissions); intent.putExtra(EXTRA_REQUEST_CODE, requestCode); return intent; } public boolean shouldShowPermissionError(SidebarContext context, String id) { String key = "show_error" + id; return mSharedPreferences.getBoolean(key, true); } public void setDontShowPermissionAgain(SidebarContext context, String id) { String key = "show_error" + id; mSharedPreferences.edit().putBoolean(key, false).apply(); } public boolean canDrawOverlays(Context context) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { return Settings.canDrawOverlays(context); } return true; } }