Skip to content

Commit

Permalink
front: Fix permissions in marshmellow.
Browse files Browse the repository at this point in the history
  • Loading branch information
fzurita committed Jan 2, 2016
1 parent e86f3f5 commit 5a317b8
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 5 deletions.
4 changes: 4 additions & 0 deletions res/values/strings.xml
Expand Up @@ -428,6 +428,10 @@
<string name="assetExtractor_progress">%1$.0f%% done: %2$s</string> <string name="assetExtractor_progress">%1$.0f%% done: %2$s</string>
<string name="assetExtractor_finished">Finished</string> <string name="assetExtractor_finished">Finished</string>
<string name="assetExtractor_failed">Error extracting app data.\nPlease unplug USB cable, reboot device, and re-launch app.\nFor help, please visit %1$s.</string> <string name="assetExtractor_failed">Error extracting app data.\nPlease unplug USB cable, reboot device, and re-launch app.\nFor help, please visit %1$s.</string>
<string name="assetExtractor_error">Error</string>
<string name="assetExtractor_failed_permissions">This app cannot proceed without these permissions</string>
<string name="assetExtractor_permissions_title">Permissions</string>
<string name="assetExtractor_permissions_rationale">Mupen64Plus AE needs to be able to: \nRead your storage to read ROM files, save states, and configuration.\nWrite to your storage to write configuration and save data.</string>


