diff --git a/code/portal_highlighter.js b/code/portal_highlighter.js index e9de1edc..7e6feb15 100644 --- a/code/portal_highlighter.js +++ b/code/portal_highlighter.js @@ -6,19 +6,37 @@ window._highlighters = null; window._current_highlighter = localStorage.portal_highlighter; window._no_highlighter = 'No Highlights'; +if(window._current_highlighter !== undefined) { + if (typeof android !== 'undefined' && android && android.setActiveHighlighter) + android.setActiveHighlighter(window._current_highlighter); +} + + window.addPortalHighlighter = function(name, callback) { if(_highlighters === null) { _highlighters = {}; } _highlighters[name] = callback; + + if (typeof android !== 'undefined' && android && android.addPortalHighlighter) + android.addPortalHighlighter(name); + if(localStorage.portal_highlighter === undefined) { _current_highlighter = name; + if (typeof android !== 'undefined' && android && android.setActiveHighlighter) + android.setActiveHighlighter(name); + localStorage.portal_highlighter = name; } portalHighlighterControl(); } window.portalHighlighterControl = function() { + if (typeof android !== 'undefined' && android && android.addPortalHighlighter) { + $('#portal_highlight_select').remove(); + return; + } + if(_highlighters !== null) { if($('#portal_highlight_select').length === 0) { $("body").append(""); @@ -32,13 +50,6 @@ window.portalHighlighterControl = function() { }); $("#portal_highlight_select").val(_current_highlighter); $("#portal_highlight_select").change(function(){ changePortalHighlights($(this).val());}); - // notify android that the select spinner is enabled. - // this disables javascript injection on android side. - // if android is not notified, the spinner closes on the next JS call - if (typeof android !== 'undefined' && android && android.spinnerEnabled) { - $("#portal_highlight_select").click(function(){ android.spinnerEnabled(true);}); - $("#portal_highlight_select").focus(function(){ android.spinnerEnabled(false);}); - } $(".leaflet-top.leaflet-left").css('padding-top', '20px'); $(".leaflet-control-scale-line").css('margin-top','25px'); } @@ -46,6 +57,8 @@ window.portalHighlighterControl = function() { window.changePortalHighlights = function(name) { _current_highlighter = name; + if (typeof android !== 'undefined' && android && android.setActiveHighlighter) + android.setActiveHighlighter(name); resetHighlightedPortals(); localStorage.portal_highlighter = name; } diff --git a/code/smartphone.js b/code/smartphone.js index f8cf7d4b..edaa1d8b 100644 --- a/code/smartphone.js +++ b/code/smartphone.js @@ -125,6 +125,18 @@ window.runOnSmartphonesAfterBoot = function() { var l = $('#chatcontrols a:visible'); l.css('width', 100/l.length + '%'); + // notify android that a select spinner is enabled. + // this disables javascript injection on android side. + // if android is not notified, the spinner closes on the next JS call + if (typeof android !== 'undefined' && android && android.spinnerEnabled) { + $("body").on("click", "select", function() { + android.spinnerEnabled(true); + }); + $("body").on("focus", "select", function() { + android.spinnerEnabled(false); + }); + } + // add event to portals that allows long press to switch to sidebar window.addHook('portalAdded', function(data) { data.portal.on('add', function() { diff --git a/mobile/AndroidManifest.xml b/mobile/AndroidManifest.xml index f5659971..2dc57bbc 100644 --- a/mobile/AndroidManifest.xml +++ b/mobile/AndroidManifest.xml @@ -1,8 +1,8 @@ + package="com.cradle.iitc_mobile" + android:versionCode="48" + android:versionName="0.6.4"> + android:theme="@style/AppBaseTheme"> @@ -37,7 +37,7 @@ - + @@ -49,12 +49,12 @@ + android:pathPrefix="/intel" + android:scheme="https"/> + android:pathPrefix="/intel" + android:scheme="http"/> @@ -68,24 +68,24 @@ - + + android:configChanges="orientation|keyboard|keyboardHidden|screenSize" + android:label="@string/activity_settings" + android:theme="@style/AppBaseTheme"/> - + android:configChanges="orientation|keyboard|keyboardHidden|screenSize" + android:label="@string/activity_plugins" + android:theme="@style/AppBaseTheme"/> @@ -100,7 +100,7 @@ android:excludeFromRecents="true" android:exported="false" android:icon="@drawable/copy" - android:label="Copy to clipboard" + android:label="@string/activity_share_to_clipboard" android:noHistory="false"> @@ -137,4 +137,4 @@ android:value="com.cradle.iitc_mobile.IITC_Mobile"/> - + \ No newline at end of file diff --git a/mobile/README.md b/mobile/README.md index 8fdf2f40..6d4b7e21 100644 --- a/mobile/README.md +++ b/mobile/README.md @@ -9,7 +9,7 @@ The Android App behaves like the desktop version, but uses the mobile view, whic - show users current location -- a geo intent is sent, when a portals Map link is clicked (lets you navigate to portals) +- share interface for portal links, portal navigation etc. - a geolocate button (you have to enable GPS satellites + location access to use this feature) @@ -23,7 +23,7 @@ The Android App behaves like the desktop version, but uses the mobile view, whic - in-app search -- support for unofficial plugins. Just copy the *.user.js files to ```/IITC_Mobile/plugins/``` and they should appear at the end of the plugin list. Note: For every option a new persistent database entry is created. If you want to remove a plugin from your external storage you want to ensure that it is disabled in the settings, otherwise IITCM will always try to load it on start-up. If you messed this up you can wipe app data or add the plugin back to storage, disable it and remove it. Another option would be: Do nothing...it should work even so. +- support for unofficial plugins. Just copy the *.user.js files to ```/IITC_Mobile/plugins/``` and they should appear at the top of the plugin list. Note: For every option a new persistent database entry is created. If you want to remove a plugin from your external storage you want to ensure that it is disabled in the settings, otherwise IITCM will always try to load it on start-up. If you messed this up you can wipe app data or add the plugin back to storage, disable it and remove it. Another option would be: Do nothing...it should work even so. - developer mode: all script source will be loaded from ```/IITC_Mobile/dev/``` diff --git a/mobile/res/values/strings.xml b/mobile/res/values/strings.xml index c1265866..2e067082 100644 --- a/mobile/res/values/strings.xml +++ b/mobile/res/values/strings.xml @@ -2,6 +2,10 @@ IITC Mobile + IITC Mobile Settings + IITC Plugins + Share using… + Copy to clipboard Settings Reload IITC Print Version @@ -67,9 +71,9 @@ Press back button twice to exit Avoids accidental exits Developer options - Enable developer mode - If enabled, all IITC sources will be loaded from external storage of the Android device. - Please copy all sources from $IITC_folder/build/mobile/ to /sdcard/IITC_Mobile/dev/. + Enable developer mode + If enabled, all IITC sources will be loaded from external storage of the Android device. + Please copy all sources from $IITC_folder/build/mobile/ to /sdcard/IITC_Mobile/dev/. Display advanced menu In addition to the default IITC buttons the advanced menu contains a debug pane plus an option to clear cookies @@ -99,4 +103,5 @@ Base Layers Overlay Layers Deselect/Select all - + + \ No newline at end of file diff --git a/mobile/smartphone.css b/mobile/smartphone.css index 1a7f7076..bec0a5e8 100644 --- a/mobile/smartphone.css +++ b/mobile/smartphone.css @@ -185,12 +185,6 @@ body { width: 100%; } - -#portal_highlight_select{ - top:0px !important; - left:0px !important; -} - /* * for some reason leaflet popups on mobile are colored white on white * so force the popup msg color to black diff --git a/mobile/src/com/cradle/iitc_mobile/IITC_ActionBarHelper.java b/mobile/src/com/cradle/iitc_mobile/IITC_ActionBarHelper.java new file mode 100644 index 00000000..01b6ebe7 --- /dev/null +++ b/mobile/src/com/cradle/iitc_mobile/IITC_ActionBarHelper.java @@ -0,0 +1,158 @@ +package com.cradle.iitc_mobile; + +import android.app.ActionBar; +import android.app.ActionBar.OnNavigationListener; +import android.content.SharedPreferences; +import android.preference.PreferenceManager; +import android.widget.ArrayAdapter; +import android.widget.Toast; + +public class IITC_ActionBarHelper implements OnNavigationListener { + // Show/hide the up arrow on the very left + // getActionBar().setDisplayHomeAsUpEnabled(enabled); + + // Show/hide the activity icon/logo + // getActionBar().setDisplayShowHomeEnabled(enabled); + + // Show/hide the activity title + // getActionBar().setDisplayShowTitleEnabled(enabled); + + // Makes the icon/title clickable + // getActionBar().setHomeButtonEnabled(enabled); + + private class HighlighterAdapter extends ArrayAdapter { + public HighlighterAdapter() { + super(mIitc, android.R.layout.simple_list_item_1); + clear(); + } + + @Override + public void add(String object) { + super.remove(object); // to avoid duplicates + super.add(object); + } + + @Override + public void clear() { + super.clear(); + add("No Highlights");// Probably must be the same as window._no_highlighter + } + } + + private IITC_Mobile mIitc; + private ActionBar mActionBar; + private SharedPreferences mPrefs; + private HighlighterAdapter mHighlighters; + + private String mActiveHighlighter = null; + private boolean mDesktopMode = false; + private boolean mFullscreen = false; + private boolean mHideInFullscreen = false; + private int mPane = android.R.id.home; + + public IITC_ActionBarHelper(IITC_Mobile activity, ActionBar bar) { + mIitc = activity; + mActionBar = bar; + mPrefs = PreferenceManager.getDefaultSharedPreferences(activity); + mHighlighters = new HighlighterAdapter(); + + mActionBar.setDisplayShowHomeEnabled(true); // show icon + mActionBar.setListNavigationCallbacks(mHighlighters, this); + + onPrefChanged(); // also calls updateActionBar() + } + + private void updateActionBar() { + boolean showHighlighter = true; + + if (mDesktopMode) { + mActionBar.setDisplayHomeAsUpEnabled(false); // Hide "up" indicator + mActionBar.setHomeButtonEnabled(false); // Make icon unclickable + mActionBar.setTitle(mIitc.getString(R.string.app_name)); + } else { + if (mPane != android.R.id.home) { + mActionBar.setDisplayHomeAsUpEnabled(true); // Show "up" indicator + mActionBar.setHomeButtonEnabled(true);// Make icon clickable + showHighlighter = false; + } + else { + mActionBar.setDisplayHomeAsUpEnabled(false); // Hide "up" indicator + mActionBar.setHomeButtonEnabled(false); // Make icon unclickable + } + mActionBar.setTitle(IITC_Mobile.PANE_TITLES.get(mPane, mIitc.getString(R.string.app_name))); + } + + if (mHighlighters.getCount() < 2) // there should always be "No Highlights" + showHighlighter = false; + + if (showHighlighter) { + mActionBar.setDisplayShowTitleEnabled(false); // Hide title + mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST); + setActiveHighlighter(mActiveHighlighter); + } else { + mActionBar.setDisplayShowTitleEnabled(true); // Show title + mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD); + } + if (mFullscreen && mHideInFullscreen) + mActionBar.hide(); + else + mActionBar.show(); + } + + public void addPortalHighlighter(String name) { + mHighlighters.add(name); + + if (name.equals(mActiveHighlighter)) + setActiveHighlighter(name); + + updateActionBar(); + } + + public boolean hideInFullscreen() { + return mHideInFullscreen; + } + + @Override + public boolean onNavigationItemSelected(int position, long itemId) { + String name = mHighlighters.getItem(position); + mIitc.getWebView().loadUrl("javascript: window.changePortalHighlights('" + name + "')"); + return true; + } + + public void onPrefChanged() { + mDesktopMode = mPrefs.getBoolean("pref_force_desktop", false); + mHideInFullscreen = mPrefs.getBoolean("pref_fullscreen_actionbar", false); + updateActionBar(); + } + + public void reset() { + mHighlighters.clear(); + mPane = android.R.id.home; + updateActionBar(); + } + + public void setActiveHighlighter(String name) { + mActiveHighlighter = name; + + if (mActionBar.getNavigationMode() == ActionBar.NAVIGATION_MODE_LIST) { + int position = mHighlighters.getPosition(mActiveHighlighter); + if (position >= 0 && position < mActionBar.getNavigationItemCount()) + mActionBar.setSelectedNavigationItem(position); + } + } + + public void setFullscreen(boolean fullscreen) { + mFullscreen = fullscreen; + if (mFullscreen && mHideInFullscreen) { + // show a toast with instructions to exit the fullscreen mode again + Toast.makeText(mIitc, "Press back button to exit fullscreen", Toast.LENGTH_SHORT).show(); + } + + updateActionBar(); + } + + public void switchTo(int button) { + mPane = button; + updateActionBar(); + } +} diff --git a/mobile/src/com/cradle/iitc_mobile/IITC_JSInterface.java b/mobile/src/com/cradle/iitc_mobile/IITC_JSInterface.java index e6a84364..cd3cbf94 100644 --- a/mobile/src/com/cradle/iitc_mobile/IITC_JSInterface.java +++ b/mobile/src/com/cradle/iitc_mobile/IITC_JSInterface.java @@ -1,10 +1,5 @@ package com.cradle.iitc_mobile; -import java.util.HashMap; - -import org.json.JSONArray; -import org.json.JSONException; - import android.app.Activity; import android.app.AlertDialog; import android.content.ClipData; @@ -25,6 +20,11 @@ import android.widget.Toast; import com.cradle.iitc_mobile.share.ShareActivity; +import org.json.JSONArray; +import org.json.JSONException; + +import java.util.HashMap; + // provide communication between IITC script and android app public class IITC_JSInterface { @@ -96,46 +96,20 @@ public class IITC_JSInterface { } @JavascriptInterface - public void switchToPane(String id) { - + public void switchToPane(final String id) { final IITC_Mobile iitcm = (IITC_Mobile) mContext; - final int button_id; - final String title; - if (id.equals("map")) { - button_id = android.R.id.home; - title = iitcm.getString(R.string.app_name); - } else if (id.equals("info")) { - button_id = R.id.menu_info; - title = "Info"; - } else if (id.equals("full")) { - button_id = R.id.menu_full; - title = "Full"; - } else if (id.equals("compact")) { - button_id = R.id.menu_compact; - title = "Compact"; - } else if (id.equals("public")) { - button_id = R.id.menu_public; - title = "Public"; - } else if (id.equals("faction")) { - button_id = R.id.menu_faction; - title = "Faction"; - } else if (id.equals("debug")) { - button_id = R.id.menu_debug; - title = "Debug"; - } - // default - else { - button_id = android.R.id.home; - title = iitcm.getString(R.string.app_name); - } - - Log.d("iitcm", "switch to pane " + id); iitcm.runOnUiThread(new Runnable() { @Override public void run() { - iitcm.getActionBar().setTitle(title); - iitcm.backStackUpdate(button_id); + IITC_ActionBarHelper actionbar = iitcm.getActionBarHelper(); + Integer button = IITC_Mobile.PANES.get(id); + + if (button == null) + button = android.R.id.home; + + actionbar.switchTo(button); + iitcm.backStackUpdate(button); } }); } @@ -169,10 +143,10 @@ public class IITC_JSInterface { public void setLayers(String base_layer, String overlay_layer) { /* - * the layer strings have a form like: - * [{"layerId":27,"name":"MapQuest OSM","active":true}, - * {"layerId":28,"name":"Default Ingress Map","active":false}] - * Put it in a JSONArray and parse it + * the layer strings have a form like: + * [{"layerId":27,"name":"MapQuest OSM","active":true}, + * {"layerId":28,"name":"Default Ingress Map","active":false}] + * Put it in a JSONArray and parse it */ JSONArray base_layersJSON = null; JSONArray overlay_layersJSON = null; @@ -256,6 +230,28 @@ public class IITC_JSInterface { showMultiSelection(); } + @JavascriptInterface + public void addPortalHighlighter(final String name) { + final IITC_Mobile iitc = ((IITC_Mobile) mContext); + iitc.runOnUiThread(new Runnable() { + @Override + public void run() { + iitc.getActionBarHelper().addPortalHighlighter(name); + } + }); + } + + @JavascriptInterface + public void setActiveHighlighter(final String name) { + final IITC_Mobile iitc = ((IITC_Mobile) mContext); + iitc.runOnUiThread(new Runnable() { + @Override + public void run() { + iitc.getActionBarHelper().setActiveHighlighter(name); + } + }); + } + // show all overlay layers in a multi selection list dialog private void showMultiSelection() { // build the layer chooser dialog @@ -287,6 +283,7 @@ public class IITC_JSInterface { final ListView list = dialog.getListView(); list.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { boolean disable = false; + @Override public boolean onItemLongClick(AdapterView adapterView, View view, int i, long l) { int j = 0; diff --git a/mobile/src/com/cradle/iitc_mobile/IITC_Mobile.java b/mobile/src/com/cradle/iitc_mobile/IITC_Mobile.java index 93c246cc..b8d84c83 100644 --- a/mobile/src/com/cradle/iitc_mobile/IITC_Mobile.java +++ b/mobile/src/com/cradle/iitc_mobile/IITC_Mobile.java @@ -13,14 +13,12 @@ import android.content.res.Configuration; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; -import android.net.ConnectivityManager; -import android.net.NetworkInfo; import android.net.Uri; -import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.preference.PreferenceManager; import android.util.Log; +import android.util.SparseArray; import android.view.Menu; import android.view.MenuItem; import android.view.View; @@ -35,6 +33,7 @@ import android.widget.Toast; import java.io.IOException; import java.net.URISyntaxException; import java.util.ArrayList; +import java.util.HashMap; public class IITC_Mobile extends Activity { @@ -48,8 +47,6 @@ public class IITC_Mobile extends Activity { private LocationManager mLocMngr = null; private LocationListener mLocListener = null; private boolean mFullscreenMode = false; - private boolean mFullscreenActionbar = false; - private ActionBar mActionBar; private IITC_DeviceAccountLogin mLogin; private MenuItem mSearchMenuItem; private boolean mDesktopMode = false; @@ -57,6 +54,7 @@ public class IITC_Mobile extends Activity { private boolean mReloadNeeded = false; private final ArrayList mDialogStack = new ArrayList(); private SharedPreferences mSharedPrefs; + private IITC_ActionBarHelper mActionBarHelper; // Used for custom back stack handling private final ArrayList mBackStack = new ArrayList(); @@ -64,6 +62,27 @@ public class IITC_Mobile extends Activity { private int mCurrentPane = android.R.id.home; private boolean mBackButtonPressed = false; + public static final SparseArray PANE_TITLES = new SparseArray(); + public static final HashMap PANES = new HashMap(); + + static { + PANES.put("map", android.R.id.home); + PANES.put("info", R.id.menu_info); + PANES.put("full", R.id.menu_full); + PANES.put("compact", R.id.menu_compact); + PANES.put("public", R.id.menu_public); + PANES.put("faction", R.id.menu_faction); + PANES.put("debug", R.id.menu_debug); + + // No need to declare android.R.id.home - that title is default + PANE_TITLES.append(R.id.menu_info, "Info"); + PANE_TITLES.append(R.id.menu_full, "Full"); + PANE_TITLES.append(R.id.menu_compact, "Compact"); + PANE_TITLES.append(R.id.menu_public, "Public"); + PANE_TITLES.append(R.id.menu_faction, "Faction"); + PANE_TITLES.append(R.id.menu_debug, "Debug"); + } + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -74,38 +93,25 @@ public class IITC_Mobile extends Activity { setContentView(R.layout.activity_main); mIitcWebView = (IITC_WebView) findViewById(R.id.iitc_webview); - // fetch actionbar, set display flags, title and enable home button - mActionBar = this.getActionBar(); - mActionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_HOME - | ActionBar.DISPLAY_USE_LOGO | ActionBar.DISPLAY_SHOW_TITLE); - mActionBar.setTitle(getString(R.string.app_name)); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) - mActionBar.setHomeButtonEnabled(true); + // pass ActionBar to helper because we deprecated getActionBar + mActionBarHelper = new IITC_ActionBarHelper(this, super.getActionBar()); // do something if user changed something in the settings - mSharedPrefs = PreferenceManager - .getDefaultSharedPreferences(this); + mSharedPrefs = PreferenceManager.getDefaultSharedPreferences(this); mSharedPrefChangeListener = new OnSharedPreferenceChangeListener() { @Override public void onSharedPreferenceChanged( SharedPreferences sharedPreferences, String key) { if (key.equals("pref_force_desktop")) { mDesktopMode = sharedPreferences.getBoolean("pref_force_desktop", false); - if (mDesktopMode) { - setActionBarHomeEnabledWithUp(false); - mActionBar.setTitle(getString(R.string.app_name)); - } else mActionBar.setHomeButtonEnabled(true); + mActionBarHelper.onPrefChanged(); invalidateOptionsMenu(); } if (key.equals("pref_user_loc")) mIsLocEnabled = sharedPreferences.getBoolean("pref_user_loc", false); if (key.equals("pref_fullscreen_actionbar")) { - mFullscreenActionbar = sharedPreferences.getBoolean("pref_fullscreen_actionbar", - false); - if (mFullscreenMode) - IITC_Mobile.this.getActionBar().hide(); - // no iitc reload needed here + mActionBarHelper.onPrefChanged(); return; } if (key.equals("pref_advanced_menu")) { @@ -142,8 +148,7 @@ public class IITC_Mobile extends Activity { mLastLocation = location; } - public void onStatusChanged(String provider, int status, - Bundle extras) { + public void onStatusChanged(String provider, int status, Bundle extras) { } public void onProviderEnabled(String provider) { @@ -163,11 +168,8 @@ public class IITC_Mobile extends Activity { mLocListener); } - mFullscreenActionbar = mSharedPrefs.getBoolean("pref_fullscreen_actionbar", false); - // Clear the back stack mBackStack.clear(); - setActionBarHomeEnabledWithUp(false); handleIntent(getIntent(), true); } @@ -222,7 +224,7 @@ public class IITC_Mobile extends Activity { (SearchView) mSearchMenuItem.getActionView(); searchView.setQuery(query, false); searchView.clearFocus(); - mActionBar.setTitle(getString(R.string.app_name)); + mActionBarHelper.switchTo(android.R.id.home); backStackUpdate(android.R.id.home); mIitcWebView.loadUrl("javascript:search('" + query + "');"); return; @@ -252,17 +254,13 @@ public class IITC_Mobile extends Activity { throw use; } - if (parts.length > 1) // query string present - { + if (parts.length > 1) { // query string present // search for z= for (String param : parts[1].split("&")) { - if (param.startsWith("z=")) - { - try - { + if (param.startsWith("z=")) { + try { z = Integer.valueOf(param.substring(2)); - } catch (NumberFormatException e) - { + } catch (NumberFormatException e) { URISyntaxException use = new URISyntaxException(uri.toString(), "could not parse zoom level"); use.initCause(e); throw use; @@ -283,61 +281,32 @@ public class IITC_Mobile extends Activity { super.onResume(); // enough idle...let's do some work - Log.d("iitcm", "resuming...setting reset idleTimer"); - mIitcWebView.loadUrl("javascript: window.idleTime = 0"); + Log.d("iitcm", "resuming...reset idleTimer"); mIitcWebView.updateCaching(); if (mIsLocEnabled) { // Register the mSharedPrefChangeListener with the Location Manager to receive // location updates - mLocMngr.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, - 0, 0, mLocListener); - mLocMngr.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, - mLocListener); + mLocMngr.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, mLocListener); + mLocMngr.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mLocListener); } if (mReloadNeeded) { Log.d("iitcm", "preference had changed...reload needed"); - this.loadUrl(mIntelUrl); - mReloadNeeded = false; + reloadIITC(); + } + else { + // iitc is not fully booted...timer will be reset by the script itself + if (findViewById(R.id.imageLoading).getVisibility() == View.GONE) { + mIitcWebView.loadUrl("javascript: window.idleReset();"); + } } } @Override protected void onStop() { - ConnectivityManager conMan = - (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); - - NetworkInfo mobile = conMan - .getNetworkInfo(ConnectivityManager.TYPE_MOBILE); - NetworkInfo wifi = conMan.getNetworkInfo(ConnectivityManager.TYPE_WIFI); - - // check if Mobile or Wifi module is available..then handle states - // TODO: theory...we do not have to check for a Wifi module...every - // android device should have one - if (mobile != null) { - Log.d("iitcm", "mobile internet module detected...check states"); - if (mobile.getState() == NetworkInfo.State.CONNECTED - || mobile.getState() == NetworkInfo.State.CONNECTING) { - Log.d("iitcm", - "connected to mobile net...abort all running requests"); - // cancel all current requests - mIitcWebView.loadUrl("javascript: window.requests.abort()"); - // set idletime to maximum...no need for more - mIitcWebView.loadUrl("javascript: window.idleTime = 999"); - } else if (wifi.getState() == NetworkInfo.State.CONNECTED - || wifi.getState() == NetworkInfo.State.CONNECTING) { - mIitcWebView.loadUrl("javascript: window.idleTime = 999"); - } - } else { - Log.d("iitcm", - "no mobile internet module detected...check wifi state"); - if (wifi.getState() == NetworkInfo.State.CONNECTED - || wifi.getState() == NetworkInfo.State.CONNECTING) { - mIitcWebView.loadUrl("javascript: window.idleTime = 999"); - } - } Log.d("iitcm", "stopping iitcm"); + mIitcWebView.loadUrl("javascript: window.idleSet();"); if (mIsLocEnabled) mLocMngr.removeUpdates(mLocListener); @@ -369,7 +338,7 @@ public class IITC_Mobile extends Activity { } // exit fullscreen mode if it is enabled and action bar is disabled // or the back stack is empty - if (mFullscreenMode && (mBackStack.isEmpty() || mFullscreenActionbar)) { + if (mFullscreenMode && (mBackStack.isEmpty() || mActionBarHelper.hideInFullscreen())) { this.toggleFullscreen(); } else if (!mBackStack.isEmpty()) { // Pop last item from backstack and pretend the relevant menu item was clicked @@ -391,19 +360,12 @@ public class IITC_Mobile extends Activity { } } - private void setActionBarHomeEnabledWithUp(boolean enabled) { - mActionBar.setDisplayHomeAsUpEnabled(enabled); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) - mActionBar.setHomeButtonEnabled(enabled); - } - public void backStackPop() { // shouldn't be called when back stack is empty // catch wrong usage if (mBackStack.isEmpty()) { // Empty back stack means we should be at home (ie map) screen - setActionBarHomeEnabledWithUp(false); - mActionBar.setTitle(getString(R.string.app_name)); + mActionBarHelper.switchTo(android.R.id.home); mIitcWebView.loadUrl("javascript: window.show('map');"); return; } @@ -427,13 +389,6 @@ public class IITC_Mobile extends Activity { } mCurrentPane = itemId; - if (mBackStack.size() >= 1) { - setActionBarHomeEnabledWithUp(true); - } else { - // if we popped our last item from stack...illustrate it on home button - // Empty back stack means we should be at home (ie map) screen - setActionBarHomeEnabledWithUp(false); - } } @Override @@ -480,14 +435,13 @@ public class IITC_Mobile extends Activity { // the getLayers function calls the setLayers method of IITC_JSInterface mIitcWebView.loadUrl("javascript: window.layerChooser.getLayers()"); return true; - // get the users current location and focus it on map - case R.id.locate: + case R.id.locate: // get the users current location and focus it on map mIitcWebView.loadUrl("javascript: window.show('map');"); // get location from network by default if (!mIsLocEnabled) { mIitcWebView.loadUrl("javascript: " + "window.map.locate({setView : true, maxZoom: 15});"); - // if gps location is displayed we can use a better location without any costs + // if gps location is displayed we can use a better location without any costs } else { if (mLastLocation != null) mIitcWebView.loadUrl("javascript: window.map.setView(new L.LatLng(" + @@ -495,8 +449,7 @@ public class IITC_Mobile extends Activity { mLastLocation.getLongitude() + "), 15);"); } return true; - // start settings activity - case R.id.action_settings: + case R.id.action_settings: // start settings activity Intent intent = new Intent(this, IITC_PreferenceActivity.class); intent.putExtra("iitc_version", mIitcWebView.getWebViewClient() .getIITCVersion()); @@ -530,12 +483,12 @@ public class IITC_Mobile extends Activity { } public void reloadIITC() { - mActionBar.setTitle(getString(R.string.app_name)); + mActionBarHelper.reset(); mBackStack.clear(); - setActionBarHomeEnabledWithUp(false); // iitc starts on map after reload mCurrentPane = android.R.id.home; - this.loadUrl(mIntelUrl); + loadUrl(mIntelUrl); + mReloadNeeded = false; } private void loadIITC() { @@ -580,19 +533,9 @@ public class IITC_Mobile extends Activity { } public void toggleFullscreen() { - if (mFullscreenMode) { - if (mFullscreenActionbar) - this.getActionBar().show(); - this.mFullscreenMode = false; - } else { - if (mFullscreenActionbar) { - this.getActionBar().hide(); - // show a toast with instructions to exit the fc mode again - Toast.makeText(this, "Press back button to exit fullscreen", - Toast.LENGTH_SHORT).show(); - } - this.mFullscreenMode = true; - } + mFullscreenMode = !mFullscreenMode; + mActionBarHelper.setFullscreen(mFullscreenMode); + // toggle notification bar WindowManager.LayoutParams attrs = getWindow().getAttributes(); attrs.flags ^= WindowManager.LayoutParams.FLAG_FULLSCREEN; @@ -628,7 +571,7 @@ public class IITC_Mobile extends Activity { * called by IITC_WebViewClient when the Google login form is opened. */ public void onReceivedLoginRequest(IITC_WebViewClient client, WebView view, - String realm, String account, String args) { + String realm, String account, String args) { Log.d("iitcm", "logging in...set caching mode to default"); mIitcWebView.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT); mLogin = new IITC_DeviceAccountLogin(this, view, client); @@ -689,4 +632,17 @@ public class IITC_Mobile extends Activity { item = menu.findItem(R.id.menu_clear_cookies); item.setVisible(mAdvancedMenu); } + + /** + * @deprecated ActionBar related stuff should be handled by ActionBarHelper + */ + @Deprecated + @Override + public ActionBar getActionBar() { + return super.getActionBar(); + } + + public IITC_ActionBarHelper getActionBarHelper() { + return mActionBarHelper; + } } diff --git a/mobile/src/com/cradle/iitc_mobile/IITC_PluginPreferenceActivity.java b/mobile/src/com/cradle/iitc_mobile/IITC_PluginPreferenceActivity.java index d05562cc..610e08d7 100644 --- a/mobile/src/com/cradle/iitc_mobile/IITC_PluginPreferenceActivity.java +++ b/mobile/src/com/cradle/iitc_mobile/IITC_PluginPreferenceActivity.java @@ -1,6 +1,5 @@ package com.cradle.iitc_mobile; -import android.app.ActionBar; import android.content.Context; import android.content.res.AssetManager; import android.os.Bundle; @@ -43,9 +42,8 @@ public class IITC_PluginPreferenceActivity extends PreferenceActivity { @Override public void onBuildHeaders(List
target) { - ActionBar bar = getActionBar(); - bar.setTitle("IITC Plugins"); - bar.setDisplayHomeAsUpEnabled(true); + getActionBar().setDisplayHomeAsUpEnabled(true); + mHeaders = target; // since the plugins container is static, // it is enough to parse the plugin only on first start. @@ -62,8 +60,7 @@ public class IITC_PluginPreferenceActivity extends PreferenceActivity { @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { - // exit settings when home button (iitc icon) is pressed - case android.R.id.home: + case android.R.id.home: // exit settings when home button (iitc icon) is pressed onBackPressed(); return true; default: @@ -157,8 +154,7 @@ public class IITC_PluginPreferenceActivity extends PreferenceActivity { } } - void addPluginPreference(String src, String plugin_key, - boolean user) { + void addPluginPreference(String src, String plugin_key, boolean user) { // now parse plugin name, description and category String header = src.substring(src.indexOf("==UserScript=="), @@ -186,8 +182,14 @@ public class IITC_PluginPreferenceActivity extends PreferenceActivity { plugin_name = plugin_name.replace("IITC plugin: ", ""); // add [User] tag to user plugins - if (user) + if (user) { plugin_cat = USER_PLUGIN + plugin_cat; + } + + // do not add deleted plugins + if (plugin_cat.equals("Deleted")) { + return; + } // now we have all stuff together and can build the preference // first check if we need a new category @@ -306,20 +308,20 @@ public class IITC_PluginPreferenceActivity extends PreferenceActivity { if (convertView == null) { holder = new HeaderViewHolder(); switch (headerType) { - case HEADER_TYPE_CATEGORY: - view = new TextView(getContext(), null, - android.R.attr.listSeparatorTextViewStyle); - holder.title = (TextView) view; - break; + case HEADER_TYPE_CATEGORY: + view = new TextView(getContext(), null, + android.R.attr.listSeparatorTextViewStyle); + holder.title = (TextView) view; + break; - case HEADER_TYPE_NORMAL: - view = mInflater.inflate(R.layout.preference_header_item, - parent, false); - holder.title = (TextView) view - .findViewById(R.id.plug_pref_title); - holder.summary = (TextView) view - .findViewById(R.id.plug_pref_summary); - break; + case HEADER_TYPE_NORMAL: + view = mInflater.inflate(R.layout.preference_header_item, + parent, false); + holder.title = (TextView) view + .findViewById(R.id.plug_pref_title); + holder.summary = (TextView) view + .findViewById(R.id.plug_pref_summary); + break; } view.setTag(holder); } else { @@ -330,22 +332,22 @@ public class IITC_PluginPreferenceActivity extends PreferenceActivity { // All view fields must be updated every time, because the view may // be recycled switch (headerType) { - case HEADER_TYPE_CATEGORY: - holder.title.setText(header.getTitle(getContext() - .getResources())); - break; - case HEADER_TYPE_NORMAL: - holder.title.setText(header.getTitle(getContext() - .getResources())); - CharSequence summary = header.getSummary(getContext() - .getResources()); - if (!TextUtils.isEmpty(summary)) { - holder.summary.setVisibility(View.VISIBLE); - holder.summary.setText(summary); - } else { - holder.summary.setVisibility(View.GONE); - } - break; + case HEADER_TYPE_CATEGORY: + holder.title.setText(header.getTitle(getContext() + .getResources())); + break; + case HEADER_TYPE_NORMAL: + holder.title.setText(header.getTitle(getContext() + .getResources())); + CharSequence summary = header.getSummary(getContext() + .getResources()); + if (!TextUtils.isEmpty(summary)) { + holder.summary.setVisibility(View.VISIBLE); + holder.summary.setText(summary); + } else { + holder.summary.setVisibility(View.GONE); + } + break; } return view; diff --git a/mobile/src/com/cradle/iitc_mobile/IITC_PreferenceActivity.java b/mobile/src/com/cradle/iitc_mobile/IITC_PreferenceActivity.java index ad222eff..2595d41b 100644 --- a/mobile/src/com/cradle/iitc_mobile/IITC_PreferenceActivity.java +++ b/mobile/src/com/cradle/iitc_mobile/IITC_PreferenceActivity.java @@ -14,8 +14,6 @@ public class IITC_PreferenceActivity extends Activity { MainSettings settings = new MainSettings(); - // set action bar title - getActionBar().setTitle("IITC Mobile Settings"); getActionBar().setHomeButtonEnabled(true); // iitc version @@ -23,15 +21,16 @@ public class IITC_PreferenceActivity extends Activity { settings.setArguments(bundle); // Display the fragment as the main content. - getFragmentManager().beginTransaction() - .replace(android.R.id.content, settings).commit(); + getFragmentManager() + .beginTransaction() + .replace(android.R.id.content, settings) + .commit(); } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { - // exit settings when home button (iitc icon) is pressed - case android.R.id.home: + case android.R.id.home: // exit settings when home button (iitc icon) is pressed onBackPressed(); return true; default: diff --git a/mobile/src/com/cradle/iitc_mobile/async/CheckHttpResponse.java b/mobile/src/com/cradle/iitc_mobile/async/CheckHttpResponse.java index 861677c3..e7df6056 100644 --- a/mobile/src/com/cradle/iitc_mobile/async/CheckHttpResponse.java +++ b/mobile/src/com/cradle/iitc_mobile/async/CheckHttpResponse.java @@ -8,7 +8,6 @@ import android.util.Log; import com.cradle.iitc_mobile.IITC_JSInterface; import com.cradle.iitc_mobile.IITC_Mobile; -import com.cradle.iitc_mobile.IITC_WebView; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; diff --git a/mobile/src/com/cradle/iitc_mobile/share/IntentFragment.java b/mobile/src/com/cradle/iitc_mobile/share/IntentFragment.java index 2d8b3780..b1b15682 100644 --- a/mobile/src/com/cradle/iitc_mobile/share/IntentFragment.java +++ b/mobile/src/com/cradle/iitc_mobile/share/IntentFragment.java @@ -42,8 +42,7 @@ public class IntentFragment extends Fragment implements OnScrollListener, OnItem } @Override - public void onItemClick(AdapterView parent, View view, int position, long id) - { + public void onItemClick(AdapterView parent, View view, int position, long id) { Intent intent = mListView.getTargetIntent(position); startActivity(intent); } diff --git a/mobile/src/com/cradle/iitc_mobile/share/IntentFragmentAdapter.java b/mobile/src/com/cradle/iitc_mobile/share/IntentFragmentAdapter.java index 1460348c..68743a08 100644 --- a/mobile/src/com/cradle/iitc_mobile/share/IntentFragmentAdapter.java +++ b/mobile/src/com/cradle/iitc_mobile/share/IntentFragmentAdapter.java @@ -1,12 +1,12 @@ package com.cradle.iitc_mobile.share; -import java.util.ArrayList; -import java.util.List; - import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentPagerAdapter; +import java.util.ArrayList; +import java.util.List; + public class IntentFragmentAdapter extends FragmentPagerAdapter { private List mTabs; diff --git a/mobile/src/com/cradle/iitc_mobile/share/IntentListView.java b/mobile/src/com/cradle/iitc_mobile/share/IntentListView.java index 669e8fa3..d0a72cc6 100644 --- a/mobile/src/com/cradle/iitc_mobile/share/IntentListView.java +++ b/mobile/src/com/cradle/iitc_mobile/share/IntentListView.java @@ -1,10 +1,5 @@ package com.cradle.iitc_mobile.share; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; - import android.app.Activity; import android.content.ComponentName; import android.content.Context; @@ -24,6 +19,11 @@ import android.widget.TextView; import com.cradle.iitc_mobile.R; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; + public class IntentListView extends ListView { private static class CopyHandler extends Pair { public CopyHandler(ResolveInfo resolveInfo) { @@ -35,10 +35,8 @@ public class IntentListView extends ListView { } } - private class IntentAdapter extends ArrayAdapter - { - private IntentAdapter() - { + private class IntentAdapter extends ArrayAdapter { + private IntentAdapter() { super(IntentListView.this.getContext(), android.R.layout.simple_list_item_1); } @@ -126,8 +124,7 @@ public class IntentListView extends ListView { setIntents(intentList); } - public void setIntents(ArrayList intents) - { + public void setIntents(ArrayList intents) { mAdapter.setNotifyOnChange(false); mAdapter.clear(); @@ -154,10 +151,8 @@ public class IntentListView extends ListView { ActivityInfo activity = info.activityInfo; // remove all IITCm intents, except for SendToClipboard in case Drive is not installed - if (activity.packageName.equals(packageName)) - { - if (hasCopyIntent || !activity.name.equals(SendToClipboard.class.getCanonicalName())) - { + if (activity.packageName.equals(packageName)) { + if (hasCopyIntent || !activity.name.equals(SendToClipboard.class.getCanonicalName())) { activityList.remove(i); i--; continue; diff --git a/mobile/src/com/cradle/iitc_mobile/share/SendToClipboard.java b/mobile/src/com/cradle/iitc_mobile/share/SendToClipboard.java index 2f9b332f..3134452e 100644 --- a/mobile/src/com/cradle/iitc_mobile/share/SendToClipboard.java +++ b/mobile/src/com/cradle/iitc_mobile/share/SendToClipboard.java @@ -7,6 +7,7 @@ import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.widget.Toast; + import com.cradle.iitc_mobile.R; public class SendToClipboard extends Activity { diff --git a/mobile/src/com/cradle/iitc_mobile/share/ShareActivity.java b/mobile/src/com/cradle/iitc_mobile/share/ShareActivity.java index fdf6eb4f..71200af3 100644 --- a/mobile/src/com/cradle/iitc_mobile/share/ShareActivity.java +++ b/mobile/src/com/cradle/iitc_mobile/share/ShareActivity.java @@ -16,7 +16,6 @@ import com.cradle.iitc_mobile.R; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; -import java.text.DecimalFormatSymbols; import java.util.ArrayList; public class ShareActivity extends FragmentActivity implements ActionBar.TabListener { @@ -28,15 +27,7 @@ public class ShareActivity extends FragmentActivity implements ActionBar.TabList IntentFragmentAdapter mFragmentAdapter; ViewPager mViewPager; - private void addTab(Intent intent, int label, int icon) - { - ArrayList intents = new ArrayList(1); - intents.add(intent); - addTab(intents, label, icon); - } - - private void addTab(ArrayList intents, int label, int icon) - { + private void addTab(ArrayList intents, int label, int icon) { IntentFragment fragment = new IntentFragment(); Bundle args = new Bundle(); args.putParcelableArrayList("intents", intents); @@ -46,6 +37,12 @@ public class ShareActivity extends FragmentActivity implements ActionBar.TabList mFragmentAdapter.add(fragment); } + private void addTab(Intent intent, int label, int icon) { + ArrayList intents = new ArrayList(1); + intents.add(intent); + addTab(intents, label, icon); + } + private String getUrl() { String url = "http://www.ingress.com/intel?ll=" + mLl + "&z=" + mZoom; if (mIsPortal) @@ -64,15 +61,6 @@ public class ShareActivity extends FragmentActivity implements ActionBar.TabList .apply(); } - private void setupShareIntent(String str) { - Intent intent = new Intent(Intent.ACTION_SEND); - intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); - intent.setType("text/plain"); - intent.putExtra(Intent.EXTRA_TEXT, str); - intent.putExtra(Intent.EXTRA_SUBJECT, mTitle); - addTab(intent, R.string.tab_share, R.drawable.share); - } - private void setupIntents() { setupShareIntent(getUrl()); @@ -98,6 +86,15 @@ public class ShareActivity extends FragmentActivity implements ActionBar.TabList addTab(intent, R.string.tab_browser, R.drawable.browser); } + private void setupShareIntent(String str) { + Intent intent = new Intent(Intent.ACTION_SEND); + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); + intent.setType("text/plain"); + intent.putExtra(Intent.EXTRA_TEXT, str); + intent.putExtra(Intent.EXTRA_SUBJECT, mTitle); + addTab(intent, R.string.tab_share, R.drawable.share); + } + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -146,8 +143,7 @@ public class ShareActivity extends FragmentActivity implements ActionBar.TabList mSharedPrefs = PreferenceManager.getDefaultSharedPreferences(this); int selected = mSharedPrefs.getInt("pref_share_selected_tab", 0); - if (selected < mFragmentAdapter.getCount()) - { + if (selected < mFragmentAdapter.getCount()) { mViewPager.setCurrentItem(selected); actionBar.setSelectedNavigationItem(selected); } diff --git a/plugins/layer-farms-find.user.js b/plugins/layer-farms-find.user.js index d2b80044..bd1ec897 100644 --- a/plugins/layer-farms-find.user.js +++ b/plugins/layer-farms-find.user.js @@ -340,13 +340,6 @@ var setup = function() { possibleFarmPortals = []; window.plugin.farmFind.levelLayerGroup = new L.LayerGroup(); $('body').append(''); - // notify android that the select spinner is enabled. - // this disables javascript injection on android side. - // if android is not notified, the spinner closes on the next JS call - if (typeof android !== 'undefined' && android && android.spinnerEnabled) { - $("#farm_level_select").click(function(){ android.spinnerEnabled(true);}); - $("#farm_level_select").focus(function(){ android.spinnerEnabled(false);}); - } var myselect = document.getElementById("farm_level_select"); myselect.options.selectedIndex = 6; window.addLayerGroup('Farms', window.plugin.farmFind.levelLayerGroup, true); diff --git a/website/page/faq.php b/website/page/faq.php index 3f63258e..f32d4843 100644 --- a/website/page/faq.php +++ b/website/page/faq.php @@ -64,6 +64,24 @@ This depends on your browser. From here you can remove/disable individual plugins or IITC itself. +
  • +

    Is it possible to add external plugins to IITC Mobile?

    +Yes it is! +
      +
    • Create a folder named "IITC Mobile" in your home directory.
    • +
    • Inside this folder, create a new folder named "plugins".
    • +
    • Copy all your additional plugins to this folder.
    • +
    • You should see your plugins listed above the official plugins.
    • +
    +Note: +
      +
    • The plugins wrapper function has to be identical to all other IITC plugins (IITCm removes it via search and replace). + Alternatively, you can use the @@PLUGINSTART@@ / @@PLUGINEND@@ macros or remove the wrapper by hand.
    • +
    • The filename has to end with *.user.js.
    • +
    • If you don't know where to find your home directory: Enable dev-mode in the settings and follow the hint.
    • +
    +
  • +
  • What do the colours mean in 'DEBUG Data Tiles'

    The data from the Niantic server is download in square tiles. Sometimes requests fail. The colours show this status