mirror of
https://github.com/CTCaer/RetroArch.git
synced 2025-01-12 05:40:36 +00:00
Merge pull request #4770 from bparker06/permissions
android: add runtime permission checking for Android 6.0+
This commit is contained in:
commit
f79630e778
@ -1463,6 +1463,10 @@ static void frontend_linux_get_env(int *argc,
|
||||
strlcpy(app_dir, argv, sizeof(app_dir));
|
||||
(*env)->ReleaseStringUTFChars(env, jstr, argv);
|
||||
|
||||
/* Check for runtime permissions on Android 6.0+ */
|
||||
if (env && android_app->checkRuntimePermissions)
|
||||
CALL_VOID_METHOD(env, android_app->activity->clazz, android_app->checkRuntimePermissions);
|
||||
|
||||
//set paths depending on the ability to write to internal_storage_path
|
||||
|
||||
if(!string_is_empty(internal_storage_path))
|
||||
@ -1867,6 +1871,8 @@ static void frontend_linux_init(void *data)
|
||||
"onRetroArchExit", "()V");
|
||||
GET_METHOD_ID(env, android_app->isAndroidTV, class,
|
||||
"isAndroidTV", "()Z");
|
||||
GET_METHOD_ID(env, android_app->checkRuntimePermissions, class,
|
||||
"checkRuntimePermissions", "()V");
|
||||
CALL_OBJ_METHOD(env, obj, android_app->activity->clazz,
|
||||
android_app->getIntent);
|
||||
|
||||
|
@ -161,6 +161,7 @@ struct android_app
|
||||
jmethodID getPendingIntentDownloadsLocation;
|
||||
jmethodID getPendingIntentScreenshotsLocation;
|
||||
jmethodID isAndroidTV;
|
||||
jmethodID checkRuntimePermissions;
|
||||
};
|
||||
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
<uses-feature android:name="android.hardware.gamepad" android:required="false"/>
|
||||
<uses-sdk
|
||||
android:minSdkVersion="9"
|
||||
android:targetSdkVersion="21" />
|
||||
android:targetSdkVersion="23" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
|
@ -11,5 +11,5 @@
|
||||
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
|
||||
|
||||
# Project target.
|
||||
target=android-22
|
||||
target=android-23
|
||||
android.library.reference.1=libs/googleplay
|
||||
|
@ -1,15 +1,23 @@
|
||||
package com.retroarch.browser.retroactivity;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import com.retroarch.browser.preferences.util.UserPreferences;
|
||||
import android.content.res.Configuration;
|
||||
import android.app.UiModeManager;
|
||||
import android.util.Log;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.Manifest;
|
||||
import android.content.DialogInterface;
|
||||
import android.app.AlertDialog;
|
||||
|
||||
/**
|
||||
* Class which provides common methods for RetroActivity related classes.
|
||||
*/
|
||||
public class RetroActivityCommon extends RetroActivityLocation
|
||||
{
|
||||
final private int REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS = 124;
|
||||
|
||||
// Exiting cleanly from NDK seems to be nearly impossible.
|
||||
// Have to use exit(0) to avoid weird things happening, even with runOnUiThread() approaches.
|
||||
// Use a separate JNI function to explicitly trigger the readback.
|
||||
@ -18,6 +26,103 @@ public class RetroActivityCommon extends RetroActivityLocation
|
||||
finish();
|
||||
}
|
||||
|
||||
public void showMessageOKCancel(String message, DialogInterface.OnClickListener onClickListener)
|
||||
{
|
||||
new AlertDialog.Builder(this).setMessage(message)
|
||||
.setPositiveButton("OK", onClickListener).setCancelable(false)
|
||||
.setNegativeButton("Cancel", null).create().show();
|
||||
}
|
||||
|
||||
private boolean addPermission(List<String> permissionsList, String permission)
|
||||
{
|
||||
if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED)
|
||||
{
|
||||
permissionsList.add(permission);
|
||||
|
||||
// Check for Rationale Option
|
||||
if (!shouldShowRequestPermissionRationale(permission))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void checkRuntimePermissions()
|
||||
{
|
||||
runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
checkRuntimePermissionsRunnable();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void checkRuntimePermissionsRunnable()
|
||||
{
|
||||
if (android.os.Build.VERSION.SDK_INT >= 23)
|
||||
{
|
||||
// Android 6.0+ needs runtime permission checks
|
||||
List<String> permissionsNeeded = new ArrayList<String>();
|
||||
final List<String> permissionsList = new ArrayList<String>();
|
||||
|
||||
if (!addPermission(permissionsList, Manifest.permission.READ_EXTERNAL_STORAGE))
|
||||
permissionsNeeded.add("Read External Storage");
|
||||
if (!addPermission(permissionsList, Manifest.permission.WRITE_EXTERNAL_STORAGE))
|
||||
permissionsNeeded.add("Write External Storage");
|
||||
|
||||
if (permissionsList.size() > 0)
|
||||
{
|
||||
if (permissionsNeeded.size() > 0)
|
||||
{
|
||||
// Need Rationale
|
||||
Log.i("RetroActivity", "Need to request external storage permissions.");
|
||||
|
||||
String message = "You need to grant access to " + permissionsNeeded.get(0);
|
||||
|
||||
for (int i = 1; i < permissionsNeeded.size(); i++)
|
||||
message = message + ", " + permissionsNeeded.get(i);
|
||||
|
||||
showMessageOKCancel(message,
|
||||
new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
|
||||
REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
|
||||
|
||||
Log.i("RetroActivity", "User accepted request for external storage permissions.");
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
|
||||
REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
|
||||
|
||||
Log.i("RetroActivity", "Requested external storage permissions.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)
|
||||
{
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
|
||||
for (int i = 0; i < permissions.length; i++)
|
||||
{
|
||||
if(grantResults[i] == PackageManager.PERMISSION_GRANTED)
|
||||
{
|
||||
Log.i("RetroActivity", "Permission: " + permissions[i] + " was granted.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.i("RetroActivity", "Permission: " + permissions[i] + " was not granted.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isAndroidTV()
|
||||
{
|
||||
Configuration config = getResources().getConfiguration();
|
||||
|
Loading…
x
Reference in New Issue
Block a user