<!-- Cheats Configuration --> <!-- Cheats Configuration -->
<string name="cheats_defaultName">Cheat %1$d</string> <string name="cheats_defaultName">Cheat %1$d</string>
Expand Down
146 changes: 141 additions & 5 deletions src/paulscode/android/mupen64plusae/SplashActivity.java
Expand Up @@ -37,10 +37,19 @@
import paulscode.android.mupen64plusae.util.Notifier; import paulscode.android.mupen64plusae.util.Notifier;
import paulscode.android.mupen64plusae.util.RomDatabase; import paulscode.android.mupen64plusae.util.RomDatabase;
import tv.ouya.console.api.OuyaFacade; import tv.ouya.console.api.OuyaFacade;
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.res.Resources; import android.content.res.Resources;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.ActivityCompat.OnRequestPermissionsResultCallback;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AppCompatActivity;
import android.support.v7.preference.PreferenceManager; import android.support.v7.preference.PreferenceManager;
import android.text.Html; import android.text.Html;
Expand All @@ -52,8 +61,14 @@
* The main activity that presents the splash screen, extracts the assets if necessary, and launches * The main activity that presents the splash screen, extracts the assets if necessary, and launches
* the main menu activity. * the main menu activity.
*/ */
public class SplashActivity extends AppCompatActivity implements ExtractAssetsListener public class SplashActivity extends AppCompatActivity implements ExtractAssetsListener, OnRequestPermissionsResultCallback
{ {
//Permission request ID
static final int PERMISSION_REQUEST = 177;

//Total number of permissions requested
static final int NUM_PERMISSIONS = 2;

/** /**
* Asset version number, used to determine stale assets. Increment this number every time the * Asset version number, used to determine stale assets. Increment this number every time the
* assets are updated on disk. * assets are updated on disk.
Expand Down Expand Up @@ -170,6 +185,119 @@ public void onCreate( Bundle savedInstanceState )
Popups.showInvalidInstall( this ); Popups.showInvalidInstall( this );
} }
} }

public void requestPermissions()
{
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
|| ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)
{

// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_EXTERNAL_STORAGE)
|| ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE))
{
//Show dialog asking for permissions
new AlertDialog.Builder(this)
.setTitle(getString(R.string.assetExtractor_permissions_title))
.setMessage(getString(R.string.assetExtractor_permissions_rationale))
.setPositiveButton(getString(android.R.string.ok), new OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
actuallyRequestPermissions();
}

}).setNegativeButton(getString(android.R.string.cancel), new OnClickListener()
{
//Show dialog stating that the app can't continue without proper permissions
@Override
public void onClick(DialogInterface dialog, int which)
{
new AlertDialog.Builder(SplashActivity.this).setTitle(getString(R.string.assetExtractor_error))
.setMessage(getString(R.string.assetExtractor_failed_permissions))
.setPositiveButton(getString( android.R.string.ok ), new OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
SplashActivity.this.finish();
}

}).setCancelable(false).show();
}
}).setCancelable(false).show();
}
else
{
// No explanation needed, we can request the permission.
actuallyRequestPermissions();
}
}
else
{
//Permissions already granted, continue
extractAssets();
}
}

@SuppressLint("InlinedApi")
public void actuallyRequestPermissions()
{
ActivityCompat.requestPermissions(this, new String[] {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE }, PERMISSION_REQUEST);
}

@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults)
{
switch (requestCode)
{
case PERMISSION_REQUEST:
{
// If request is cancelled, the result arrays are empty.
boolean good = true;
if (permissions.length != NUM_PERMISSIONS || grantResults.length != NUM_PERMISSIONS)
{
good = false;
}

for (int i = 0; i < grantResults.length && good; i++)
{
if (grantResults[i] != PackageManager.PERMISSION_GRANTED)
{
good = false;
}
}

if (!good)
{
// permission denied, boo! Disable the app.
new AlertDialog.Builder(SplashActivity.this).setTitle(getString(R.string.assetExtractor_error))
.setMessage(getString(R.string.assetExtractor_failed_permissions))
.setPositiveButton(getString( android.R.string.ok ), new OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
SplashActivity.this.finish();
}

}).setCancelable(false).show();
}
else
{
//Permissions already granted, continue
extractAssets();
}
return;
}

// other 'case' lines to check for other
// permissions this app might request
}
}


/** Runnable that launches the non-UI thread from the UI thread after the activity has resumed. */ /** Runnable that launches the non-UI thread from the UI thread after the activity has resumed. */
private final Runnable extractAssetsTaskLauncher = new Runnable() private final Runnable extractAssetsTaskLauncher = new Runnable()
Expand All @@ -179,10 +307,7 @@ public void run()
{ {
if( mAppData.getAssetVersion() != ASSET_VERSION ) if( mAppData.getAssetVersion() != ASSET_VERSION )
{ {
// Extract and merge the assets if they are out of date requestPermissions();
FileUtil.deleteFolder( new File( mAppData.coreSharedDataDir ) );
mAssetsExtracted = 0;
new ExtractAssetsTask( getAssets(), SOURCE_DIR, mAppData.coreSharedDataDir, SplashActivity.this ).execute();
} }
else else
{ {
Expand All @@ -195,6 +320,17 @@ public void run()
} }
}; };


/**
* Extract assets
*/
private void extractAssets()
{
// Extract and merge the assets if they are out of date
FileUtil.deleteFolder( new File( mAppData.coreSharedDataDir ) );
mAssetsExtracted = 0;
new ExtractAssetsTask( getAssets(), SOURCE_DIR, mAppData.coreSharedDataDir, SplashActivity.this ).execute();
}

@Override @Override
public void onExtractAssetsProgress( String nextFileToExtract ) public void onExtractAssetsProgress( String nextFileToExtract )
{ {
Expand Down
6 changes: 6 additions & 0 deletions src/paulscode/android/mupen64plusae/persistent/AppData.java
Expand Up @@ -91,6 +91,12 @@ public class AppData
/** True if device is running Lollipop or later (21 - Android 5.0.x) */ /** True if device is running Lollipop or later (21 - Android 5.0.x) */
public static final boolean IS_LOLLIPOP = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP; public static final boolean IS_LOLLIPOP = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;


/** True if device is running Lollipop MR1 or later (22 - Android 5.1.x) */
public static final boolean IS_LOLLIPOP_MR1 = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1;

/** True if device is running marshmallow or later (23 - Android 6.0.x) */
public static final boolean IS_MARSHMELLOW = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M;

/** True if device is an OUYA. */ /** True if device is an OUYA. */
public static final boolean IS_OUYA_HARDWARE = OuyaFacade.getInstance().isRunningOnOUYAHardware(); public static final boolean IS_OUYA_HARDWARE = OuyaFacade.getInstance().isRunningOnOUYAHardware();


Expand Down

0 comments on commit 5a317b8

Please sign in to comment.