Loading app/src/main/java/org/lineageos/recorder/DialogActivity.java +17 −47 Original line number Diff line number Diff line Loading @@ -15,8 +15,6 @@ */ package org.lineageos.recorder; import android.Manifest; import android.content.pm.PackageManager; import android.os.Bundle; import androidx.annotation.NonNull; Loading @@ -25,17 +23,19 @@ import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.SwitchCompat; import org.lineageos.recorder.utils.PermissionManager; import org.lineageos.recorder.utils.Utils; public class DialogActivity extends AppCompatActivity { private static final int REQUEST_LOCATION_PERMS = 214; private PermissionManager mPermissionManager; private SwitchCompat mLocationSwitch; @Override protected void onCreate(@Nullable Bundle savedInstance) { super.onCreate(savedInstance); mPermissionManager = new PermissionManager(this); setFinishOnTouchOutside(true); final AlertDialog dialog = new AlertDialog.Builder(this) Loading @@ -62,33 +62,15 @@ public class DialogActivity extends AppCompatActivity { public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] results) { super.onRequestPermissionsResult(requestCode, permissions, results); if (hasLocationPermission()) { toggleAfterPermissionRequest(requestCode); return; } if (shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION)) { new AlertDialog.Builder(this) .setTitle(R.string.dialog_permissions_title) .setMessage(getString(R.string.dialog_permissions_location)) .setPositiveButton(R.string.dialog_permissions_ask, (dialog, position) -> { dialog.dismiss(); askLocationPermission(); }) .setNegativeButton(R.string.dialog_permissions_dismiss, (dialog, position) -> mLocationSwitch.setChecked(false)) .show(); if (requestCode == PermissionManager.REQUEST_CODE) { if (mPermissionManager.hasLocationPermission()) { toggleAfterPermissionRequest(); } else { // User has denied all the required permissions "forever" new AlertDialog.Builder(this) .setTitle(R.string.dialog_permissions_title) .setMessage(R.string.snack_permissions_no_permission_location) .setPositiveButton(R.string.dialog_permissions_dismiss, null) .show(); mPermissionManager.onLocationPermissionDenied(); mLocationSwitch.setChecked(false); } } } @Override public void onBackPressed() { Loading @@ -105,7 +87,7 @@ public class DialogActivity extends AppCompatActivity { boolean isRecording) { final boolean tagWithLocation; if (Utils.getTagWithLocation(this)) { if (hasLocationPermission()) { if (mPermissionManager.hasLocationPermission()) { tagWithLocation = true; } else { // Permission revoked -> disabled feature Loading @@ -123,10 +105,10 @@ public class DialogActivity extends AppCompatActivity { } else { locationSwitch.setOnCheckedChangeListener((button, isChecked) -> { if (isChecked) { if (hasLocationPermission()) { if (mPermissionManager.hasLocationPermission()) { Utils.setTagWithLocation(this, true); } else { askLocationPermission(); mPermissionManager.requestLocationPermission(); } } else { Utils.setTagWithLocation(this, false); Loading @@ -148,20 +130,8 @@ public class DialogActivity extends AppCompatActivity { } } private boolean hasLocationPermission() { int result = checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION); return result == PackageManager.PERMISSION_GRANTED; } private void askLocationPermission() { requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_LOCATION_PERMS); } private void toggleAfterPermissionRequest(int requestCode) { if (requestCode == REQUEST_LOCATION_PERMS) { private void toggleAfterPermissionRequest() { mLocationSwitch.setChecked(true); Utils.setTagWithLocation(this, true); } } } app/src/main/java/org/lineageos/recorder/RecorderActivity.java +15 −96 Original line number Diff line number Diff line Loading @@ -17,7 +17,6 @@ package org.lineageos.recorder; import static android.provider.MediaStore.Audio.Media.RECORD_SOUND_ACTION; import android.Manifest; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; Loading @@ -25,7 +24,6 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.ServiceConnection; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.net.Uri; import android.os.Bundle; import android.os.Handler; Loading @@ -52,21 +50,11 @@ import org.lineageos.recorder.ui.WaveFormView; import org.lineageos.recorder.utils.LastRecordHelper; import org.lineageos.recorder.utils.LocationHelper; import org.lineageos.recorder.utils.OnBoardingHelper; import org.lineageos.recorder.utils.PermissionManager; import org.lineageos.recorder.utils.Utils; import java.util.ArrayList; public class RecorderActivity extends AppCompatActivity implements SharedPreferences.OnSharedPreferenceChangeListener { private static final int REQUEST_SOUND_REC_PERMS = 440; private static final int[] PERMISSION_ERROR_MESSAGE_RES_IDS = { 0, R.string.dialog_permissions_mic, R.string.dialog_permissions_phone, R.string.dialog_permissions_mic_phone, }; private ServiceConnection mConnection; private SoundRecorderService mSoundService; private SharedPreferences mPrefs; Loading @@ -78,6 +66,7 @@ public class RecorderActivity extends AppCompatActivity implements private WaveFormView mRecordingVisualizer; private LocationHelper mLocationHelper; private PermissionManager mPermissionManager; private TaskExecutor mTaskExecutor; private boolean mReturnAudio; Loading Loading @@ -121,6 +110,7 @@ public class RecorderActivity extends AppCompatActivity implements mPrefs.registerOnSharedPreferenceChangeListener(this); mLocationHelper = new LocationHelper(this); mPermissionManager = new PermissionManager(this); mTaskExecutor = new TaskExecutor(); getLifecycle().addObserver(mTaskExecutor); Loading Loading @@ -170,42 +160,12 @@ public class RecorderActivity extends AppCompatActivity implements @NonNull int[] results) { super.onRequestPermissionsResult(requestCode, permissions, results); if (hasAllAudioRecorderPermissions()) { toggleAfterPermissionRequest(requestCode); return; } if (shouldShowRequestPermissionRationale(Manifest.permission.RECORD_AUDIO) || shouldShowRequestPermissionRationale(Manifest.permission.READ_PHONE_STATE)) { // Explain the user why the denied permission is needed int error = 0; if (!hasAudioPermission()) { error |= 1; } if (!hasPhoneReaderPermission()) { error |= 1 << 1; } String message = getString(PERMISSION_ERROR_MESSAGE_RES_IDS[error]); new AlertDialog.Builder(this) .setTitle(R.string.dialog_permissions_title) .setMessage(message) .setPositiveButton(R.string.dialog_permissions_ask, (dialog, position) -> { dialog.dismiss(); askPermissionsAgain(requestCode); }) .setNegativeButton(R.string.dialog_permissions_dismiss, null) .show(); if (requestCode == PermissionManager.REQUEST_CODE) { if (mPermissionManager.hasEssentialPermissions()) { toggleAfterPermissionRequest(); } else { // User has denied all the required permissions "forever" new AlertDialog.Builder(this) .setTitle(R.string.dialog_permissions_title) .setMessage(R.string.snack_permissions_no_permission) .setPositiveButton(R.string.dialog_permissions_dismiss, null) .show(); mPermissionManager.onEssentialPermissionsDenied(); } } } Loading @@ -221,21 +181,13 @@ public class RecorderActivity extends AppCompatActivity implements } private void toggleAfterPermissionRequest(int requestCode) { if (requestCode == REQUEST_SOUND_REC_PERMS) { private void toggleAfterPermissionRequest() { bindSoundRecService(); new Handler(Looper.getMainLooper()).postDelayed(this::toggleSoundRecorder, 500); } } private void askPermissionsAgain(int requestCode) { if (requestCode == REQUEST_SOUND_REC_PERMS) { checkSoundRecPermissions(); } } private void toggleSoundRecorder() { if (checkSoundRecPermissions()) { if (mPermissionManager.requestEssentialPermissions()) { return; } Loading Loading @@ -305,42 +257,9 @@ public class RecorderActivity extends AppCompatActivity implements } } private boolean hasAudioPermission() { int result = checkSelfPermission(Manifest.permission.RECORD_AUDIO); return result == PackageManager.PERMISSION_GRANTED; } private boolean hasPhoneReaderPermission() { int result = checkSelfPermission(Manifest.permission.READ_PHONE_STATE); return result == PackageManager.PERMISSION_GRANTED; } private boolean hasAllAudioRecorderPermissions() { return hasAudioPermission() && hasPhoneReaderPermission(); } private boolean checkSoundRecPermissions() { ArrayList<String> permissions = new ArrayList<>(); if (!hasAudioPermission()) { permissions.add(Manifest.permission.RECORD_AUDIO); } if (!hasPhoneReaderPermission()) { permissions.add(Manifest.permission.READ_PHONE_STATE); } if (permissions.isEmpty()) { return false; } String[] permissionArray = permissions.toArray(new String[0]); requestPermissions(permissionArray, REQUEST_SOUND_REC_PERMS); return true; } private void setupConnection() { checkSoundRecPermissions(); mPermissionManager.requestEssentialPermissions(); mConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder binder) { Loading @@ -356,7 +275,7 @@ public class RecorderActivity extends AppCompatActivity implements } private void bindSoundRecService() { if (mSoundService == null && hasAllAudioRecorderPermissions()) { if (mSoundService == null && mPermissionManager.hasEssentialPermissions()) { setupConnection(); bindService(new Intent(this, SoundRecorderService.class), mConnection, BIND_AUTO_CREATE); Loading app/src/main/java/org/lineageos/recorder/utils/PermissionManager.java 0 → 100644 +142 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 The LineageOS Project * * 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 org.lineageos.recorder.utils; import android.Manifest; import android.app.Activity; import android.content.pm.PackageManager; import androidx.annotation.StringRes; import androidx.appcompat.app.AlertDialog; import org.lineageos.recorder.R; import java.util.ArrayList; import java.util.List; public final class PermissionManager { public static final int REQUEST_CODE = 440; private static final int[] PERMISSION_ERROR_MESSAGE_RES_IDS = { 0, R.string.dialog_permissions_mic, R.string.dialog_permissions_phone, R.string.dialog_permissions_mic_phone, }; private final Activity activity; public PermissionManager(Activity activity) { this.activity = activity; } public boolean requestEssentialPermissions() { final List<String> missingPermissions = new ArrayList<>(); if (!hasRecordAudioPermission()) { missingPermissions.add(Manifest.permission.RECORD_AUDIO); } if (!hasPhoneReadStatusPermission()) { missingPermissions.add(Manifest.permission.READ_PHONE_STATE); } if (missingPermissions.isEmpty()) { return false; } else { final String[] requestArray = missingPermissions.toArray(new String[0]); activity.requestPermissions(requestArray, REQUEST_CODE); return true; } } public void requestLocationPermission() { if (!hasLocationPermission()) { final String[] requestArray = {Manifest.permission.ACCESS_FINE_LOCATION}; activity.requestPermissions(requestArray, REQUEST_CODE); } } public boolean hasEssentialPermissions() { return hasRecordAudioPermission() && hasPhoneReadStatusPermission(); } public boolean hasRecordAudioPermission() { return activity.checkSelfPermission(Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED; } public boolean hasPhoneReadStatusPermission() { return activity.checkSelfPermission(Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED; } public boolean hasLocationPermission() { return activity.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED; } public void onEssentialPermissionsDenied() { if (activity.shouldShowRequestPermissionRationale(Manifest.permission.READ_PHONE_STATE) || activity.shouldShowRequestPermissionRationale(Manifest.permission.RECORD_AUDIO)) { // Explain the user why the denied permission is needed int error = 0; if (!hasRecordAudioPermission()) { error |= 1; } if (!hasPhoneReadStatusPermission()) { error |= 1 << 1; } showPermissionRationale(PERMISSION_ERROR_MESSAGE_RES_IDS[error], this::requestEssentialPermissions); } else { // User has denied all the required permissions "forever" showPermissionError(R.string.snack_permissions_no_permission); } } public void onLocationPermissionDenied() { if (activity.shouldShowRequestPermissionRationale( Manifest.permission.ACCESS_FINE_LOCATION)) { showPermissionRationale(R.string.dialog_permissions_location, this::requestLocationPermission); } else { showPermissionError(R.string.snack_permissions_no_permission_location); } } private void showPermissionRationale(@StringRes int messageRes, Runnable requestAgain) { new AlertDialog.Builder(activity) .setTitle(R.string.dialog_permissions_title) .setMessage(messageRes) .setPositiveButton(R.string.dialog_permissions_ask, (dialog, position) -> { dialog.dismiss(); requestAgain.run(); }) .setNegativeButton(R.string.dialog_permissions_dismiss, null) .show(); } private void showPermissionError(@StringRes int messageRes) { new AlertDialog.Builder(activity) .setTitle(R.string.dialog_permissions_title) .setMessage(messageRes) .setPositiveButton(R.string.dialog_permissions_dismiss, null) .show(); } } Loading
app/src/main/java/org/lineageos/recorder/DialogActivity.java +17 −47 Original line number Diff line number Diff line Loading @@ -15,8 +15,6 @@ */ package org.lineageos.recorder; import android.Manifest; import android.content.pm.PackageManager; import android.os.Bundle; import androidx.annotation.NonNull; Loading @@ -25,17 +23,19 @@ import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.SwitchCompat; import org.lineageos.recorder.utils.PermissionManager; import org.lineageos.recorder.utils.Utils; public class DialogActivity extends AppCompatActivity { private static final int REQUEST_LOCATION_PERMS = 214; private PermissionManager mPermissionManager; private SwitchCompat mLocationSwitch; @Override protected void onCreate(@Nullable Bundle savedInstance) { super.onCreate(savedInstance); mPermissionManager = new PermissionManager(this); setFinishOnTouchOutside(true); final AlertDialog dialog = new AlertDialog.Builder(this) Loading @@ -62,33 +62,15 @@ public class DialogActivity extends AppCompatActivity { public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] results) { super.onRequestPermissionsResult(requestCode, permissions, results); if (hasLocationPermission()) { toggleAfterPermissionRequest(requestCode); return; } if (shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION)) { new AlertDialog.Builder(this) .setTitle(R.string.dialog_permissions_title) .setMessage(getString(R.string.dialog_permissions_location)) .setPositiveButton(R.string.dialog_permissions_ask, (dialog, position) -> { dialog.dismiss(); askLocationPermission(); }) .setNegativeButton(R.string.dialog_permissions_dismiss, (dialog, position) -> mLocationSwitch.setChecked(false)) .show(); if (requestCode == PermissionManager.REQUEST_CODE) { if (mPermissionManager.hasLocationPermission()) { toggleAfterPermissionRequest(); } else { // User has denied all the required permissions "forever" new AlertDialog.Builder(this) .setTitle(R.string.dialog_permissions_title) .setMessage(R.string.snack_permissions_no_permission_location) .setPositiveButton(R.string.dialog_permissions_dismiss, null) .show(); mPermissionManager.onLocationPermissionDenied(); mLocationSwitch.setChecked(false); } } } @Override public void onBackPressed() { Loading @@ -105,7 +87,7 @@ public class DialogActivity extends AppCompatActivity { boolean isRecording) { final boolean tagWithLocation; if (Utils.getTagWithLocation(this)) { if (hasLocationPermission()) { if (mPermissionManager.hasLocationPermission()) { tagWithLocation = true; } else { // Permission revoked -> disabled feature Loading @@ -123,10 +105,10 @@ public class DialogActivity extends AppCompatActivity { } else { locationSwitch.setOnCheckedChangeListener((button, isChecked) -> { if (isChecked) { if (hasLocationPermission()) { if (mPermissionManager.hasLocationPermission()) { Utils.setTagWithLocation(this, true); } else { askLocationPermission(); mPermissionManager.requestLocationPermission(); } } else { Utils.setTagWithLocation(this, false); Loading @@ -148,20 +130,8 @@ public class DialogActivity extends AppCompatActivity { } } private boolean hasLocationPermission() { int result = checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION); return result == PackageManager.PERMISSION_GRANTED; } private void askLocationPermission() { requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_LOCATION_PERMS); } private void toggleAfterPermissionRequest(int requestCode) { if (requestCode == REQUEST_LOCATION_PERMS) { private void toggleAfterPermissionRequest() { mLocationSwitch.setChecked(true); Utils.setTagWithLocation(this, true); } } }
app/src/main/java/org/lineageos/recorder/RecorderActivity.java +15 −96 Original line number Diff line number Diff line Loading @@ -17,7 +17,6 @@ package org.lineageos.recorder; import static android.provider.MediaStore.Audio.Media.RECORD_SOUND_ACTION; import android.Manifest; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; Loading @@ -25,7 +24,6 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.ServiceConnection; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.net.Uri; import android.os.Bundle; import android.os.Handler; Loading @@ -52,21 +50,11 @@ import org.lineageos.recorder.ui.WaveFormView; import org.lineageos.recorder.utils.LastRecordHelper; import org.lineageos.recorder.utils.LocationHelper; import org.lineageos.recorder.utils.OnBoardingHelper; import org.lineageos.recorder.utils.PermissionManager; import org.lineageos.recorder.utils.Utils; import java.util.ArrayList; public class RecorderActivity extends AppCompatActivity implements SharedPreferences.OnSharedPreferenceChangeListener { private static final int REQUEST_SOUND_REC_PERMS = 440; private static final int[] PERMISSION_ERROR_MESSAGE_RES_IDS = { 0, R.string.dialog_permissions_mic, R.string.dialog_permissions_phone, R.string.dialog_permissions_mic_phone, }; private ServiceConnection mConnection; private SoundRecorderService mSoundService; private SharedPreferences mPrefs; Loading @@ -78,6 +66,7 @@ public class RecorderActivity extends AppCompatActivity implements private WaveFormView mRecordingVisualizer; private LocationHelper mLocationHelper; private PermissionManager mPermissionManager; private TaskExecutor mTaskExecutor; private boolean mReturnAudio; Loading Loading @@ -121,6 +110,7 @@ public class RecorderActivity extends AppCompatActivity implements mPrefs.registerOnSharedPreferenceChangeListener(this); mLocationHelper = new LocationHelper(this); mPermissionManager = new PermissionManager(this); mTaskExecutor = new TaskExecutor(); getLifecycle().addObserver(mTaskExecutor); Loading Loading @@ -170,42 +160,12 @@ public class RecorderActivity extends AppCompatActivity implements @NonNull int[] results) { super.onRequestPermissionsResult(requestCode, permissions, results); if (hasAllAudioRecorderPermissions()) { toggleAfterPermissionRequest(requestCode); return; } if (shouldShowRequestPermissionRationale(Manifest.permission.RECORD_AUDIO) || shouldShowRequestPermissionRationale(Manifest.permission.READ_PHONE_STATE)) { // Explain the user why the denied permission is needed int error = 0; if (!hasAudioPermission()) { error |= 1; } if (!hasPhoneReaderPermission()) { error |= 1 << 1; } String message = getString(PERMISSION_ERROR_MESSAGE_RES_IDS[error]); new AlertDialog.Builder(this) .setTitle(R.string.dialog_permissions_title) .setMessage(message) .setPositiveButton(R.string.dialog_permissions_ask, (dialog, position) -> { dialog.dismiss(); askPermissionsAgain(requestCode); }) .setNegativeButton(R.string.dialog_permissions_dismiss, null) .show(); if (requestCode == PermissionManager.REQUEST_CODE) { if (mPermissionManager.hasEssentialPermissions()) { toggleAfterPermissionRequest(); } else { // User has denied all the required permissions "forever" new AlertDialog.Builder(this) .setTitle(R.string.dialog_permissions_title) .setMessage(R.string.snack_permissions_no_permission) .setPositiveButton(R.string.dialog_permissions_dismiss, null) .show(); mPermissionManager.onEssentialPermissionsDenied(); } } } Loading @@ -221,21 +181,13 @@ public class RecorderActivity extends AppCompatActivity implements } private void toggleAfterPermissionRequest(int requestCode) { if (requestCode == REQUEST_SOUND_REC_PERMS) { private void toggleAfterPermissionRequest() { bindSoundRecService(); new Handler(Looper.getMainLooper()).postDelayed(this::toggleSoundRecorder, 500); } } private void askPermissionsAgain(int requestCode) { if (requestCode == REQUEST_SOUND_REC_PERMS) { checkSoundRecPermissions(); } } private void toggleSoundRecorder() { if (checkSoundRecPermissions()) { if (mPermissionManager.requestEssentialPermissions()) { return; } Loading Loading @@ -305,42 +257,9 @@ public class RecorderActivity extends AppCompatActivity implements } } private boolean hasAudioPermission() { int result = checkSelfPermission(Manifest.permission.RECORD_AUDIO); return result == PackageManager.PERMISSION_GRANTED; } private boolean hasPhoneReaderPermission() { int result = checkSelfPermission(Manifest.permission.READ_PHONE_STATE); return result == PackageManager.PERMISSION_GRANTED; } private boolean hasAllAudioRecorderPermissions() { return hasAudioPermission() && hasPhoneReaderPermission(); } private boolean checkSoundRecPermissions() { ArrayList<String> permissions = new ArrayList<>(); if (!hasAudioPermission()) { permissions.add(Manifest.permission.RECORD_AUDIO); } if (!hasPhoneReaderPermission()) { permissions.add(Manifest.permission.READ_PHONE_STATE); } if (permissions.isEmpty()) { return false; } String[] permissionArray = permissions.toArray(new String[0]); requestPermissions(permissionArray, REQUEST_SOUND_REC_PERMS); return true; } private void setupConnection() { checkSoundRecPermissions(); mPermissionManager.requestEssentialPermissions(); mConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder binder) { Loading @@ -356,7 +275,7 @@ public class RecorderActivity extends AppCompatActivity implements } private void bindSoundRecService() { if (mSoundService == null && hasAllAudioRecorderPermissions()) { if (mSoundService == null && mPermissionManager.hasEssentialPermissions()) { setupConnection(); bindService(new Intent(this, SoundRecorderService.class), mConnection, BIND_AUTO_CREATE); Loading
app/src/main/java/org/lineageos/recorder/utils/PermissionManager.java 0 → 100644 +142 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 The LineageOS Project * * 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 org.lineageos.recorder.utils; import android.Manifest; import android.app.Activity; import android.content.pm.PackageManager; import androidx.annotation.StringRes; import androidx.appcompat.app.AlertDialog; import org.lineageos.recorder.R; import java.util.ArrayList; import java.util.List; public final class PermissionManager { public static final int REQUEST_CODE = 440; private static final int[] PERMISSION_ERROR_MESSAGE_RES_IDS = { 0, R.string.dialog_permissions_mic, R.string.dialog_permissions_phone, R.string.dialog_permissions_mic_phone, }; private final Activity activity; public PermissionManager(Activity activity) { this.activity = activity; } public boolean requestEssentialPermissions() { final List<String> missingPermissions = new ArrayList<>(); if (!hasRecordAudioPermission()) { missingPermissions.add(Manifest.permission.RECORD_AUDIO); } if (!hasPhoneReadStatusPermission()) { missingPermissions.add(Manifest.permission.READ_PHONE_STATE); } if (missingPermissions.isEmpty()) { return false; } else { final String[] requestArray = missingPermissions.toArray(new String[0]); activity.requestPermissions(requestArray, REQUEST_CODE); return true; } } public void requestLocationPermission() { if (!hasLocationPermission()) { final String[] requestArray = {Manifest.permission.ACCESS_FINE_LOCATION}; activity.requestPermissions(requestArray, REQUEST_CODE); } } public boolean hasEssentialPermissions() { return hasRecordAudioPermission() && hasPhoneReadStatusPermission(); } public boolean hasRecordAudioPermission() { return activity.checkSelfPermission(Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED; } public boolean hasPhoneReadStatusPermission() { return activity.checkSelfPermission(Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED; } public boolean hasLocationPermission() { return activity.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED; } public void onEssentialPermissionsDenied() { if (activity.shouldShowRequestPermissionRationale(Manifest.permission.READ_PHONE_STATE) || activity.shouldShowRequestPermissionRationale(Manifest.permission.RECORD_AUDIO)) { // Explain the user why the denied permission is needed int error = 0; if (!hasRecordAudioPermission()) { error |= 1; } if (!hasPhoneReadStatusPermission()) { error |= 1 << 1; } showPermissionRationale(PERMISSION_ERROR_MESSAGE_RES_IDS[error], this::requestEssentialPermissions); } else { // User has denied all the required permissions "forever" showPermissionError(R.string.snack_permissions_no_permission); } } public void onLocationPermissionDenied() { if (activity.shouldShowRequestPermissionRationale( Manifest.permission.ACCESS_FINE_LOCATION)) { showPermissionRationale(R.string.dialog_permissions_location, this::requestLocationPermission); } else { showPermissionError(R.string.snack_permissions_no_permission_location); } } private void showPermissionRationale(@StringRes int messageRes, Runnable requestAgain) { new AlertDialog.Builder(activity) .setTitle(R.string.dialog_permissions_title) .setMessage(messageRes) .setPositiveButton(R.string.dialog_permissions_ask, (dialog, position) -> { dialog.dismiss(); requestAgain.run(); }) .setNegativeButton(R.string.dialog_permissions_dismiss, null) .show(); } private void showPermissionError(@StringRes int messageRes) { new AlertDialog.Builder(activity) .setTitle(R.string.dialog_permissions_title) .setMessage(messageRes) .setPositiveButton(R.string.dialog_permissions_dismiss, null) .show(); } }