Java tutorial
/**************************************************************************** * * * Project64 - A Nintendo 64 emulator. * * http://www.pj64-emu.com/ * * Copyright (C) 2012 Project64. All rights reserved. * * * * License: * * GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * * * ****************************************************************************/ package emu.project64; import java.io.File; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Locale; import java.util.Timer; import java.util.TimerTask; import emu.project64.R; import emu.project64.dialog.ProgressDialog; import emu.project64.game.GameActivity; import emu.project64.game.GameActivityXperiaPlay; import emu.project64.inAppPurchase.IabBroadcastReceiver; import emu.project64.inAppPurchase.IabBroadcastReceiver.IabBroadcastListener; import emu.project64.inAppPurchase.IabHelper; import emu.project64.inAppPurchase.IabHelper.IabAsyncInProgressException; import emu.project64.inAppPurchase.IabResult; import emu.project64.inAppPurchase.Inventory; import emu.project64.inAppPurchase.Purchase; import emu.project64.jni.LanguageStringID; import emu.project64.jni.NativeExports; import emu.project64.jni.SettingsID; import emu.project64.jni.SystemEvent; import emu.project64.jni.UISettingID; import emu.project64.settings.GameSettingsActivity; import emu.project64.settings.SettingsActivity; import emu.project64.util.Strings; import emu.project64.util.Utility; import android.annotation.TargetApi; import android.app.Activity; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnCancelListener; import android.content.Intent; import android.content.IntentFilter; import android.content.res.Configuration; import android.graphics.Color; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.support.v4.content.res.ResourcesCompat; import android.support.v4.view.GravityCompat; import android.support.v4.widget.DrawerLayout; import android.support.v7.app.ActionBarDrawerToggle; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.Toolbar; import android.util.DisplayMetrics; import android.util.Log; import android.view.KeyEvent; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.webkit.WebView; import android.widget.ArrayAdapter; import android.widget.ListAdapter; import android.widget.TextView; public class GalleryActivity extends AppCompatActivity implements IabBroadcastListener { //Progress dialog for ROM scan private ProgressDialog mProgress = null; // Widgets private RecyclerView mGridView; private DrawerLayout mDrawerLayout; private ActionBarDrawerToggle mDrawerToggle; private MenuListView mDrawerList; // Resizable gallery thumb nails public int galleryWidth; public int galleryMaxWidth; public int galleryHalfSpacing; public int galleryColumns = 2; // Misc. private static List<GalleryItem> mGalleryItems = new ArrayList<GalleryItem>(); private static List<GalleryItem> mRecentItems = new ArrayList<GalleryItem>(); private static GalleryActivity mActiveGalleryActivity = null; // The IAB helper object IabHelper mIabHelper; private boolean mHasSaveSupport = false; private boolean mPj64Supporter = false; // Provides purchase notification while this app is running IabBroadcastReceiver mBroadcastReceiver; public static final int GAME_DIR_REQUEST_CODE = 1; static final String SKU_SAVESUPPORT = "save_support"; static final String SKU_PJ64SUPPORTOR_2 = "supportproject64_2"; static final String SKU_PJ64SUPPORTOR_5 = "supportproject64_5"; static final String SKU_PJ64SUPPORTOR_8 = "supportproject64_8"; static final String SKU_PJ64SUPPORTOR_10 = "supportproject64_10"; // (arbitrary) request code for the purchase flow static final int RC_REQUEST = 10001; static final int RC_SETTINGS = 10002; @Override protected void onNewIntent(Intent intent) { // If the activity is already running and is launched again (e.g. from a file manager app), // the existing instance will be reused rather than a new one created. This behavior is // specified in the manifest (launchMode = singleTask). In that situation, any activities // above this on the stack (e.g. GameActivity, GamePrefsActivity) will be destroyed // gracefully and onNewIntent() will be called on this instance. onCreate() will NOT be // called again on this instance. Currently, the only info that may be passed via the intent // is the selected game path, so we only need to refresh that aspect of the UI. This will // happen anyhow in onResume(), so we don't really need to do much here. super.onNewIntent(intent); // Only remember the last intent used setIntent(intent); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mActiveGalleryActivity = this; String FirstRun = NativeExports.UISettingsLoadString(UISettingID.SupportWindow_FirstRun.getValue()); if (FirstRun.length() == 0) { SimpleDateFormat format = new SimpleDateFormat("MMMM d, yyyy", Locale.ENGLISH); NativeExports.UISettingsSaveString(UISettingID.SupportWindow_FirstRun.getValue(), format.format(new Date())); } mIabHelper = new IabHelper(this, "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnfHFIq+X0oIvV+bwcvdqQv5GmpWLL6Bw8xE6MLFzXzUGUIUZBwQS6Cz5IC0UM76ujPDPqQPeGy/8oq/bswB5pHCz2iS4ySGalzFfYfeIDklOe+R1pLEqmHuwsR5o4b8rLePLGmUI7hA0kozOTb0i+epANV3Pj63i5XFZLA7RMi5I+YysoE9Fob6kCx0kb02AATacF0OXI9paE1izvsHhZcOIrT4TRMbGlZjBVE/pcJtoBDh33QKz/JBOXWvwnh+efqhVsq/UfA6jYI+U4Z4tsnWhem8DB6Kqj5EhClC6qCPmkBFiOabyKaqhI/urBtYOwxkW9erwtA6OcDoHm5J/JwIDAQAB"); // enable debug logging (for a production application, you should set this to false). mIabHelper.enableDebugLogging(true); Log.d("GalleryActivity", "Starting setup."); mIabHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() { public void onIabSetupFinished(IabResult result) { Log.d("GalleryActivity", "onIabSetupFinished."); if (!result.isSuccess()) { // Oh noes, there was a problem. Log.d("GalleryActivity", "Problem setting up in-app billing: " + result); // complain("Problem setting up in-app billing: " + result); mHasSaveSupport = true; mPj64Supporter = true; return; } // Have we been disposed of in the meantime? If so, quit. if (mIabHelper == null) return; // Important: Dynamically register for broadcast messages about updated purchases. // We register the receiver here instead of as a <receiver> in the Manifest // because we always call getPurchases() at startup, so therefore we can ignore // any broadcasts sent while the app isn't running. // Note: registering this listener in an Activity is a bad idea, but is done here // because this is a SAMPLE. Regardless, the receiver must be registered after // IabHelper is setup, but before first call to getPurchases(). mBroadcastReceiver = new IabBroadcastReceiver(GalleryActivity.this); IntentFilter broadcastFilter = new IntentFilter(IabBroadcastReceiver.ACTION); registerReceiver(mBroadcastReceiver, broadcastFilter); // IAB is fully set up. Now, let's get an inventory of stuff we own. Log.d("GalleryActivity", "Setup successful. Querying inventory."); try { mIabHelper.queryInventoryAsync(mGotInventoryListener); } catch (IabAsyncInProgressException e) { //complain("Error querying inventory. Another async operation in progress."); } } }); // Lay out the content setContentView(R.layout.gallery_activity); mGridView = (RecyclerView) findViewById(R.id.gridview); mProgress = new ProgressDialog(null, this, getString(R.string.scanning_title), "", getString(R.string.toast_pleaseWait), false); // Load Cached Rom List NativeExports.LoadRomList(); refreshGrid(); // Update the grid layout galleryMaxWidth = (int) getResources().getDimension(R.dimen.galleryImageWidth); galleryHalfSpacing = (int) getResources().getDimension(R.dimen.galleryHalfSpacing); DisplayMetrics metrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(metrics); int width = metrics.widthPixels - galleryHalfSpacing * 2; galleryColumns = (int) Math.ceil(width * 1.0 / (galleryMaxWidth + galleryHalfSpacing * 2)); galleryWidth = width / galleryColumns - galleryHalfSpacing * 2; GridLayoutManager layoutManager = (GridLayoutManager) mGridView.getLayoutManager(); layoutManager.setSpanCount(galleryColumns); // Add the toolbar to the activity (which supports the fancy menu/arrow animation) Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); toolbar.setTitle(R.string.app_name); setSupportActionBar(toolbar); // Configure the navigation drawer mDrawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout); mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, toolbar, 0, 0); mDrawerLayout.addDrawerListener(mDrawerToggle); // Configure the list in the navigation drawer mDrawerList = (MenuListView) findViewById(R.id.drawerNavigation); mDrawerList.setMenuResource(R.menu.gallery_drawer); // Handle menu item selections mDrawerList.setOnClickListener(new MenuListView.OnClickListener() { @Override public void onClick(MenuItem menuItem) { GalleryActivity.this.onOptionsItemSelected(menuItem); } }); UpdateLanguage(); } void UpdateLanguage() { Strings.SetMenuTitle(mDrawerList.getMenu(), R.id.menuItem_settings, LanguageStringID.ANDROID_SETTINGS); Strings.SetMenuTitle(mDrawerList.getMenu(), R.id.menuItem_forum, LanguageStringID.ANDROID_FORUM); Strings.SetMenuTitle(mDrawerList.getMenu(), R.id.menuItem_reportBug, LanguageStringID.ANDROID_REPORT_BUG); Strings.SetMenuTitle(mDrawerList.getMenu(), R.id.menuItem_about, LanguageStringID.ANDROID_ABOUT); } // Enables or disables the "please wait" screen. void setWaitScreen(boolean set) { if (set) { WebView webView = (WebView) findViewById(R.id.screen_wait); webView.loadData(Utility.readAsset("loading.htm", ""), "text/html", "UTF8"); } findViewById(R.id.screen_main).setVisibility(set ? View.GONE : View.VISIBLE); findViewById(R.id.screen_wait).setVisibility(set ? View.VISIBLE : View.GONE); } // Listener that's called when we finish querying the items and subscriptions we own IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() { public void onQueryInventoryFinished(IabResult result, Inventory inventory) { Log.d("GalleryActivity", "Query inventory finished."); // Have we been disposed of in the meantime? If so, quit. if (mIabHelper == null) return; // Is it a failure? if (result.isFailure()) { //complain("Failed to query inventory: " + result); return; } Log.d("GalleryActivity", "Query inventory was successful."); /* * Check for items we own. Notice that for each purchase, we check * the developer payload to see if it's correct! See * verifyDeveloperPayload(). */ /*IabHelper.OnConsumeFinishedListener listener = new IabHelper.OnConsumeFinishedListener() { @Override public void onConsumeFinished(Purchase purchase, IabResult result) { Log.d("GalleryActivity", "SKU_SAVESUPPORT consumed"); } }; try { mIabHelper.consumeAsync(inventory.getPurchase(SKU_SAVESUPPORT), listener); } catch (IabAsyncInProgressException e) { // TODO Auto-generated catch block e.printStackTrace(); }*/ Purchase ItemPurchase = inventory.getPurchase(SKU_SAVESUPPORT); Log.d("GalleryActivity", "Purchased SKU_SAVESUPPORT " + (ItemPurchase != null ? "Yes" : "No")); if (ItemPurchase != null) { mPj64Supporter = true; } if (!mPj64Supporter) { ItemPurchase = inventory.getPurchase(SKU_PJ64SUPPORTOR_2); Log.d("GalleryActivity", "Purchased SKU_PJ64SUPPORTOR_2 " + (ItemPurchase != null ? "Yes" : "No")); if (ItemPurchase != null) { mPj64Supporter = true; } } if (!mPj64Supporter) { ItemPurchase = inventory.getPurchase(SKU_PJ64SUPPORTOR_5); Log.d("GalleryActivity", "Purchased SKU_PJ64SUPPORTOR_5 " + (ItemPurchase != null ? "Yes" : "No")); if (ItemPurchase != null) { mPj64Supporter = true; } } if (!mPj64Supporter) { ItemPurchase = inventory.getPurchase(SKU_PJ64SUPPORTOR_8); Log.d("GalleryActivity", "Purchased SKU_PJ64SUPPORTOR_8 " + (ItemPurchase != null ? "Yes" : "No")); if (ItemPurchase != null) { mPj64Supporter = true; } } if (!mPj64Supporter) { ItemPurchase = inventory.getPurchase(SKU_PJ64SUPPORTOR_10); Log.d("GalleryActivity", "Purchased SKU_PJ64SUPPORTOR_10 " + (ItemPurchase != null ? "Yes" : "No")); if (ItemPurchase != null) { mPj64Supporter = true; } } setWaitScreen(false); } }; IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() { public void onIabPurchaseFinished(IabResult result, Purchase purchase) { Log.d("GalleryActivity", "Purchase finished: " + result + ", purchase: " + purchase); // if we were disposed of in the meantime, quit. if (mIabHelper == null) return; if (result.isFailure()) { Log.e("GalleryActivity", "**** Purcahse Error: " + result); alert("Save Support Upgrade failed\n\n" + result.getMessage()); setWaitScreen(false); ShowSupportWindow(); return; } Log.d("GalleryActivity", "Purchase successful."); if (purchase.getSku().equals(SKU_SAVESUPPORT)) { // bought the premium upgrade! Log.d("GalleryActivity", "Purchase is save support. Congratulating user."); alert("Thank you for upgrading to have save support!"); mHasSaveSupport = true; setWaitScreen(false); } if (purchase.getSku().equals(SKU_PJ64SUPPORTOR_2) || purchase.getSku().equals(SKU_PJ64SUPPORTOR_5) || purchase.getSku().equals(SKU_PJ64SUPPORTOR_8) || purchase.getSku().equals(SKU_PJ64SUPPORTOR_10)) { // bought the premium upgrade! Log.d("GalleryActivity", "Purchase is project64 support. Congratulating user."); alert("Thank you for supporting Project64!"); mPj64Supporter = true; setWaitScreen(false); } } }; void alert(String message) { AlertDialog.Builder bld = new AlertDialog.Builder(this); bld.setMessage(message); bld.setNeutralButton("OK", null); Log.d("GalleryActivity", "Showing alert dialog: " + message); bld.create().show(); } public void receivedBroadcast() { // Received a broadcast notification that the inventory of items has changed Log.d("GalleryActivity", "Received broadcast notification. Querying inventory."); try { mIabHelper.queryInventoryAsync(mGotInventoryListener); } catch (IabAsyncInProgressException e) { //complain("Error querying inventory. Another async operation in progress."); } } @Override protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); mDrawerToggle.syncState(); } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); mDrawerToggle.onConfigurationChanged(newConfig); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.gallery_activity, menu); Strings.SetMenuTitle(menu, R.id.menuItem_gameDir, LanguageStringID.ANDROID_GAMEDIR); return super.onCreateOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.menuItem_gameDir: Intent intent = new Intent(this, ScanRomsActivity.class); startActivityForResult(intent, GAME_DIR_REQUEST_CODE); return true; case R.id.menuItem_settings: Intent SettingsIntent = new Intent(this, SettingsActivity.class); startActivity(SettingsIntent); return true; case R.id.menuItem_forum: Intent ForumIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://forum.pj64-emu.com/forumdisplay.php?f=13")); startActivity(ForumIntent); return true; case R.id.menuItem_reportBug: Intent IssueIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://github.com/project64/project64/issues")); startActivity(IssueIntent); return true; case R.id.menuItem_about: Intent AboutIntent = new Intent(this, AboutActivity.class); startActivity(AboutIntent); return true; default: return super.onOptionsItemSelected(item); } } private boolean HasAutoSave(File GameSaveDir) { if (!GameSaveDir.exists() || !GameSaveDir.isDirectory()) { return false; } File[] fList = GameSaveDir.listFiles(); for (File file : fList) { String extension = ""; int i = file.getName().lastIndexOf('.'); if (i > 0) { extension = file.getName().substring(i + 1); } if (extension.equals("zip")) { i = file.getName().lastIndexOf('.', i - 1); if (i > 0) { extension = file.getName().substring(i + 1); } } if (extension.equals("pj.zip") || extension.equals("pj")) { return true; } } return false; } private void StartGameMenu(boolean ShowSettings) { File InstantSaveDir = new File( NativeExports.SettingsLoadString(SettingsID.Directory_InstantSave.getValue())); final File GameSaveDir = new File(InstantSaveDir, NativeExports.SettingsLoadString(SettingsID.Game_UniqueSaveDir.getValue())); class Item { public final String text; public final int icon; public Item(String text, Integer icon) { this.text = text; this.icon = icon; } @Override public String toString() { return text; } } List<Item> menuItemLst = new ArrayList<Item>(); if (ShouldShowSupportWindow()) { menuItemLst.add(new Item("Resume from Native save", R.drawable.ic_lock)); menuItemLst.add(new Item("Resume from Auto save", R.drawable.ic_lock)); } else { menuItemLst.add(new Item("Resume from Native save", R.drawable.ic_controller)); menuItemLst.add(new Item("Resume from Auto save", R.drawable.ic_play)); } menuItemLst.add(new Item("Restart", R.drawable.ic_refresh)); if (ShowSettings && !NativeExports.SettingsLoadBool(SettingsID.UserInterface_BasicMode.getValue())) { menuItemLst.add(new Item("Settings", R.drawable.ic_sliders)); } Item[] itemsDynamic = new Item[menuItemLst.size()]; itemsDynamic = menuItemLst.toArray(itemsDynamic); final Item[] items = itemsDynamic; final File SaveDir = GameSaveDir; ListAdapter adapter = new ArrayAdapter<Item>(this, android.R.layout.select_dialog_item, android.R.id.text1, items) { public View getView(int position, View convertView, android.view.ViewGroup parent) { //Use super class to create the View View v = super.getView(position, convertView, parent); TextView tv = (TextView) v.findViewById(android.R.id.text1); // Get Drawable icon Drawable d = items[position].icon != 0 ? ResourcesCompat.getDrawable(getResources(), items[position].icon, null) : null; tv.setTextColor(Color.parseColor("#FFFFFF")); if (d != null) { d.setColorFilter(Color.parseColor("#FFFFFF"), android.graphics.PorterDuff.Mode.SRC_ATOP); } if (!isEnabled(position)) { tv.setTextColor(Color.parseColor("#555555")); if (d != null) { d.setColorFilter(Color.parseColor("#555555"), android.graphics.PorterDuff.Mode.SRC_ATOP); } } //Put the image on the TextView tv.setCompoundDrawablesWithIntrinsicBounds(d, null, null, null); //Add margin between image and text (support various screen densities) int dp5 = (int) (5 * getResources().getDisplayMetrics().density + 0.5f); tv.setCompoundDrawablePadding(dp5); return v; } @Override public boolean areAllItemsEnabled() { return true; } @Override public boolean isEnabled(int position) { if (position == 1 && HasAutoSave(SaveDir) == false) { return false; } if (position == 2 && SaveDir.exists() == false) { return false; } return true; } }; final Context finalContext = this; final Activity finalActivity = this; AlertDialog.Builder GameMenu = new AlertDialog.Builder(finalContext); GameMenu.setTitle(NativeExports.SettingsLoadString(SettingsID.Game_GoodName.getValue())); GameMenu.setAdapter(adapter, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int item) { if ((item == 0 || item == 1) && ShouldShowSupportWindow()) { ShowSupportWindow(); return; } if (item == 0) { launchGameActivity(); } else if (item == 1) { NativeExports.SettingsSaveDword(SettingsID.Game_CurrentSaveState.getValue(), 0); NativeExports.ExternalEvent(SystemEvent.SysEvent_LoadMachineState.getValue()); launchGameActivity(); } else if (item == 2) { AlertDialog.Builder ResetPrompt = new AlertDialog.Builder(finalContext); ResetPrompt.setTitle(getText(R.string.confirmResetGame_title)) .setMessage(getText(R.string.confirmResetGame_message)) .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { String[] entries = SaveDir.list(); for (String s : entries) { File currentFile = new File(SaveDir.getPath(), s); currentFile.delete(); } SaveDir.delete(); NativeExports.UISettingsSaveDword(UISettingID.Game_RunCount.getValue(), 0); launchGameActivity(); } }).setNegativeButton(android.R.string.cancel, this).show(); } else if (item == 3) { Intent SettingsIntent = new Intent(finalContext, GameSettingsActivity.class); startActivityForResult(SettingsIntent, RC_SETTINGS); } } }); GameMenu.show(); } public void onGalleryItemClick(GalleryItem item) { NativeExports.LoadGame(item.romFile.getAbsolutePath()); if (ShouldShowSupportWindow()) { ShowSupportWindow(); } else { File InstantSaveDir = new File( NativeExports.SettingsLoadString(SettingsID.Directory_InstantSave.getValue())); final File GameSaveDir = new File(InstantSaveDir, NativeExports.SettingsLoadString(SettingsID.Game_UniqueSaveDir.getValue())); if (HasAutoSave(GameSaveDir)) { NativeExports.SettingsSaveDword(SettingsID.Game_CurrentSaveState.getValue(), 0); NativeExports.ExternalEvent(SystemEvent.SysEvent_LoadMachineState.getValue()); } launchGameActivity(); } } public boolean onGalleryItemLongClick(GalleryItem item) { NativeExports.LoadGame(item.romFile.getAbsolutePath()); if (ShouldShowSupportWindow()) { ShowSupportWindow(); } else { StartGameMenu(true); } Log.d("GalleryActivity", "onGalleryItemLongClick 4"); return true; } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { Log.d("GalleryActivity", "onActivityResult(" + requestCode + "," + resultCode + "," + data); if (requestCode == RC_SETTINGS) { StartGameMenu(true); return; } // Check which request we're responding to if (requestCode == GAME_DIR_REQUEST_CODE) { // Make sure the request was successful if (resultCode == RESULT_OK && data != null) { Bundle extras = data.getExtras(); String searchPath = extras.getString(ScanRomsActivity.GAME_DIR_PATH); boolean searchRecursively = extras.getBoolean(ScanRomsActivity.GAME_DIR_RECURSIVELY); if (searchPath != null) { NativeExports.RefreshRomDir(searchPath, searchRecursively); } } } // Pass on the activity result to the helper for handling if (mIabHelper != null && !mIabHelper.handleActivityResult(requestCode, resultCode, data)) { // not handled, so handle it ourselves (here's where you'd // perform any handling of activity results not related to in-app // billing... super.onActivityResult(requestCode, resultCode, data); } } void refreshGrid() { List<GalleryItem> items; items = new ArrayList<GalleryItem>(); if (mRecentItems.size() > 0) { items.add(new GalleryItem(this, Strings.GetString(LanguageStringID.ANDROID_GALLERY_RECENTLYPLAYED))); items.addAll(mRecentItems); items.add(new GalleryItem(this, Strings.GetString(LanguageStringID.ANDROID_GALLERY_LIBRARY))); } Collections.sort(mGalleryItems, new GalleryItem.NameComparator()); items.addAll(mGalleryItems); mGridView.setAdapter(new GalleryItem.Adapter(this, items)); // Allow the headings to take up the entire width of the layout final List<GalleryItem> finalItems = items; GridLayoutManager layoutManager = new GridLayoutManager(this, galleryColumns); layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { @Override public int getSpanSize(int position) { // Headings will take up every span (column) in the grid if (finalItems.get(position).isHeading) return galleryColumns; // Games will fit in a single column return 1; } }); mGridView.setLayoutManager(layoutManager); } @Override protected void onResume() { super.onResume(); refreshViews(); } @TargetApi(11) private void refreshViews() { // Refresh the gallery refreshGrid(); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_MENU) { if (mDrawerLayout.isDrawerOpen(GravityCompat.START)) { mDrawerLayout.closeDrawer(GravityCompat.START); } else { mDrawerLayout.openDrawer(GravityCompat.START); } return true; } return super.onKeyDown(keyCode, event); } @Override public void onBackPressed() { if (mDrawerLayout.isDrawerOpen(GravityCompat.START)) { mDrawerLayout.closeDrawer(GravityCompat.START); } else { moveTaskToBack(true); } } public void PurcahseProject64Support(Activity activity, String sku) { setWaitScreen(true); //Purchase save support try { String payload = NativeExports.appVersion(); mIabHelper.launchPurchaseFlow(activity, sku, RC_REQUEST, mPurchaseFinishedListener, payload); } catch (IabAsyncInProgressException e) { setWaitScreen(false); } } private boolean ShouldShowSupportWindow() { Log.d("GalleryActivity", "ShowSupportWindow mHasSaveSupport = " + mHasSaveSupport); if (mHasSaveSupport) { return false; } Log.d("GalleryActivity", "ShowSupportWindow mPj64Supporter = " + mPj64Supporter); if (mPj64Supporter) { return false; } int RunCount = NativeExports.UISettingsLoadDword(UISettingID.SupportWindow_RunCount.getValue()); Log.d("GalleryActivity", "ShowSupportWindow RunCount = " + RunCount); if (RunCount == -1) { return false; } RunCount = NativeExports.UISettingsLoadDword(UISettingID.Game_RunCount.getValue()); Log.d("GalleryActivity", "ShowSupportWindow Game_RunCount = " + RunCount); if (RunCount < 5) { return false; } return true; } public void ShowSupportWindow() { final Context context = this; final Activity activity = this; AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle(getText(R.string.GetSaveSupport_title)); builder.setMessage(getText(R.string.GetSaveSupport_message)); builder.setNeutralButton("Not now", null); builder.setNegativeButton("Support Project64", null); builder.setCancelable(false); final AlertDialog dialog = builder.create(); dialog.show(); dialog.getButton(AlertDialog.BUTTON_NEUTRAL).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { dialog.dismiss(); StartGameMenu(false); } }); dialog.getButton(AlertDialog.BUTTON_NEGATIVE).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { setWaitScreen(true); //Purchase save support try { String payload = NativeExports.appVersion(); mIabHelper.launchPurchaseFlow(activity, SKU_SAVESUPPORT, RC_REQUEST, mPurchaseFinishedListener, payload); } catch (IabAsyncInProgressException e) { setWaitScreen(false); } dialog.dismiss(); } }); dialog.setCanceledOnTouchOutside(false); } public void launchGameActivity() { // Launch the game activity boolean isXperiaPlay = false; Intent intent = isXperiaPlay ? new Intent(this, GameActivityXperiaPlay.class) : new Intent(this, GameActivity.class); this.startActivity(intent); } public static void LanguageChanged() { if (mActiveGalleryActivity != null) { mActiveGalleryActivity.finish(); mActiveGalleryActivity.startActivity(mActiveGalleryActivity.getIntent()); } } public static void RomListReset() { mGalleryItems = new ArrayList<GalleryItem>(); if (mActiveGalleryActivity != null && mActiveGalleryActivity.mProgress != null) { Handler h = new Handler(Looper.getMainLooper()); h.post(new Runnable() { public void run() { mActiveGalleryActivity.mProgress.show(); } }); } } public static void RomListAddItem(String FullFileName, String FileName, String GoodName, int TextColor) { GalleryItem item = new GalleryItem(mActiveGalleryActivity, GoodName, FileName, FullFileName, TextColor); mGalleryItems.add(item); if (mActiveGalleryActivity != null && mActiveGalleryActivity.mProgress != null) { Handler h = new Handler(Looper.getMainLooper()); final String ProgressText = new String(FileName); final String ProgressSubText = new String(FullFileName); final String ProgressMessage = new String("Added " + GoodName); h.post(new Runnable() { public void run() { mActiveGalleryActivity.mProgress.setText(ProgressText); mActiveGalleryActivity.mProgress.setSubtext(ProgressSubText); mActiveGalleryActivity.mProgress.setMessage(ProgressMessage); } }); } } private static void refreshRecentRoms() { mRecentItems = new ArrayList<GalleryItem>(); Log.d("GalleryActivity", "File_RecentGameFileCount = " + NativeExports.UISettingsLoadDword(UISettingID.File_RecentGameFileCount.getValue())); for (int i = 0, n = NativeExports .UISettingsLoadDword(UISettingID.File_RecentGameFileCount.getValue()); i < n; i++) { String RecentFile = NativeExports .UISettingsLoadStringIndex(UISettingID.File_RecentGameFileIndex.getValue(), i); if (RecentFile.length() == 0) { break; } for (int z = 0; z < mGalleryItems.size(); z++) { if (RecentFile.equals(mGalleryItems.get(z).romFile.getAbsolutePath())) { mRecentItems.add(mGalleryItems.get(z)); break; } } } } public static void RomListLoadDone() { refreshRecentRoms(); if (mActiveGalleryActivity != null && mActiveGalleryActivity.mProgress != null) { Handler h = new Handler(Looper.getMainLooper()); h.post(new Runnable() { public void run() { mActiveGalleryActivity.refreshGrid(); mActiveGalleryActivity.mProgress.dismiss(); } }); } } public static void RecentRomsUpdated() { refreshRecentRoms(); Handler h = new Handler(Looper.getMainLooper()); h.post(new Runnable() { public void run() { mActiveGalleryActivity.refreshGrid(); } }); } }