diff options
Diffstat (limited to 'main/src/cgeo/geocaching/activity')
8 files changed, 445 insertions, 49 deletions
diff --git a/main/src/cgeo/geocaching/activity/AbstractActivity.java b/main/src/cgeo/geocaching/activity/AbstractActivity.java index cc9931a..6ceead0 100644 --- a/main/src/cgeo/geocaching/activity/AbstractActivity.java +++ b/main/src/cgeo/geocaching/activity/AbstractActivity.java @@ -3,7 +3,10 @@ package cgeo.geocaching.activity; import butterknife.ButterKnife; import cgeo.geocaching.CgeoApplication; +import cgeo.geocaching.Geocache; import cgeo.geocaching.R; +import cgeo.geocaching.enumerations.CacheType; +import cgeo.geocaching.network.AndroidBeam; import cgeo.geocaching.network.Cookies; import cgeo.geocaching.settings.Settings; import cgeo.geocaching.utils.ClipboardUtils; @@ -13,18 +16,13 @@ import cgeo.geocaching.utils.TranslationUtils; import org.apache.commons.lang3.StringUtils; import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; import rx.Subscription; import rx.subscriptions.Subscriptions; -import android.annotation.TargetApi; import android.content.Intent; import android.content.res.Resources; -import android.nfc.NdefMessage; -import android.nfc.NdefRecord; -import android.nfc.NfcAdapter; -import android.nfc.NfcEvent; -import android.os.Build; import android.os.Bundle; import android.support.v7.app.ActionBarActivity; import android.support.v7.view.ActionMode; @@ -75,6 +73,7 @@ public abstract class AbstractActivity extends ActionBarActivity implements IAbs supportRequestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); initializeCommonFields(); + AndroidBeam.disable(this); } @Override @@ -96,9 +95,9 @@ public abstract class AbstractActivity extends ActionBarActivity implements IAbs return super.onOptionsItemSelected(item); } - public void onResume(final Subscription resumeSubscription) { + public void onResume(final Subscription... resumeSubscriptions) { super.onResume(); - this.resumeSubscription = resumeSubscription; + this.resumeSubscription = Subscriptions.from(resumeSubscriptions); } @Override @@ -203,34 +202,21 @@ public abstract class AbstractActivity extends ActionBarActivity implements IAbs } } - // Do not support older devices than Android 4.0 - // Although there even are 2.3 devices (Nexus S) - // these are so few that we don't want to deal with the older (non Android Beam) API - - public interface ActivitySharingInterface { - /** Return an URL that represent the current activity for sharing or null for no sharing. */ - public String getAndroidBeamUri(); - } - - protected void initializeAndroidBeam(final ActivitySharingInterface sharingInterface) { - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.ICE_CREAM_SANDWICH) { - initializeICSAndroidBeam(sharingInterface); + protected void setCacheTitleBar(@Nullable final String geocode, @Nullable final String name, @Nullable final CacheType type) { + if (StringUtils.isNotBlank(name)) { + setTitle(StringUtils.isNotBlank(geocode) ? name + " (" + geocode + ")" : name); + } else { + setTitle(StringUtils.isNotBlank(geocode) ? geocode : res.getString(R.string.cache)); } - } - - @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) - protected void initializeICSAndroidBeam(final ActivitySharingInterface sharingInterface) { - final NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this); - if (nfcAdapter == null) { - return; + if (type != null) { + getSupportActionBar().setIcon(getResources().getDrawable(type.markerId)); + } else { + getSupportActionBar().setIcon(android.R.color.transparent); } - nfcAdapter.setNdefPushMessageCallback(new NfcAdapter.CreateNdefMessageCallback() { - @Override - public NdefMessage createNdefMessage(final NfcEvent event) { - final String uri = sharingInterface.getAndroidBeamUri(); - return uri != null ? new NdefMessage(new NdefRecord[]{NdefRecord.createUri(uri)}) : null; - } - }, this); + } + protected void setCacheTitleBar(final @NonNull Geocache cache) { + setCacheTitleBar(cache.getGeocode(), cache.getName(), cache.getType()); } + } diff --git a/main/src/cgeo/geocaching/activity/AbstractListActivity.java b/main/src/cgeo/geocaching/activity/AbstractListActivity.java index d7482c3..86ca98f 100644 --- a/main/src/cgeo/geocaching/activity/AbstractListActivity.java +++ b/main/src/cgeo/geocaching/activity/AbstractListActivity.java @@ -1,6 +1,7 @@ package cgeo.geocaching.activity; import cgeo.geocaching.CgeoApplication; +import cgeo.geocaching.network.AndroidBeam; import android.content.res.Resources; import android.os.Bundle; @@ -48,6 +49,7 @@ public abstract class AbstractListActivity extends ActionBarListActivity impleme initializeCommonFields(); initUpAction(); + AndroidBeam.disable(this); } protected void initUpAction() { diff --git a/main/src/cgeo/geocaching/activity/AbstractViewPagerActivity.java b/main/src/cgeo/geocaching/activity/AbstractViewPagerActivity.java index 64186a0..11a5436 100644 --- a/main/src/cgeo/geocaching/activity/AbstractViewPagerActivity.java +++ b/main/src/cgeo/geocaching/activity/AbstractViewPagerActivity.java @@ -68,14 +68,12 @@ public abstract class AbstractViewPagerActivity<Page extends Enum<Page>> extends /** * Returns a validated view. * - * @return */ public View getDispatchedView(final ViewGroup parentView); /** * Returns a (maybe cached) view. * - * @return */ public View getView(final ViewGroup parentView); diff --git a/main/src/cgeo/geocaching/activity/ActionBarListActivity.java b/main/src/cgeo/geocaching/activity/ActionBarListActivity.java index 07c7ec3..a2d3ddf 100644 --- a/main/src/cgeo/geocaching/activity/ActionBarListActivity.java +++ b/main/src/cgeo/geocaching/activity/ActionBarListActivity.java @@ -18,12 +18,12 @@ public class ActionBarListActivity extends ActionBarActivity { return mListView; } - protected void setListAdapter(ListAdapter adapter) { + protected void setListAdapter(final ListAdapter adapter) { getListView().setAdapter(adapter); } protected ListAdapter getListAdapter() { - ListAdapter adapter = getListView().getAdapter(); + final ListAdapter adapter = getListView().getAdapter(); if (adapter instanceof HeaderViewListAdapter) { return ((HeaderViewListAdapter)adapter).getWrappedAdapter(); } diff --git a/main/src/cgeo/geocaching/activity/ActivityMixin.java b/main/src/cgeo/geocaching/activity/ActivityMixin.java index 28042b0..01fc62e 100644 --- a/main/src/cgeo/geocaching/activity/ActivityMixin.java +++ b/main/src/cgeo/geocaching/activity/ActivityMixin.java @@ -1,11 +1,14 @@ package cgeo.geocaching.activity; +import cgeo.geocaching.CgeoApplication; +import cgeo.geocaching.MainActivity; import cgeo.geocaching.R; import cgeo.geocaching.settings.Settings; import org.apache.commons.lang3.StringUtils; import org.eclipse.jdt.annotation.NonNull; +import android.annotation.TargetApi; import android.app.Activity; import android.content.Intent; import android.os.Build.VERSION; @@ -111,10 +114,15 @@ public final class ActivityMixin { window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); } if (Settings.useHardwareAcceleration()) { - window.setFlags(LayoutParams.FLAG_HARDWARE_ACCELERATED, LayoutParams.FLAG_HARDWARE_ACCELERATED); + enableHardwareAcceleration(window); } } + @TargetApi(VERSION_CODES.HONEYCOMB) + private static void enableHardwareAcceleration(final Window window) { + window.addFlags(LayoutParams.FLAG_HARDWARE_ACCELERATED); + } + public static void invalidateOptionsMenu(final Activity activity) { if (activity instanceof ActionBarActivity) { ((ActionBarActivity) activity).supportInvalidateOptionsMenu(); @@ -127,8 +135,6 @@ public final class ActivityMixin { /** * insert text into the EditText at the current cursor position * - * @param editText - * @param insertText * @param moveCursor * place the cursor after the inserted text */ @@ -139,7 +145,7 @@ public final class ActivityMixin { final int end = Math.max(selectionStart, selectionEnd); final String content = editText.getText().toString(); - String completeText; + final String completeText; if (start > 0 && !Character.isWhitespace(content.charAt(start - 1))) { completeText = " " + insertText; } else { @@ -152,13 +158,18 @@ public final class ActivityMixin { } public static boolean navigateUp(@NonNull final Activity activity) { - // see http://developer.android.com/training/implementing-navigation/ancestral.html - final Intent upIntent = NavUtils.getParentActivityIntent(activity); - if (upIntent == null) { + // first check if there is a parent declared in the manifest + Intent upIntent = NavUtils.getParentActivityIntent(activity); + // if there is no parent, and if this was not a new task, then just go back to simulate going to a parent + if (upIntent == null && !activity.isTaskRoot()) { activity.finish(); return true; } - if (NavUtils.shouldUpRecreateTask(activity, upIntent)) { + // use the main activity, if there was no back stack and no manifest based parent + if (upIntent == null) { + upIntent = new Intent(CgeoApplication.getInstance(), MainActivity.class); + } + if (NavUtils.shouldUpRecreateTask(activity, upIntent) || activity.isTaskRoot()) { // This activity is NOT part of this app's task, so create a new task // when navigating up, with a synthesized back stack. TaskStackBuilder.create(activity) @@ -175,7 +186,7 @@ public final class ActivityMixin { } public static void presentShowcase(final IAbstractActivity activity) { - if (VERSION.SDK_INT < 11) { + if (VERSION.SDK_INT < 14) { return; } final ShowcaseViewBuilder builder = activity.getShowcase(); diff --git a/main/src/cgeo/geocaching/activity/OAuthAuthorizationActivity.java b/main/src/cgeo/geocaching/activity/OAuthAuthorizationActivity.java new file mode 100644 index 0000000..2dfac5b --- /dev/null +++ b/main/src/cgeo/geocaching/activity/OAuthAuthorizationActivity.java @@ -0,0 +1,400 @@ +package cgeo.geocaching.activity; + +import butterknife.InjectView; + +import cgeo.geocaching.Intents; +import cgeo.geocaching.R; +import cgeo.geocaching.network.Network; +import cgeo.geocaching.network.OAuth; +import cgeo.geocaching.network.OAuthTokens; +import cgeo.geocaching.network.Parameters; +import cgeo.geocaching.utils.BundleUtils; +import cgeo.geocaching.utils.Log; +import cgeo.geocaching.utils.MatcherWrapper; +import cgeo.geocaching.utils.RxUtils; + +import ch.boye.httpclientandroidlib.HttpResponse; +import ch.boye.httpclientandroidlib.ParseException; +import ch.boye.httpclientandroidlib.client.entity.UrlEncodedFormEntity; +import ch.boye.httpclientandroidlib.util.EntityUtils; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; + +import rx.functions.Action0; + +import android.app.ProgressDialog; +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.view.View; +import android.widget.Button; +import android.widget.TextView; + +import java.io.IOException; +import java.util.regex.Pattern; + +public abstract class OAuthAuthorizationActivity extends AbstractActivity { + + public static final int NOT_AUTHENTICATED = 0; + public static final int AUTHENTICATED = 1; + + private static final int STATUS_ERROR = 0; + private static final int STATUS_SUCCESS = 1; + private static final int STATUS_ERROR_EXT_MSG = 2; + private static final Pattern PARAMS_PATTERN_1 = Pattern.compile("oauth_token=([\\w_.-]+)"); + private static final Pattern PARAMS_PATTERN_2 = Pattern.compile("oauth_token_secret=([\\w_.-]+)"); + + @NonNull private String host = StringUtils.EMPTY; + @NonNull private String pathRequest = StringUtils.EMPTY; + @NonNull private String pathAuthorize = StringUtils.EMPTY; + @NonNull private String pathAccess = StringUtils.EMPTY; + private boolean https = false; + @NonNull private String consumerKey = StringUtils.EMPTY; + @NonNull private String consumerSecret = StringUtils.EMPTY; + @NonNull private String callback = StringUtils.EMPTY; + private String OAtoken = null; + private String OAtokenSecret = null; + @InjectView(R.id.start) protected Button startButton; + @InjectView(R.id.auth_1) protected TextView auth_1; + @InjectView(R.id.auth_2) protected TextView auth_2; + private ProgressDialog requestTokenDialog = null; + private ProgressDialog changeTokensDialog = null; + + private final Handler requestTokenHandler = new Handler() { + + @Override + public void handleMessage(final Message msg) { + if (requestTokenDialog != null && requestTokenDialog.isShowing()) { + requestTokenDialog.dismiss(); + } + + startButton.setOnClickListener(new StartListener()); + startButton.setEnabled(true); + + if (msg.what == STATUS_SUCCESS) { + startButton.setText(getAuthAgain()); + } else if (msg.what == STATUS_ERROR_EXT_MSG) { + String errMsg = getErrAuthInitialize(); + errMsg += msg.obj != null ? "\n" + msg.obj.toString() : ""; + showToast(errMsg); + startButton.setText(getAuthStart()); + } else { + showToast(getErrAuthInitialize()); + startButton.setText(getAuthStart()); + } + } + + }; + + private final Handler changeTokensHandler = new Handler() { + + @Override + public void handleMessage(final Message msg) { + if (changeTokensDialog != null && changeTokensDialog.isShowing()) { + changeTokensDialog.dismiss(); + } + + if (msg.what == AUTHENTICATED) { + showToast(getAuthDialogCompleted()); + setResult(RESULT_OK); + finish(); + } else { + showToast(getErrAuthProcess()); + startButton.setText(getAuthStart()); + } + } + }; + + @Override + public void onCreate(final Bundle savedInstanceState) { + super.onCreate(savedInstanceState, R.layout.authorization_activity); + + final Bundle extras = getIntent().getExtras(); + if (extras != null) { + host = BundleUtils.getString(extras, Intents.EXTRA_OAUTH_HOST, host); + pathRequest = BundleUtils.getString(extras, Intents.EXTRA_OAUTH_PATH_REQUEST, pathRequest); + pathAuthorize = BundleUtils.getString(extras, Intents.EXTRA_OAUTH_PATH_AUTHORIZE, pathAuthorize); + pathAccess = BundleUtils.getString(extras, Intents.EXTRA_OAUTH_PATH_ACCESS, pathAccess); + https = extras.getBoolean(Intents.EXTRA_OAUTH_HTTPS, https); + consumerKey = BundleUtils.getString(extras, Intents.EXTRA_OAUTH_CONSUMER_KEY, consumerKey); + consumerSecret = BundleUtils.getString(extras, Intents.EXTRA_OAUTH_CONSUMER_SECRET, consumerSecret); + callback = BundleUtils.getString(extras, Intents.EXTRA_OAUTH_CALLBACK, callback); + } + + setTitle(getAuthTitle()); + + auth_1.setText(getAuthExplainShort()); + auth_2.setText(getAuthExplainLong()); + + final ImmutablePair<String, String> tempToken = getTempTokens(); + OAtoken = tempToken.left; + OAtokenSecret = tempToken.right; + + startButton.setText(getAuthAuthorize()); + startButton.setEnabled(true); + startButton.setOnClickListener(new StartListener()); + + if (StringUtils.isBlank(OAtoken) && StringUtils.isBlank(OAtokenSecret)) { + // start authorization process + startButton.setText(getAuthStart()); + } else { + // already have temporary tokens, continue from pin + startButton.setText(getAuthAgain()); + } + } + + @Override + public void onNewIntent(final Intent intent) { + setIntent(intent); + } + + @Override + public void onResume() { + super.onResume(); + final Uri uri = getIntent().getData(); + if (uri != null) { + final String verifier = uri.getQueryParameter("oauth_verifier"); + if (StringUtils.isNotBlank(verifier)) { + exchangeTokens(verifier); + } else { + // We can shortcut the whole verification process if we do not have a token at all. + changeTokensHandler.sendEmptyMessage(NOT_AUTHENTICATED); + } + } + } + + private void requestToken() { + + final Parameters params = new Parameters(); + params.put("oauth_callback", callback); + final String method = "GET"; + OAuth.signOAuth(host, pathRequest, method, https, params, new OAuthTokens(null, null), consumerKey, consumerSecret); + final HttpResponse response = Network.getRequest(getUrlPrefix() + host + pathRequest, params); + + if (Network.isSuccess(response)) { + final String line = Network.getResponseData(response); + + int status = STATUS_ERROR; + if (StringUtils.isNotBlank(line)) { + assert line != null; + final MatcherWrapper paramsMatcher1 = new MatcherWrapper(PARAMS_PATTERN_1, line); + if (paramsMatcher1.find()) { + OAtoken = paramsMatcher1.group(1); + } + final MatcherWrapper paramsMatcher2 = new MatcherWrapper(PARAMS_PATTERN_2, line); + if (paramsMatcher2.find()) { + OAtokenSecret = paramsMatcher2.group(1); + } + + if (StringUtils.isNotBlank(OAtoken) && StringUtils.isNotBlank(OAtokenSecret)) { + setTempTokens(OAtoken, OAtokenSecret); + try { + final Parameters paramsBrowser = new Parameters(); + paramsBrowser.put("oauth_token", OAtoken); + final String encodedParams = EntityUtils.toString(new UrlEncodedFormEntity(paramsBrowser)); + startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(getUrlPrefix() + host + pathAuthorize + "?" + encodedParams))); + status = STATUS_SUCCESS; + } catch (ParseException | IOException e) { + Log.e("OAuthAuthorizationActivity.requestToken", e); + } + } + } + + requestTokenHandler.sendEmptyMessage(status); + } else { + final String extErrMsg = getExtendedErrorMsg(response); + if (StringUtils.isNotBlank(extErrMsg)) { + final Message msg = requestTokenHandler.obtainMessage(STATUS_ERROR_EXT_MSG, extErrMsg); + requestTokenHandler.sendMessage(msg); + } else { + requestTokenHandler.sendEmptyMessage(STATUS_ERROR); + } + } + } + + private void changeToken(final String verifier) { + + int status = NOT_AUTHENTICATED; + + try { + final Parameters params = new Parameters("oauth_verifier", verifier); + + final String method = "POST"; + OAuth.signOAuth(host, pathAccess, method, https, params, new OAuthTokens(OAtoken, OAtokenSecret), consumerKey, consumerSecret); + final String line = StringUtils.defaultString(Network.getResponseData(Network.postRequest(getUrlPrefix() + host + pathAccess, params))); + + OAtoken = ""; + OAtokenSecret = ""; + + final MatcherWrapper paramsMatcher1 = new MatcherWrapper(PARAMS_PATTERN_1, line); + if (paramsMatcher1.find()) { + OAtoken = paramsMatcher1.group(1); + } + final MatcherWrapper paramsMatcher2 = new MatcherWrapper(PARAMS_PATTERN_2, line); + if (paramsMatcher2.find() && paramsMatcher2.groupCount() > 0) { + OAtokenSecret = paramsMatcher2.group(1); + } + + if (StringUtils.isBlank(OAtoken) && StringUtils.isBlank(OAtokenSecret)) { + OAtoken = ""; + OAtokenSecret = ""; + setTokens(null, null, false); + } else { + setTokens(OAtoken, OAtokenSecret, true); + status = AUTHENTICATED; + } + } catch (final Exception e) { + Log.e("OAuthAuthorizationActivity.changeToken", e); + } + + changeTokensHandler.sendEmptyMessage(status); + } + + private String getUrlPrefix() { + return https ? "https://" : "http://"; + } + + private class StartListener implements View.OnClickListener { + + @Override + public void onClick(final View arg0) { + if (requestTokenDialog == null) { + requestTokenDialog = new ProgressDialog(OAuthAuthorizationActivity.this); + requestTokenDialog.setCancelable(false); + requestTokenDialog.setMessage(getAuthDialogWait()); + } + requestTokenDialog.show(); + startButton.setEnabled(false); + startButton.setOnTouchListener(null); + startButton.setOnClickListener(null); + + setTempTokens(null, null); + RxUtils.networkScheduler.createWorker().schedule(new Action0() { + @Override + public void call() { + requestToken(); + } + }); + } + } + + private void exchangeTokens(final String verifier) { + if (changeTokensDialog == null) { + changeTokensDialog = new ProgressDialog(this); + changeTokensDialog.setCancelable(false); + changeTokensDialog.setMessage(getAuthDialogWait()); + } + changeTokensDialog.show(); + + RxUtils.networkScheduler.createWorker().schedule(new Action0() { + @Override + public void call() { + changeToken(verifier); + } + }); + } + + protected abstract ImmutablePair<String, String> getTempTokens(); + + protected abstract void setTempTokens(@Nullable String tokenPublic, @Nullable String tokenSecret); + + protected abstract void setTokens(@Nullable String tokenPublic, @Nullable String tokenSecret, boolean enable); + + // get resources from derived class + + protected abstract String getAuthTitle(); + + protected String getAuthAgain() { + return getString(R.string.auth_again); + } + + protected String getErrAuthInitialize() { + return getString(R.string.err_auth_initialize); + } + + protected String getAuthStart() { + return getString(R.string.auth_start); + } + + protected abstract String getAuthDialogCompleted(); + + protected String getErrAuthProcess() { + return res.getString(R.string.err_auth_process); + } + + /** + * Allows deriving classes to check the response for error messages specific to their OAuth implementation + * + * @param response + * The error response of the token request + * @return String with a more detailed error message (user-facing, localized), can be empty + */ + @SuppressWarnings("static-method") + protected String getExtendedErrorMsg(final HttpResponse response) { + return StringUtils.EMPTY; + } + + protected String getAuthDialogWait() { + return res.getString(R.string.auth_dialog_waiting, getAuthTitle()); + } + + protected String getAuthExplainShort() { + return res.getString(R.string.auth_explain_short, getAuthTitle()); + } + + protected String getAuthExplainLong() { + return res.getString(R.string.auth_explain_long, getAuthTitle()); + } + + protected String getAuthAuthorize() { + return res.getString(R.string.auth_authorize, getAuthTitle()); + } + + public static class OAuthParameters { + @NonNull public final String host; + @NonNull public final String pathRequest; + @NonNull public final String pathAuthorize; + @NonNull public final String pathAccess; + public final boolean https; + @NonNull public final String consumerKey; + @NonNull public final String consumerSecret; + @NonNull public final String callback; + + public OAuthParameters(@NonNull final String host, + @NonNull final String pathRequest, + @NonNull final String pathAuthorize, + @NonNull final String pathAccess, + final boolean https, + @NonNull final String consumerKey, + @NonNull final String consumerSecret, + @NonNull final String callback) { + this.host = host; + this.pathRequest = pathRequest; + this.pathAuthorize = pathAuthorize; + this.pathAccess = pathAccess; + this.https = https; + this.consumerKey = consumerKey; + this.consumerSecret = consumerSecret; + this.callback = callback; + } + + public void setOAuthExtras(final Intent intent) { + if (intent != null) { + intent.putExtra(Intents.EXTRA_OAUTH_HOST, host); + intent.putExtra(Intents.EXTRA_OAUTH_PATH_REQUEST, pathRequest); + intent.putExtra(Intents.EXTRA_OAUTH_PATH_AUTHORIZE, pathAuthorize); + intent.putExtra(Intents.EXTRA_OAUTH_PATH_ACCESS, pathAccess); + intent.putExtra(Intents.EXTRA_OAUTH_HTTPS, https); + intent.putExtra(Intents.EXTRA_OAUTH_CONSUMER_KEY, consumerKey); + intent.putExtra(Intents.EXTRA_OAUTH_CONSUMER_SECRET, consumerSecret); + intent.putExtra(Intents.EXTRA_OAUTH_CALLBACK, callback); + } + } + + } +} diff --git a/main/src/cgeo/geocaching/activity/Progress.java b/main/src/cgeo/geocaching/activity/Progress.java index 8ee88a7..e87eaa6 100644 --- a/main/src/cgeo/geocaching/activity/Progress.java +++ b/main/src/cgeo/geocaching/activity/Progress.java @@ -19,7 +19,7 @@ public class Progress { private int progressDivider = 1; final private boolean hideAbsolute; - public Progress(boolean hideAbsolute) { + public Progress(final boolean hideAbsolute) { this.hideAbsolute = hideAbsolute; } diff --git a/main/src/cgeo/geocaching/activity/ShowcaseViewBuilder.java b/main/src/cgeo/geocaching/activity/ShowcaseViewBuilder.java index 04f096d..86f5302 100644 --- a/main/src/cgeo/geocaching/activity/ShowcaseViewBuilder.java +++ b/main/src/cgeo/geocaching/activity/ShowcaseViewBuilder.java @@ -29,7 +29,6 @@ public class ShowcaseViewBuilder extends Builder { /** * Use the hash of the title for the single shot remembering * - * @param resId */ private void setSingleshot(final CharSequence title) { super.singleShot(title.hashCode()); |