+ * On Android 4.2+ devices this will retrieve the optimal low-latency sampling rate, + * since Android 4.2 adds support for low latency audio in general. + *
+ * On other devices, it simply returns the regular optimal sampling rate + * as returned by the hardware. + * + * @param ctx The current {@link Context}. + * + * @return the optimal audio sampling rate in Hz. + */ + private static int getOptimalSamplingRate(Context ctx) + { + int ret; + if (Build.VERSION.SDK_INT >= 17) + ret = getLowLatencyOptimalSamplingRate(ctx); + else + ret = AudioTrack.getNativeOutputSampleRate(AudioManager.STREAM_MUSIC); + + Log.i(TAG, "Using sampling rate: " + ret + " Hz"); + return ret; + } +} diff --git a/pkg/android/phoenix64/src/com/retroarch/browser/retroactivity/RetroActivityCamera.java b/pkg/android/phoenix64/src/com/retroarch/browser/retroactivity/RetroActivityCamera.java new file mode 100644 index 0000000000..d51d7f768f --- /dev/null +++ b/pkg/android/phoenix64/src/com/retroarch/browser/retroactivity/RetroActivityCamera.java @@ -0,0 +1,225 @@ +package com.retroarch.browser.retroactivity; + +import java.io.IOException; + +import com.retroarch.browser.preferences.util.UserPreferences; + +import android.annotation.SuppressLint; +import android.content.SharedPreferences; +import android.graphics.SurfaceTexture; +import android.graphics.SurfaceTexture.OnFrameAvailableListener; +import android.hardware.Camera; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +//For Android 3.0 and up + +/** + * Class which provides {@link Camera} functionality + * to {@link RetroActivityFuture}. + */ +@SuppressLint("NewApi") +public class RetroActivityCamera extends RetroActivityCommon +{ + private Camera mCamera = null; + private long lastTimestamp = 0; + private SurfaceTexture texture; + private boolean updateSurface = true; + private boolean camera_service_running = false; + + /** + * Executed when the {@link Camera} + * is staring to capture. + */ + public void onCameraStart() + { + if (camera_service_running) + return; + + if (mCamera != null) + mCamera.startPreview(); + camera_service_running = true; + } + + /** + * Executed when the {@link Camera} is done capturing. + *
+ * Note that this does not release the currently held + * {@link Camera} instance and must be freed by calling + * {@link #onCameraFree} + */ + public void onCameraStop() + { + if (!camera_service_running) + return; + + if (mCamera != null) + mCamera.stopPreview(); + camera_service_running = false; + } + + /** + * Releases the currently held {@link Camera} instance. + */ + public void onCameraFree() + { + onCameraStop(); + + if (mCamera != null) + mCamera.release(); + } + + /** + * Initializes the camera for use. + */ + public void onCameraInit() + { + if (mCamera != null) + return; + + mCamera = Camera.open(); + } + + /** + * Polls the camera for updates to the {@link SurfaceTexture}. + * + * @return true if polling was successful, false otherwise. + */ + public boolean onCameraPoll() + { + if (!camera_service_running) + return false; + + if (texture == null) + { + Log.i("RetroActivity", "No texture"); + return true; + } + else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) + { + if (updateSurface) + { + texture.updateTexImage(); + } + + long newTimestamp = texture.getTimestamp(); + + if (newTimestamp != lastTimestamp) + { + lastTimestamp = newTimestamp; + return true; + } + + return false; + } + + return true; + } + + /** + * Initializes the {@link SurfaceTexture} used by the + * {@link Camera} with a given OpenGL texure ID. + * + * @param gl_texid texture ID to initialize the + * {@link SurfaceTexture} with. + */ + public void onCameraTextureInit(int gl_texid) + { + texture = new SurfaceTexture(gl_texid); + texture.setOnFrameAvailableListener(onCameraFrameAvailableListener); + } + + /** + * Sets the {@link Camera} texture with the texture represented + * by the given OpenGL texture ID. + * + * @param gl_texid The texture ID representing the texture to set the camera to. + * @throws IOException If setting the texture fails. + */ + public void onCameraSetTexture(int gl_texid) throws IOException + { + if (texture == null) + onCameraTextureInit(gl_texid); + + if (mCamera != null) + mCamera.setPreviewTexture(texture); + } + + private final OnFrameAvailableListener onCameraFrameAvailableListener = new OnFrameAvailableListener() + { + @Override + public void onFrameAvailable(SurfaceTexture surfaceTexture) + { + updateSurface = true; + } + }; + + @Override + public void onCreate(Bundle savedInstanceState) + { + // Save the current setting for updates + SharedPreferences prefs = UserPreferences.getPreferences(this); + SharedPreferences.Editor edit = prefs.edit(); + edit.putBoolean("CAMERA_UPDATES_ON", false); + edit.apply(); + + camera_service_running = false; + + super.onCreate(savedInstanceState); + } + + @Override + public void onPause() + { + // Save the current setting for updates + SharedPreferences prefs = UserPreferences.getPreferences(this); + SharedPreferences.Editor edit = prefs.edit(); + edit.putBoolean("CAMERA_UPDATES_ON", camera_service_running); + edit.apply(); + + onCameraStop(); + super.onPause(); + } + + @Override + public void onResume() + { + SharedPreferences prefs = UserPreferences.getPreferences(this); + SharedPreferences.Editor edit = prefs.edit(); + + /* + * Get any previous setting for camera updates + * Gets "false" if an error occurs + */ + if (prefs.contains("CAMERA_UPDATES_ON")) + { + camera_service_running = prefs.getBoolean("CAMERA_UPDATES_ON", false); + if (camera_service_running) + { + onCameraStart(); + } + } + else // Otherwise, turn off camera updates + { + edit.putBoolean("CAMERA_UPDATES_ON", false); + edit.apply(); + camera_service_running = false; + } + super.onResume(); + } + + @Override + public void onDestroy() + { + onCameraFree(); + super.onDestroy(); + } + + @Override + public void onStop() + { + onCameraStop(); + super.onStop(); + } +} diff --git a/pkg/android/phoenix64/src/com/retroarch/browser/retroactivity/RetroActivityCommon.java b/pkg/android/phoenix64/src/com/retroarch/browser/retroactivity/RetroActivityCommon.java new file mode 100644 index 0000000000..e660dd2eb9 --- /dev/null +++ b/pkg/android/phoenix64/src/com/retroarch/browser/retroactivity/RetroActivityCommon.java @@ -0,0 +1,141 @@ +package com.retroarch.browser.retroactivity; + +import com.retroarch.browser.preferences.util.UserPreferences; +import android.annotation.TargetApi; +import android.content.res.Configuration; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.app.UiModeManager; +import android.os.BatteryManager; +import android.os.Build; +import android.os.PowerManager; +import android.util.Log; + +import java.util.concurrent.CountDownLatch; + +/** + * Class which provides common methods for RetroActivity related classes. + */ +public class RetroActivityCommon extends RetroActivityLocation +{ + public static int FRONTEND_POWERSTATE_NONE = 0; + public static int FRONTEND_POWERSTATE_NO_SOURCE = 1; + public static int FRONTEND_POWERSTATE_CHARGING = 2; + public static int FRONTEND_POWERSTATE_CHARGED = 3; + public static int FRONTEND_POWERSTATE_ON_POWER_SOURCE = 4; + public boolean sustainedPerformanceMode = true; + + // 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. + public void onRetroArchExit() + { + finish(); + } + + @TargetApi(24) + public void setSustainedPerformanceMode(boolean on) + { + sustainedPerformanceMode = on; + + if (Build.VERSION.SDK_INT >= 24) { + if (isSustainedPerformanceModeSupported()) { + final CountDownLatch latch = new CountDownLatch(1); + + runOnUiThread(new Runnable() { + @Override + public void run() { + Log.i("RetroActivity", "setting sustained performance mode to " + sustainedPerformanceMode); + + getWindow().setSustainedPerformanceMode(sustainedPerformanceMode); + + latch.countDown(); + } + }); + + try { + latch.await(); + }catch(InterruptedException e) { + e.printStackTrace(); + } + } + } + } + + @TargetApi(24) + public boolean isSustainedPerformanceModeSupported() + { + boolean supported = false; + + if (Build.VERSION.SDK_INT >= 24) + { + PowerManager powerManager = (PowerManager)getSystemService(Context.POWER_SERVICE); + + if (powerManager.isSustainedPerformanceModeSupported()) + supported = true; + } + + + Log.i("RetroActivity", "isSustainedPerformanceModeSupported? " + supported); + + return supported; + } + + public int getBatteryLevel() + { + IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); + // This doesn't actually register anything (or need to) because we know this particular intent is sticky and we do not specify a BroadcastReceiver anyway + Intent batteryStatus = registerReceiver(null, ifilter); + int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, 0); + int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, 100); + + float percent = ((float)level / (float)scale) * 100.0f; + + Log.i("RetroActivity", "battery: level = " + level + ", scale = " + scale + ", percent = " + percent); + + return (int)percent; + } + + public int getPowerstate() + { + IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); + // This doesn't actually register anything (or need to) because we know this particular intent is sticky and we do not specify a BroadcastReceiver anyway + Intent batteryStatus = registerReceiver(null, ifilter); + int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1); + boolean hasBattery = batteryStatus.getBooleanExtra(BatteryManager.EXTRA_PRESENT, false); + boolean isCharging = (status == BatteryManager.BATTERY_STATUS_CHARGING); + boolean isCharged = (status == BatteryManager.BATTERY_STATUS_FULL); + int powerstate = FRONTEND_POWERSTATE_NONE; + + if (isCharged) + powerstate = FRONTEND_POWERSTATE_CHARGED; + else if (isCharging) + powerstate = FRONTEND_POWERSTATE_CHARGING; + else if (!hasBattery) + powerstate = FRONTEND_POWERSTATE_NO_SOURCE; + else + powerstate = FRONTEND_POWERSTATE_ON_POWER_SOURCE; + + Log.i("RetroActivity", "power state = " + powerstate); + + return powerstate; + } + + public boolean isAndroidTV() + { + Configuration config = getResources().getConfiguration(); + UiModeManager uiModeManager = (UiModeManager)getSystemService(UI_MODE_SERVICE); + + if (uiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_TELEVISION) + { + Log.i("RetroActivity", "isAndroidTV == true"); + return true; + } + else + { + Log.i("RetroActivity", "isAndroidTV == false"); + return false; + } + } +} diff --git a/pkg/android/phoenix64/src/com/retroarch/browser/retroactivity/RetroActivityFuture.java b/pkg/android/phoenix64/src/com/retroarch/browser/retroactivity/RetroActivityFuture.java new file mode 100644 index 0000000000..eba29872a6 --- /dev/null +++ b/pkg/android/phoenix64/src/com/retroarch/browser/retroactivity/RetroActivityFuture.java @@ -0,0 +1,87 @@ +package com.retroarch.browser.retroactivity; + +import android.view.View; +import android.view.WindowManager; +import android.content.Intent; +import android.content.Context; +import android.hardware.input.InputManager; +import android.os.Build; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +public final class RetroActivityFuture extends RetroActivityCamera { + + // If set to true then Retroarch will completely exit when it loses focus + private boolean quitfocus = false; + + @Override + public void onResume() { + super.onResume(); + + setSustainedPerformanceMode(sustainedPerformanceMode); + + if (Build.VERSION.SDK_INT >= 19) { + // Immersive mode + + // Constants from API > 14 + final int API_SYSTEM_UI_FLAG_LAYOUT_STABLE = 0x00000100; + final int API_SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION = 0x00000200; + final int API_SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN = 0x00000400; + final int API_SYSTEM_UI_FLAG_FULLSCREEN = 0x00000004; + final int API_SYSTEM_UI_FLAG_IMMERSIVE_STICKY = 0x00001000; + + View thisView = getWindow().getDecorView(); + thisView.setSystemUiVisibility(API_SYSTEM_UI_FLAG_LAYOUT_STABLE + | API_SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + | API_SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN + | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION + | API_SYSTEM_UI_FLAG_FULLSCREEN + | API_SYSTEM_UI_FLAG_IMMERSIVE_STICKY); + + // Check for Android UI specific parameters + Intent retro = getIntent(); + String refresh = retro.getStringExtra("REFRESH"); + + // If REFRESH parameter is provided then try to set refreshrate accordingly + if(refresh != null) { + WindowManager.LayoutParams params = getWindow().getAttributes(); + params.preferredRefreshRate = Integer.parseInt(refresh); + getWindow().setAttributes(params); + } + + // If QUITFOCUS parameter is provided then enable that Retroarch quits when focus is lost + quitfocus = retro.hasExtra("QUITFOCUS"); + + // If HIDEMOUSE parameters is provided then hide the mourse cursor + // This requires NVIDIA Android extensions (available on NVIDIA Shield), if they are not + // available then nothing will be done + if (retro.hasExtra("HIDEMOUSE")) hideMouseCursor(); + } + } + + public void hideMouseCursor() { + + // Check for NVIDIA extensions and minimum SDK version + Method mInputManager_setCursorVisibility; + try { mInputManager_setCursorVisibility = + InputManager.class.getMethod("setCursorVisibility", boolean.class); + } + catch (NoSuchMethodException ex) { + return; // Extensions were not available so do nothing + } + + // Hide the mouse cursor + InputManager inputManager = (InputManager) getSystemService(Context.INPUT_SERVICE); + try { mInputManager_setCursorVisibility.invoke(inputManager, false); } + catch (InvocationTargetException ite) { } + catch (IllegalAccessException iae) { } + } + + @Override + public void onStop() { + super.onStop(); + + // If QUITFOCUS parameter was set then completely exit Retroarch when focus is lost + if (quitfocus) System.exit(0); + } +} diff --git a/pkg/android/phoenix64/src/com/retroarch/browser/retroactivity/RetroActivityIntent.java b/pkg/android/phoenix64/src/com/retroarch/browser/retroactivity/RetroActivityIntent.java new file mode 100644 index 0000000000..91ccc3f8a6 --- /dev/null +++ b/pkg/android/phoenix64/src/com/retroarch/browser/retroactivity/RetroActivityIntent.java @@ -0,0 +1,105 @@ +package com.retroarch.browser.retroactivity; + +import com.retroarch.browser.mainmenu.MainMenuActivity; + +import android.content.Intent; +import android.util.Log; + +public class RetroActivityIntent extends RetroActivityCommon { + private Intent pendingIntent = null; + private static final String TAG = "RetroArch"; + + @Override + public void onBackPressed() + { + Log.i("RetroActivity", "onBackKeyPressed"); + Intent retro = new Intent(this, MainMenuActivity.class); + retro.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); + startActivity(retro); + } + + @Override + public void onNewIntent(Intent intent) + { + Log.i("RetroActivity", "onNewIntent invoked."); + super.onNewIntent(intent); + setIntent(intent); + pendingIntent = intent; + } + + /** + * Gets the ROM file specified in the pending intent. + * + * @return the ROM file specified in the pending intent. + */ + public String getPendingIntentFullPath() + { + return pendingIntent.getStringExtra("ROM"); + } + + /** + * Gets the specified path to the libretro core in the pending intent. + * + * @return the specified path to the libretro core in the pending intent. + */ + public String getPendingIntentLibretroPath() + { + return pendingIntent.getStringExtra("LIBRETRO"); + } + + /** + * Gets the path specified in the pending intent to the retroarch cfg file. + * + * @return the path specified in the pending intent to the retroarch cfg file. + */ + public String getPendingIntentConfigPath() + { + return pendingIntent.getStringExtra("CONFIGFILE"); + } + + public String getPendingIntentStorageLocation() + { + return pendingIntent.getStringExtra("SDCARD"); + } + + public String getPendingIntentDownloadLocation() + { + return pendingIntent.getStringExtra("DOWNLOADS"); + } + + public String getPendingIntentScreenshotsLocation() + { + return pendingIntent.getStringExtra("SCREENSHOTS"); + } + + /** + * Gets the specified IME in the pending intent. + * + * @return the specified IME in the pending intent. + */ + public String getPendingIntentIME() + { + return pendingIntent.getStringExtra("IME"); + } + + /** + * Checks whether or not a pending intent exists. + * + * @return true if a pending intent exists, false otherwise. + */ + public boolean hasPendingIntent() + { + if (pendingIntent == null) + return false; + + return true; + } + + /** + * Clears the current pending intent. + */ + public void clearPendingIntent() + { + pendingIntent = null; + } +} diff --git a/pkg/android/phoenix64/src/com/retroarch/browser/retroactivity/RetroActivityLocation.java b/pkg/android/phoenix64/src/com/retroarch/browser/retroactivity/RetroActivityLocation.java new file mode 100644 index 0000000000..9fedbf2e7b --- /dev/null +++ b/pkg/android/phoenix64/src/com/retroarch/browser/retroactivity/RetroActivityLocation.java @@ -0,0 +1,316 @@ +package com.retroarch.browser.retroactivity; + +import com.google.android.gms.common.ConnectionResult; +import com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks; +import com.google.android.gms.common.GooglePlayServicesClient.OnConnectionFailedListener; +import com.google.android.gms.location.LocationClient; +import com.google.android.gms.location.LocationListener; +import com.google.android.gms.location.LocationRequest; +import com.retroarch.browser.preferences.util.UserPreferences; + +import android.app.NativeActivity; +import android.content.IntentSender; +import android.content.SharedPreferences; +import android.location.Location; +import android.os.Bundle; +import android.util.Log; +import android.widget.Toast; + +/** + * Class that implements location-based functionality for + * the {@link RetroActivityFuture} and {@link RetroActivityPast} + * activities. + */ +public class RetroActivityLocation extends NativeActivity +implements ConnectionCallbacks, OnConnectionFailedListener, LocationListener +{ + /* LOCATION VARIABLES */ + private static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 0; + private LocationClient mLocationClient = null; + private Location mCurrentLocation; + + // Define an object that holds accuracy and frequency parameters + LocationRequest mLocationRequest = null; + boolean mUpdatesRequested = false; + boolean locationChanged = false; + boolean location_service_running = false; + + /** + * Called by Location Services when the request to connect the + * client finishes successfully. At this point, you can + * request the current location or start periodic updates + */ + @Override + public void onConnected(Bundle dataBundle) + { + if (mLocationClient == null) + return; + + // Display the connection status + Toast.makeText(this, "Connected", Toast.LENGTH_SHORT).show(); + location_service_running = true; + + // If already requested, start periodic updates + if (mUpdatesRequested) + { + mLocationClient.requestLocationUpdates(mLocationRequest, this, null); + } + else + { + // Get last known location + mCurrentLocation = mLocationClient.getLastLocation(); + locationChanged = true; + } + } + + /** + * Called by Location Services if the connection to the + * location client drops because of an error. + */ + @Override + public void onDisconnected() + { + if (mLocationClient == null) + return; + + // Display the connection status + Toast.makeText(this, "Disconnected. Please re-connect.", Toast.LENGTH_SHORT).show(); + + // If the client is connected + if (mLocationClient.isConnected()) + { + /* + * Remove location updates for a listener. + * The current Activity is the listener, so + * the argument is "this". + */ + mLocationClient.removeLocationUpdates(this); + } + + location_service_running = false; + } + + /** + * Called by Location Services if the attempt to + * Location Services fails. + */ + @Override + public void onConnectionFailed(ConnectionResult connectionResult) + { + /* + * Google Play services can resolve some errors it detects. + * If the error has a resolution, try sending an Intent to + * start a Google Play services activity that can resolve + * error. + */ + if (connectionResult.hasResolution()) + { + try + { + // Start an Activity that tries to resolve the error + connectionResult.startResolutionForResult(this, CONNECTION_FAILURE_RESOLUTION_REQUEST); + } + catch (IntentSender.SendIntentException e) + { + // Thrown if Google Play services cancelled the original PendingIntent + e.printStackTrace(); + } + } + else + { + /* + * If no resolution is available, display a dialog to the + * user with the error. + */ + Log.e("Connection failed", "error code: " + connectionResult.getErrorCode()); + } + } + + /** + * Sets the update interval at which location-based updates + * should occur + */ + public void onLocationSetInterval(int update_interval_in_ms, int distance_interval) + { + // Use high accuracy + if (mLocationRequest == null) + return; + + mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); + + if (update_interval_in_ms == 0) + mLocationRequest.setInterval(5 * 1000); // 5 seconds + else + mLocationRequest.setInterval(update_interval_in_ms); + + // Set the fastest update interval to 1 second + mLocationRequest.setFastestInterval(1000); + } + + /** + * Initializing methods for location based functionality. + */ + public void onLocationInit() + { + /* + * Create a new location client, using the enclosing class to + * handle callbacks. + */ + if (mLocationClient == null) + mLocationClient = new LocationClient(this, this, this); + + // Start with updates turned off + mUpdatesRequested = false; + + // Create the LocationRequest object + if (mLocationRequest == null) + mLocationRequest = LocationRequest.create(); + + onLocationSetInterval(0, 0); + } + + + /** + * Executed upon starting the {@link LocationClient}. + */ + public void onLocationStart() + { + if (mLocationClient == null) + return; + + mUpdatesRequested = true; + + // Connect the client. + mLocationClient.connect(); + } + + /** + * Free up location services resources. + */ + public void onLocationFree() + { + /* TODO/FIXME */ + } + + /** + * Executed upon stopping the location client. + * Does nothing if called when the client is not started. + */ + public void onLocationStop() + { + // Disconnecting the client invalidates it. + if (mLocationClient != null && mUpdatesRequested) + mLocationClient.disconnect(); + } + + /** + * Gets the latitude at the current location in degrees. + * + * @return the latitude at the current location. + */ + public double onLocationGetLatitude() + { + return mCurrentLocation.getLatitude(); + } + + /** + * Gets the longitude at the current location in degrees. + * + * @return the longitude at the current location. + */ + public double onLocationGetLongitude() + { + return mCurrentLocation.getLongitude(); + } + + /** + * Gets the horizontal accuracy of the current location + * in meters. (NOTE: There seems to be no vertical accuracy + * for a given location with the Android location API) + * + * @return the horizontal accuracy of the current position. + */ + public double onLocationGetHorizontalAccuracy() + { + return mCurrentLocation.getAccuracy(); + } + + /** + * Tells us whether the location listener callback has + * updated the current location since the last time + * we polled. + * + * @return true if location has changed, false if location has not changed. + */ + public boolean onLocationHasChanged() + { + boolean hasChanged = locationChanged; + + // Reset flag + if (hasChanged) + locationChanged = false; + + return hasChanged; + } + + // Define the callback method that receives location updates + @Override + public void onLocationChanged(Location location) + { + if (!location_service_running) + return; + + locationChanged = true; + mCurrentLocation = location; + + // Report to the UI that the location was updated + String msg = "Updated Location: " + location.getLatitude() + ", " + location.getLongitude(); + Log.i("RetroArch GPS", msg); + //Toast.makeText(this, msg, Toast.LENGTH_SHORT).show(); + } + + @Override + public void onPause() + { + // Save the current setting for updates + SharedPreferences prefs = UserPreferences.getPreferences(this); + SharedPreferences.Editor edit = prefs.edit(); + edit.putBoolean("LOCATION_UPDATES_ON", mUpdatesRequested); + edit.apply(); + + super.onPause(); + } + + @Override + public void onResume() + { + SharedPreferences prefs = UserPreferences.getPreferences(this); + SharedPreferences.Editor edit = prefs.edit(); + + /* + * Get any previous setting for location updates + * Gets "false" if an error occurs + */ + if (prefs.contains("LOCATION_UPDATES_ON")) + { + mUpdatesRequested = prefs.getBoolean("LOCATION_UPDATES_ON", false); + if (mUpdatesRequested) + location_service_running = true; + } + else // Otherwise, turn off location updates + { + edit.putBoolean("LOCATION_UPDATES_ON", false); + edit.apply(); + location_service_running = false; + } + + super.onResume(); + } + + @Override + public void onStop() + { + onLocationStop(); + super.onStop(); + } +} diff --git a/pkg/android/phoenix64/src/com/retroarch/browser/retroactivity/RetroActivityPast.java b/pkg/android/phoenix64/src/com/retroarch/browser/retroactivity/RetroActivityPast.java new file mode 100644 index 0000000000..4c11369ee9 --- /dev/null +++ b/pkg/android/phoenix64/src/com/retroarch/browser/retroactivity/RetroActivityPast.java @@ -0,0 +1,7 @@ +package com.retroarch.browser.retroactivity; + +// For Android 2.3.x + +public final class RetroActivityPast extends RetroActivityCommon +{ +} diff --git a/pkg/android/phoenix64/version_increment.py b/pkg/android/phoenix64/version_increment.py new file mode 100644 index 0000000000..fbd58ff906 --- /dev/null +++ b/pkg/android/phoenix64/version_increment.py @@ -0,0 +1,20 @@ +#!/usr/bin/python +import time + + +from xml.dom.minidom import parse +dom1 = parse("AndroidManifest.xml") +oldVersion = dom1.documentElement.getAttribute("android:versionCode") +versionNumbers = oldVersion.split('.') + +versionName = dom1.documentElement.getAttribute("android:versionName") +versionName = versionName + "_GIT" + +versionNumbers[-1] = unicode(int(time.time())) +dom1.documentElement.setAttribute("android:versionCode", u'.'.join(versionNumbers)) +dom1.documentElement.setAttribute("android:versionName", versionName) + +with open("AndroidManifest.xml", 'wb') as f: + for line in dom1.toxml("utf-8"): + f.write(line) +