diff --git a/app/jni/i2pd b/app/jni/i2pd index 321c7cb..e59ca84 160000 --- a/app/jni/i2pd +++ b/app/jni/i2pd @@ -1 +1 @@ -Subproject commit 321c7cb7cf5a8d879c2b38b28a49b74edb27d2e5 +Subproject commit e59ca8420eab18f1e536e951c50004e5bb55e86e diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index deb1e75..03d5ee7 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -3,10 +3,11 @@ package="org.purplei2p.i2pd" android:installLocation="auto"> - + + + - diff --git a/app/src/main/java/org/purplei2p/i2pd/I2PDActivity.java b/app/src/main/java/org/purplei2p/i2pd/I2PDActivity.java index 5a64545..0c0ecc7 100644 --- a/app/src/main/java/org/purplei2p/i2pd/I2PDActivity.java +++ b/app/src/main/java/org/purplei2p/i2pd/I2PDActivity.java @@ -20,6 +20,7 @@ import android.net.ConnectivityManager; import android.net.Uri; import android.os.Bundle; import android.os.Build; +import android.os.Environment; import android.os.IBinder; import android.os.PowerManager; import android.preference.PreferenceManager; @@ -126,11 +127,17 @@ public class I2PDActivity extends Activity { daemon.addStateChangeListener(daemonStateUpdatedListener); daemonStateUpdatedListener.daemonStateUpdate(DaemonWrapper.State.uninitialized, daemon.getState()); + // request permissions - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + if(!Environment.isExternalStorageManager()) { + Log.e(TAG, "MANAGE_EXTERNAL_STORAGE perm declined, stopping i2pd"); + i2pdStop(); + } + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, - new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, + new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE }, MY_PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE); } } diff --git a/app/src/main/java/org/purplei2p/i2pd/I2PDPermsAskerActivity.java b/app/src/main/java/org/purplei2p/i2pd/I2PDPermsAskerActivity.java index b178e10..dfc32ff 100644 --- a/app/src/main/java/org/purplei2p/i2pd/I2PDPermsAskerActivity.java +++ b/app/src/main/java/org/purplei2p/i2pd/I2PDPermsAskerActivity.java @@ -4,7 +4,11 @@ import android.Manifest; import android.app.Activity; import android.content.Intent; import android.content.pm.PackageManager; +import android.net.Uri; +import android.os.Build; import android.os.Bundle; +import android.os.Environment; +import android.provider.Settings; import android.view.View; import android.widget.Button; import android.widget.TextView; @@ -16,6 +20,7 @@ import java.lang.reflect.Method; public class I2PDPermsAskerActivity extends Activity { private static final int PERMISSION_WRITE_EXTERNAL_STORAGE = 0; + private static final int PERMISSION_MANAGE_EXTERNAL_STORAGE = 0; private Button button_request_write_ext_storage_perms; private TextView textview_retry; @@ -48,57 +53,66 @@ public class I2PDPermsAskerActivity extends Activity { textview_retry.setVisibility(TextView.GONE); button_request_write_ext_storage_perms.setVisibility(Button.GONE); - Method methodCheckPermission; - Method method_shouldShowRequestPermissionRationale; - Method method_requestPermissions; - try { - methodCheckPermission = getClass().getMethod("checkSelfPermission", String.class); - method_shouldShowRequestPermissionRationale = - getClass().getMethod("shouldShowRequestPermissionRationale", String.class); - method_requestPermissions = - getClass().getMethod("requestPermissions", String[].class, int.class); - } catch (NoSuchMethodException e) { - throw new RuntimeException(e); - } - Integer resultObj; - try { - resultObj = (Integer) methodCheckPermission.invoke( - this, Manifest.permission.WRITE_EXTERNAL_STORAGE); - } catch (Throwable e) { - throw new RuntimeException(e); - } - - if (resultObj != PackageManager.PERMISSION_GRANTED) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if(!Environment.isExternalStorageManager()) { + showExplanation(); + } else { + startMainActivity(); + } + } else { + Method methodCheckPermission; + Method method_shouldShowRequestPermissionRationale; + Method method_requestPermissions; - // Should we show an explanation? - Boolean aBoolean; try { - aBoolean = (Boolean) method_shouldShowRequestPermissionRationale.invoke(this, - Manifest.permission.WRITE_EXTERNAL_STORAGE); - } catch (Exception e) { + methodCheckPermission = getClass().getMethod("checkSelfPermission", String.class); + method_shouldShowRequestPermissionRationale = + getClass().getMethod("shouldShowRequestPermissionRationale", String.class); + method_requestPermissions = + getClass().getMethod("requestPermissions", String[].class, int.class); + } catch (NoSuchMethodException e) { throw new RuntimeException(e); } - if (aBoolean) { - - // Show an explanation to the user *asynchronously* -- don't block - // this thread waiting for the user's response! After the user - // sees the explanation, try again to request the permission. - showExplanation(); - - } else { + Integer resultObj; - // No explanation needed, we can request the permission. + try { + resultObj = (Integer) methodCheckPermission.invoke( + this, Manifest.permission.WRITE_EXTERNAL_STORAGE); + } catch (Throwable e) { + throw new RuntimeException(e); + } + if (resultObj != PackageManager.PERMISSION_GRANTED) { + // Should we show an explanation? + Boolean aBoolean; try { - method_requestPermissions.invoke(this, - new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, - PERMISSION_WRITE_EXTERNAL_STORAGE); + aBoolean = (Boolean) method_shouldShowRequestPermissionRationale.invoke(this, + Manifest.permission.WRITE_EXTERNAL_STORAGE); } catch (Exception e) { throw new RuntimeException(e); } - } - } else startMainActivity(); + + if (aBoolean) { + + // Show an explanation to the user *asynchronously* -- don't block + // this thread waiting for the user's response! After the user + // sees the explanation, try again to request the permission. + + showExplanation(); + + } else { + // No explanation needed, we can request the permission. + try { + method_requestPermissions.invoke(this, + new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, + PERMISSION_WRITE_EXTERNAL_STORAGE); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } else startMainActivity(); + } } @Override @@ -136,6 +150,7 @@ public class I2PDPermsAskerActivity extends Activity { } private static final int SHOW_EXPLANATION_REQUEST = 1; // The request code + private static final int APP_STORAGE_ACCESS_REQUEST_CODE = 2; private void showExplanation() { Intent intent = new Intent(this, I2PDPermsExplanationActivity.class); @@ -144,11 +159,14 @@ public class I2PDPermsAskerActivity extends Activity { @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { - // Check which request we're responding to - if (requestCode == SHOW_EXPLANATION_REQUEST) { - // Make sure the request was successful - if (resultCode == RESULT_OK) { - // Request the permission + super.onActivityResult(requestCode, resultCode, data); + // Check which request we're responding to and make sure the request was successful + if (requestCode == SHOW_EXPLANATION_REQUEST && resultCode == RESULT_OK) { + // Request the permission + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + Intent intentManageAccess = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION, Uri.parse("package:" + BuildConfig.APPLICATION_ID)); + startActivityForResult(intentManageAccess, APP_STORAGE_ACCESS_REQUEST_CODE); + } else { Method method_requestPermissions; try { method_requestPermissions = @@ -163,9 +181,19 @@ public class I2PDPermsAskerActivity extends Activity { } catch (Exception e) { throw new RuntimeException(e); } + } + } else if (requestCode == APP_STORAGE_ACCESS_REQUEST_CODE && resultCode == RESULT_OK) { + if (Environment.isExternalStorageManager()) { + startMainActivity(); } else { - finish(); //close the app + textview_retry.setText(R.string.permDenied); + textview_retry.setVisibility(TextView.VISIBLE); + button_request_write_ext_storage_perms.setVisibility(Button.VISIBLE); + + finish(); } + } else { + finish(); // close the app } } }