mirror of
https://github.com/mauiaaron/apple2.git
synced 2025-01-14 03:30:53 +00:00
Request and handle external storage permissions on Marshmallow
- Also disentangles exposing APK assets internally and on external storage
This commit is contained in:
parent
ac78e00afa
commit
6cef33b501
@ -11,10 +11,12 @@
|
|||||||
|
|
||||||
package org.deadc0de.apple2ix;
|
package org.deadc0de.apple2ix;
|
||||||
|
|
||||||
|
import android.Manifest;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
@ -92,6 +94,8 @@ public class Apple2Activity extends Activity {
|
|||||||
public final static long NATIVE_TOUCH_ASCII_MASK = 0xFF00L;
|
public final static long NATIVE_TOUCH_ASCII_MASK = 0xFF00L;
|
||||||
public final static long NATIVE_TOUCH_SCANCODE_MASK = 0x00FFL;
|
public final static long NATIVE_TOUCH_SCANCODE_MASK = 0x00FFL;
|
||||||
|
|
||||||
|
public final static int REQUEST_PERMISSION_RWSTORE = 42;
|
||||||
|
|
||||||
private native void nativeOnCreate(String dataDir, int sampleRate, int monoBufferSize, int stereoBufferSize);
|
private native void nativeOnCreate(String dataDir, int sampleRate, int monoBufferSize, int stereoBufferSize);
|
||||||
|
|
||||||
private native void nativeOnKeyDown(int keyCode, int metaState);
|
private native void nativeOnKeyDown(int keyCode, int metaState);
|
||||||
@ -166,6 +170,27 @@ public class Apple2Activity extends Activity {
|
|||||||
showSplashScreen(!firstTime);
|
showSplashScreen(!firstTime);
|
||||||
Apple2CrashHandler.getInstance().checkForCrashes(this);
|
Apple2CrashHandler.getInstance().checkForCrashes(this);
|
||||||
|
|
||||||
|
boolean extperm = true;
|
||||||
|
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||||
|
// On Marshmallow+ specifically ask for permission to read/write storage
|
||||||
|
String readPermission = Manifest.permission.READ_EXTERNAL_STORAGE;
|
||||||
|
String writePermission = Manifest.permission.WRITE_EXTERNAL_STORAGE;
|
||||||
|
int hasReadPermission = checkSelfPermission(readPermission);
|
||||||
|
int hasWritePermission = checkSelfPermission(writePermission);
|
||||||
|
ArrayList<String> permissions = new ArrayList<String>();
|
||||||
|
if (hasReadPermission != PackageManager.PERMISSION_GRANTED) {
|
||||||
|
permissions.add(readPermission);
|
||||||
|
}
|
||||||
|
if (hasWritePermission != PackageManager.PERMISSION_GRANTED) {
|
||||||
|
permissions.add(writePermission);
|
||||||
|
}
|
||||||
|
if (!permissions.isEmpty()) {
|
||||||
|
extperm = false;
|
||||||
|
String[] params = permissions.toArray(new String[permissions.size()]);
|
||||||
|
requestPermissions(params, REQUEST_PERMISSION_RWSTORE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mGraphicsInitializedRunnable = new Runnable() {
|
mGraphicsInitializedRunnable = new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
@ -177,11 +202,15 @@ public class Apple2Activity extends Activity {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// first-time initializations
|
// first-time initializations
|
||||||
|
final boolean externalStoragePermission = extperm;
|
||||||
if (firstTime) {
|
if (firstTime) {
|
||||||
new Thread(new Runnable() {
|
new Thread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
Apple2DisksMenu.firstTime(Apple2Activity.this);
|
Apple2DisksMenu.exposeAPKAssets(Apple2Activity.this);
|
||||||
|
if (externalStoragePermission) {
|
||||||
|
Apple2DisksMenu.exposeAPKAssetsToExternal(Apple2Activity.this);
|
||||||
|
}
|
||||||
mSplashScreen.setDismissable(true);
|
mSplashScreen.setDismissable(true);
|
||||||
Log.d(TAG, "Finished first time copying...");
|
Log.d(TAG, "Finished first time copying...");
|
||||||
}
|
}
|
||||||
@ -204,6 +233,26 @@ public class Apple2Activity extends Activity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
|
||||||
|
// We should already be gracefully handling the case where user denies access.
|
||||||
|
if (requestCode == REQUEST_PERMISSION_RWSTORE) {
|
||||||
|
boolean grantedPermissions = true;
|
||||||
|
for (int grant : grantResults) {
|
||||||
|
if (grant == PackageManager.PERMISSION_DENIED) {
|
||||||
|
grantedPermissions = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (grantedPermissions) {
|
||||||
|
// this will force copying APK files (now that we have permission
|
||||||
|
Apple2DisksMenu.exposeAPKAssetsToExternal(Apple2Activity.this);
|
||||||
|
} // else ... we keep nagging on app startup ...
|
||||||
|
} else {
|
||||||
|
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onResume() {
|
protected void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
|
@ -135,7 +135,7 @@ public class Apple2DisksMenu implements Apple2MenuView {
|
|||||||
return sDataDir;
|
return sDataDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void firstTime(Apple2Activity activity) {
|
public static void exposeAPKAssetsToExternal(Apple2Activity activity) {
|
||||||
final ProgressBar bar = (ProgressBar) activity.findViewById(R.id.crash_progressBar);
|
final ProgressBar bar = (ProgressBar) activity.findViewById(R.id.crash_progressBar);
|
||||||
activity.runOnUiThread(new Runnable() {
|
activity.runOnUiThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
@ -144,7 +144,38 @@ public class Apple2DisksMenu implements Apple2MenuView {
|
|||||||
bar.setVisibility(View.VISIBLE);
|
bar.setVisibility(View.VISIBLE);
|
||||||
bar.setIndeterminate(true);
|
bar.setIndeterminate(true);
|
||||||
} catch (NullPointerException npe) {
|
} catch (NullPointerException npe) {
|
||||||
Log.v(TAG, "Whoa, avoided NPE in first time #1");
|
Log.v(TAG, "Avoid NPE in exposeAPKAssetsToExternal #1");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
getExternalStorageDirectory(activity);
|
||||||
|
Log.v(TAG, "Overwriting system files in /sdcard/apple2ix/ (external storage) ...");
|
||||||
|
recursivelyCopyAPKAssets(activity, /*from APK directory:*/"keyboards", /*to location:*/sExternalFilesDir.getAbsolutePath());
|
||||||
|
|
||||||
|
activity.runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
bar.setVisibility(View.INVISIBLE);
|
||||||
|
bar.setIndeterminate(false);
|
||||||
|
} catch (NullPointerException npe) {
|
||||||
|
Log.v(TAG, "Avoid NPE in exposeAPKAssetsToExternal #2");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void exposeAPKAssets(Apple2Activity activity) {
|
||||||
|
final ProgressBar bar = (ProgressBar) activity.findViewById(R.id.crash_progressBar);
|
||||||
|
activity.runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
bar.setVisibility(View.VISIBLE);
|
||||||
|
bar.setIndeterminate(true);
|
||||||
|
} catch (NullPointerException npe) {
|
||||||
|
Log.v(TAG, "Avoid NPE in exposeAPKAssets #1");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -154,16 +185,10 @@ public class Apple2DisksMenu implements Apple2MenuView {
|
|||||||
Log.d(TAG, "First time copying stuff-n-things out of APK for ease-of-NDK access...");
|
Log.d(TAG, "First time copying stuff-n-things out of APK for ease-of-NDK access...");
|
||||||
|
|
||||||
getExternalStorageDirectory(activity);
|
getExternalStorageDirectory(activity);
|
||||||
|
|
||||||
recursivelyCopyAPKAssets(activity, /*from APK directory:*/"disks", /*to location:*/new File(sDataDir, "disks").getAbsolutePath());
|
recursivelyCopyAPKAssets(activity, /*from APK directory:*/"disks", /*to location:*/new File(sDataDir, "disks").getAbsolutePath());
|
||||||
recursivelyCopyAPKAssets(activity, /*from APK directory:*/"keyboards", /*to location:*/new File(sDataDir, "keyboards").getAbsolutePath());
|
recursivelyCopyAPKAssets(activity, /*from APK directory:*/"keyboards", /*to location:*/new File(sDataDir, "keyboards").getAbsolutePath());
|
||||||
recursivelyCopyAPKAssets(activity, /*from APK directory:*/"shaders", /*to location:*/new File(sDataDir, "shaders").getAbsolutePath());
|
recursivelyCopyAPKAssets(activity, /*from APK directory:*/"shaders", /*to location:*/new File(sDataDir, "shaders").getAbsolutePath());
|
||||||
|
|
||||||
// expose keyboards to modding
|
|
||||||
if (sExternalFilesDir != null) {
|
|
||||||
recursivelyCopyAPKAssets(activity, /*from APK directory:*/"keyboards", /*to location:*/sExternalFilesDir.getAbsolutePath());
|
|
||||||
}
|
|
||||||
|
|
||||||
activity.runOnUiThread(new Runnable() {
|
activity.runOnUiThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
@ -171,7 +196,7 @@ public class Apple2DisksMenu implements Apple2MenuView {
|
|||||||
bar.setVisibility(View.INVISIBLE);
|
bar.setVisibility(View.INVISIBLE);
|
||||||
bar.setIndeterminate(false);
|
bar.setIndeterminate(false);
|
||||||
} catch (NullPointerException npe) {
|
} catch (NullPointerException npe) {
|
||||||
Log.v(TAG, "Whoa, avoided NPE in first time #2");
|
Log.v(TAG, "Avoid NPE in exposeAPKAssets #1");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user