Merge pull request #3187 from nextcloud/handleNoApps

Wrapper to start urls/intents if no app is available
This commit is contained in:
Andy Scherzinger 2018-10-29 22:24:59 +01:00 committed by GitHub
commit 831f083153
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 89 additions and 95 deletions

View file

@ -203,7 +203,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
private AccountManager mAccountMgr; private AccountManager mAccountMgr;
private Uri mNewCapturedUriFromOAuth2Redirection; private Uri mNewCapturedUriFromOAuth2Redirection;
/// Server PRE-Fragment elements /// Server PRE-Fragment elements
private CustomEditText mHostUrlInput; private CustomEditText mHostUrlInput;
private View mRefreshButton; private View mRefreshButton;
private TextView mServerStatusView; private TextView mServerStatusView;
@ -217,7 +217,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
private GetServerInfoOperation.ServerInfo mServerInfo = new GetServerInfoOperation.ServerInfo(); private GetServerInfoOperation.ServerInfo mServerInfo = new GetServerInfoOperation.ServerInfo();
/// Authentication PRE-Fragment elements /// Authentication PRE-Fragment elements
private CheckBox mOAuth2Check; private CheckBox mOAuth2Check;
private TextView mOAuthAuthEndpointText; private TextView mOAuthAuthEndpointText;
private TextView mOAuthTokenEndpointText; private TextView mOAuthTokenEndpointText;
@ -237,7 +237,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
private boolean mIsFirstAuthAttempt; private boolean mIsFirstAuthAttempt;
/// Identifier of operation in progress which result shouldn't be lost /// Identifier of operation in progress which result shouldn't be lost
private long mWaitingForOpId = Long.MAX_VALUE; private long mWaitingForOpId = Long.MAX_VALUE;
private String basicTokenType; private String basicTokenType;
@ -264,7 +264,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
if (savedInstanceState == null) { if (savedInstanceState == null) {
FirstRunActivity.runIfNeeded(this); FirstRunActivity.runIfNeeded(this);
} }
basicTokenType = AccountTypeUtils.getAuthTokenTypePass(MainApp.getAccountType(this)); basicTokenType = AccountTypeUtils.getAuthTokenTypePass(MainApp.getAccountType(this));
oauthTokenType = AccountTypeUtils.getAuthTokenTypeAccessToken(MainApp.getAccountType(this)); oauthTokenType = AccountTypeUtils.getAuthTokenTypeAccessToken(MainApp.getAccountType(this));
samlTokenType = AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(MainApp.getAccountType(this)); samlTokenType = AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(MainApp.getAccountType(this));
@ -379,7 +379,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
mLoginWebView.getSettings().setAllowFileAccess(false); mLoginWebView.getSettings().setAllowFileAccess(false);
mLoginWebView.getSettings().setJavaScriptEnabled(true); mLoginWebView.getSettings().setJavaScriptEnabled(true);
mLoginWebView.getSettings().setDomStorageEnabled(true); mLoginWebView.getSettings().setDomStorageEnabled(true);
if (useGenericUserAgent) { if (useGenericUserAgent) {
mLoginWebView.getSettings().setUserAgentString(MainApp.getNextcloudUserAgent()); mLoginWebView.getSettings().setUserAgentString(MainApp.getNextcloudUserAgent());
} else { } else {
@ -1339,7 +1339,8 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
uri = uriBuilder.build(); uri = uriBuilder.build();
Log_OC.d(TAG, "Starting browser to view " + uri.toString()); Log_OC.d(TAG, "Starting browser to view " + uri.toString());
Intent i = new Intent(Intent.ACTION_VIEW, uri); Intent i = new Intent(Intent.ACTION_VIEW, uri);
startActivity(i);
DisplayUtils.startIntentIfAppAvailable(i, this, R.string.no_browser_available);
} }
@ -1371,7 +1372,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
if (operation instanceof GetServerInfoOperation) { if (operation instanceof GetServerInfoOperation) {
if (operation.hashCode() == mWaitingForOpId) { if (operation.hashCode() == mWaitingForOpId) {
onGetServerInfoFinish(result); onGetServerInfoFinish(result);
} // else nothing ; only the last check operation is considered; } // else nothing ; only the last check operation is considered;
// multiple can be started if the user amends a URL quickly // multiple can be started if the user amends a URL quickly
} else if (operation instanceof OAuth2GetAccessToken) { } else if (operation instanceof OAuth2GetAccessToken) {
@ -1456,7 +1457,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
// 1. connection succeeded, and we know if it's SSL or not // 1. connection succeeded, and we know if it's SSL or not
// 2. server is installed // 2. server is installed
// 3. we got the server version // 3. we got the server version
// 4. we got the authentication method required by the server // 4. we got the authentication method required by the server
mServerInfo = (GetServerInfoOperation.ServerInfo) (result.getData().get(0)); mServerInfo = (GetServerInfoOperation.ServerInfo) (result.getData().get(0));
// show outdated warning // show outdated warning
@ -1776,7 +1777,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
} }
} else if (result.isServerFail() || result.isException()) { } else if (result.isServerFail() || result.isException()) {
/// server errors or exceptions in authorization take to requiring a new check of /// server errors or exceptions in authorization take to requiring a new check of
/// the server /// the server
mServerIsChecked = true; mServerIsChecked = true;
mServerIsValid = false; mServerIsValid = false;
@ -1837,13 +1838,13 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
if (AccountTypeUtils.getAuthTokenTypeAccessToken(accountType).equals(mAuthTokenType)) { if (AccountTypeUtils.getAuthTokenTypeAccessToken(accountType).equals(mAuthTokenType)) {
response.putString(AccountManager.KEY_AUTHTOKEN, mAuthToken); response.putString(AccountManager.KEY_AUTHTOKEN, mAuthToken);
// the next line is necessary, notifications are calling directly to the // the next line is necessary, notifications are calling directly to the
// AuthenticatorActivity to update, without AccountManager intervention // AuthenticatorActivity to update, without AccountManager intervention
mAccountMgr.setAuthToken(mAccount, mAuthTokenType, mAuthToken); mAccountMgr.setAuthToken(mAccount, mAuthTokenType, mAuthToken);
} else if (AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(accountType).equals(mAuthTokenType)) { } else if (AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(accountType).equals(mAuthTokenType)) {
response.putString(AccountManager.KEY_AUTHTOKEN, mAuthToken); response.putString(AccountManager.KEY_AUTHTOKEN, mAuthToken);
// the next line is necessary; by now, notifications are calling directly to the // the next line is necessary; by now, notifications are calling directly to the
// AuthenticatorActivity to update, without AccountManager intervention // AuthenticatorActivity to update, without AccountManager intervention
mAccountMgr.setAuthToken(mAccount, mAuthTokenType, mAuthToken); mAccountMgr.setAuthToken(mAccount, mAuthTokenType, mAuthToken);
@ -1938,7 +1939,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
} }
/// prepare result to return to the Authenticator /// prepare result to return to the Authenticator
// TODO check again what the Authenticator makes with it; probably has the same // TODO check again what the Authenticator makes with it; probably has the same
// effect as addAccountExplicitly, but it's not well done // effect as addAccountExplicitly, but it's not well done
final Intent intent = new Intent(); final Intent intent = new Intent();
intent.putExtra(AccountManager.KEY_ACCOUNT_TYPE, accountType); intent.putExtra(AccountManager.KEY_ACCOUNT_TYPE, accountType);
@ -1947,7 +1948,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
if (isOAuth || isSaml) { if (isOAuth || isSaml) {
mAccountMgr.setAuthToken(mAccount, mAuthTokenType, mAuthToken); mAccountMgr.setAuthToken(mAccount, mAuthTokenType, mAuthToken);
} }
/// add user data to the new account; TODO probably can be done in the last parameter /// add user data to the new account; TODO probably can be done in the last parameter
// addAccountExplicitly, or in KEY_USERDATA // addAccountExplicitly, or in KEY_USERDATA
mAccountMgr.setUserData(mAccount, Constants.KEY_OC_VERSION, mServerInfo.mVersion.getVersion()); mAccountMgr.setUserData(mAccount, Constants.KEY_OC_VERSION, mServerInfo.mVersion.getVersion());
mAccountMgr.setUserData(mAccount, Constants.KEY_OC_BASE_URL, mServerInfo.mBaseUrl); mAccountMgr.setUserData(mAccount, Constants.KEY_OC_BASE_URL, mServerInfo.mBaseUrl);
@ -2053,7 +2054,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
/** /**
* Called when the 'action' button in an IME is pressed ('enter' in software keyboard). * Called when the 'action' button in an IME is pressed ('enter' in software keyboard).
* *
* Used to trigger the authentication check when the user presses 'enter' after writing the * Used to trigger the authentication check when the user presses 'enter' after writing the
* password, or to throw the server test when the only field on screen is the URL input field. * password, or to throw the server test when the only field on screen is the URL input field.
*/ */
@ -2192,7 +2193,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
public void onSavedCertificate() { public void onSavedCertificate() {
Fragment fd = getSupportFragmentManager().findFragmentByTag(SAML_DIALOG_TAG); Fragment fd = getSupportFragmentManager().findFragmentByTag(SAML_DIALOG_TAG);
if (fd == null) { if (fd == null) {
// if SAML dialog is not shown, // if SAML dialog is not shown,
// the SslDialog was shown due to an SSL error in the server check // the SslDialog was shown due to an SSL error in the server check
checkOcServer(); checkOcServer();
} }

View file

@ -545,7 +545,8 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU
for (ExternalLink link : externalLinksProvider.getExternalLink(ExternalLinkType.LINK)) { for (ExternalLink link : externalLinksProvider.getExternalLink(ExternalLinkType.LINK)) {
if (menuItem.getTitle().toString().equalsIgnoreCase(link.name)) { if (menuItem.getTitle().toString().equalsIgnoreCase(link.name)) {
if (link.redirect) { if (link.redirect) {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(link.url))); Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(link.url));
DisplayUtils.startIntentIfAppAvailable(intent, this, R.string.no_browser_available);
} else { } else {
Intent externalWebViewIntent = new Intent(getApplicationContext(), ExternalSiteWebView.class); Intent externalWebViewIntent = new Intent(getApplicationContext(), ExternalSiteWebView.class);
externalWebViewIntent.putExtra(ExternalSiteWebView.EXTRA_TITLE, link.name); externalWebViewIntent.putExtra(ExternalSiteWebView.EXTRA_TITLE, link.name);

View file

@ -613,7 +613,7 @@ public abstract class FileActivity extends DrawerActivity
LoadingVersionNumberTask loadTask = new LoadingVersionNumberTask(callback); LoadingVersionNumberTask loadTask = new LoadingVersionNumberTask(callback);
loadTask.execute(url); loadTask.execute(url);
} }
public static void showDevSnackbar(Activity activity, Integer latestVersion, boolean openDirectly) { public static void showDevSnackbar(Activity activity, Integer latestVersion, boolean openDirectly) {
Integer currentVersion = -1; Integer currentVersion = -1;
try { try {
@ -630,7 +630,7 @@ public abstract class FileActivity extends DrawerActivity
String devApkLink = (String) activity.getText(R.string.dev_link) + latestVersion + ".apk"; String devApkLink = (String) activity.getText(R.string.dev_link) + latestVersion + ".apk";
Uri uriUrl = Uri.parse(devApkLink); Uri uriUrl = Uri.parse(devApkLink);
Intent intent = new Intent(Intent.ACTION_VIEW, uriUrl); Intent intent = new Intent(Intent.ACTION_VIEW, uriUrl);
activity.startActivity(intent); DisplayUtils.startIntentIfAppAvailable(intent, activity, R.string.no_browser_available);
} else { } else {
Snackbar.make(activity.findViewById(android.R.id.content), R.string.dev_version_new_version_available, Snackbar.make(activity.findViewById(android.R.id.content), R.string.dev_version_new_version_available,
Snackbar.LENGTH_LONG) Snackbar.LENGTH_LONG)
@ -638,7 +638,7 @@ public abstract class FileActivity extends DrawerActivity
String devApkLink = (String) activity.getText(R.string.dev_link) + latestVersion + ".apk"; String devApkLink = (String) activity.getText(R.string.dev_link) + latestVersion + ".apk";
Uri uriUrl = Uri.parse(devApkLink); Uri uriUrl = Uri.parse(devApkLink);
Intent intent = new Intent(Intent.ACTION_VIEW, uriUrl); Intent intent = new Intent(Intent.ACTION_VIEW, uriUrl);
activity.startActivity(intent); DisplayUtils.startIntentIfAppAvailable(intent, activity, R.string.no_browser_available);
}).show(); }).show();
} }
} else { } else {

View file

@ -63,7 +63,7 @@ public class FirstRunActivity extends BaseActivity implements ViewPager.OnPageCh
setContentView(R.layout.first_run_activity); setContentView(R.layout.first_run_activity);
boolean isProviderOrOwnInstallationVisible = getResources().getBoolean(R.bool.show_provider_or_own_installation); boolean isProviderOrOwnInstallationVisible = getResources().getBoolean(R.bool.show_provider_or_own_installation);
setSlideshowSize(getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE); setSlideshowSize(getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE);
Button loginButton = findViewById(R.id.login); Button loginButton = findViewById(R.id.login);
@ -181,7 +181,7 @@ public class FirstRunActivity extends BaseActivity implements ViewPager.OnPageCh
if (!isProviderOrOwnInstallationVisible) { if (!isProviderOrOwnInstallationVisible) {
return false; return false;
} }
if (context instanceof FirstRunActivity) { if (context instanceof FirstRunActivity) {
return false; return false;
} }
@ -210,7 +210,8 @@ public class FirstRunActivity extends BaseActivity implements ViewPager.OnPageCh
} }
public void onHostYourOwnServerClick(View view) { public void onHostYourOwnServerClick(View view) {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.url_server_install)))); Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.url_server_install)));
DisplayUtils.startIntentIfAppAvailable(intent, this, R.string.no_browser_available);
} }
@Override @Override
@ -224,7 +225,7 @@ public class FirstRunActivity extends BaseActivity implements ViewPager.OnPageCh
DisplayUtils.showSnackMessage(this, R.string.account_creation_failed); DisplayUtils.showSnackMessage(this, R.string.account_creation_failed);
return; return;
} }
setAccount(account); setAccount(account);
AccountUtils.setCurrentOwnCloudAccount(this, account.name); AccountUtils.setCurrentOwnCloudAccount(this, account.name);
onAccountSet(false); onAccountSet(false);

View file

@ -23,7 +23,6 @@ package com.owncloud.android.ui.activity;
import android.content.Intent; import android.content.Intent;
import android.graphics.PorterDuff; import android.graphics.PorterDuff;
import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.support.v7.widget.AppCompatButton; import android.support.v7.widget.AppCompatButton;
import android.text.Html; import android.text.Html;
@ -33,6 +32,7 @@ import android.view.View;
import android.widget.TextView; import android.widget.TextView;
import com.owncloud.android.R; import com.owncloud.android.R;
import com.owncloud.android.utils.DisplayUtils;
import com.owncloud.android.utils.ThemeUtils; import com.owncloud.android.utils.ThemeUtils;
/** /**
@ -94,28 +94,23 @@ public class ParticipateActivity extends FileActivity {
AppCompatButton reportButton = findViewById(R.id.participate_testing_report); AppCompatButton reportButton = findViewById(R.id.participate_testing_report);
reportButton.getBackground().setColorFilter(ThemeUtils.primaryAccentColor(this), PorterDuff.Mode.SRC_ATOP); reportButton.getBackground().setColorFilter(ThemeUtils.primaryAccentColor(this), PorterDuff.Mode.SRC_ATOP);
reportButton.setOnClickListener(new View.OnClickListener() { reportButton.setOnClickListener(v -> DisplayUtils.startLinkIntent(this, R.string.report_issue_link));
@Override
public void onClick(View v) {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.report_issue_link))));
}
});
} }
public void onGetBetaFDroidClick(View view) { public void onGetBetaFDroidClick(View view) {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.fdroid_beta_link)))); DisplayUtils.startLinkIntent(this, R.string.fdroid_beta_link);
} }
public void onGetRCFDroidClick(View view) { public void onGetRCFDroidClick(View view) {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.fdroid_link)))); DisplayUtils.startLinkIntent(this, R.string.fdroid_link);
} }
public void onGetRCPlayStoreClick(View view) { public void onGetRCPlayStoreClick(View view) {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.play_store_register_beta)))); DisplayUtils.startLinkIntent(this, R.string.play_store_register_beta);
} }
public void onGetBetaApkClick(View view) { public void onGetBetaApkClick(View view) {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.beta_apk_link)))); DisplayUtils.startLinkIntent(this, R.string.beta_apk_link);
} }
@Override @Override

View file

@ -172,7 +172,7 @@ public class Preferences extends PreferenceActivity
// About // About
setupAboutCategory(accentColor, appVersion); setupAboutCategory(accentColor, appVersion);
// Dev // Dev
setupDevCategory(accentColor, preferenceScreen); setupDevCategory(accentColor, preferenceScreen);
} }
@ -202,10 +202,7 @@ public class Preferences extends PreferenceActivity
Preference pChangelogLink = findPreference("changelog_link"); Preference pChangelogLink = findPreference("changelog_link");
if (pChangelogLink != null) { if (pChangelogLink != null) {
pChangelogLink.setOnPreferenceClickListener(preference -> { pChangelogLink.setOnPreferenceClickListener(preference -> {
String devChangelogLink = getString(R.string.dev_changelog); DisplayUtils.startLinkIntent(this, R.string.dev_changelog);
Uri uriUrl = Uri.parse(devChangelogLink);
Intent intent = new Intent(Intent.ACTION_VIEW, uriUrl);
startActivity(intent);
return true; return true;
}); });
} }
@ -230,14 +227,10 @@ public class Preferences extends PreferenceActivity
boolean licenseEnabled = getResources().getBoolean(R.bool.license_enabled); boolean licenseEnabled = getResources().getBoolean(R.bool.license_enabled);
Preference licensePreference = findPreference("license"); Preference licensePreference = findPreference("license");
if (licensePreference != null) { if (licensePreference != null) {
String licenseUrl = getString(R.string.license_url); if (licenseEnabled) {
if (licenseEnabled && !licenseUrl.isEmpty()) {
licensePreference.setSummary(R.string.prefs_gpl_v2); licensePreference.setSummary(R.string.prefs_gpl_v2);
licensePreference.setOnPreferenceClickListener(preference -> { licensePreference.setOnPreferenceClickListener(preference -> {
Uri uriUrl = Uri.parse(licenseUrl); DisplayUtils.startLinkIntent(this, R.string.license_url);
Intent intent = new Intent(Intent.ACTION_VIEW, uriUrl);
startActivity(intent);
return true; return true;
}); });
} else { } else {
@ -258,6 +251,7 @@ public class Preferences extends PreferenceActivity
Intent intent; Intent intent;
if ("application/pdf".equals(mimeType)) { if ("application/pdf".equals(mimeType)) {
intent = new Intent(Intent.ACTION_VIEW, privacyUrl); intent = new Intent(Intent.ACTION_VIEW, privacyUrl);
DisplayUtils.startIntentIfAppAvailable(intent, this, R.string.no_pdf_app_available);
} else { } else {
intent = new Intent(getApplicationContext(), ExternalSiteWebView.class); intent = new Intent(getApplicationContext(), ExternalSiteWebView.class);
intent.putExtra(ExternalSiteWebView.EXTRA_TITLE, intent.putExtra(ExternalSiteWebView.EXTRA_TITLE,
@ -283,12 +277,9 @@ public class Preferences extends PreferenceActivity
boolean sourcecodeEnabled = getResources().getBoolean(R.bool.sourcecode_enabled); boolean sourcecodeEnabled = getResources().getBoolean(R.bool.sourcecode_enabled);
Preference sourcecodePreference = findPreference("sourcecode"); Preference sourcecodePreference = findPreference("sourcecode");
if (sourcecodePreference != null) { if (sourcecodePreference != null) {
String sourcecodeUrl = getString(R.string.sourcecode_url); if (sourcecodeEnabled) {
if (sourcecodeEnabled && !sourcecodeUrl.isEmpty()) {
sourcecodePreference.setOnPreferenceClickListener(preference -> { sourcecodePreference.setOnPreferenceClickListener(preference -> {
Uri uriUrl = Uri.parse(sourcecodeUrl); DisplayUtils.startLinkIntent(this, R.string.sourcecode_url);
Intent intent = new Intent(Intent.ACTION_VIEW, uriUrl);
startActivity(intent);
return true; return true;
}); });
} else { } else {
@ -332,7 +323,7 @@ public class Preferences extends PreferenceActivity
if (!imprintWeb.isEmpty()) { if (!imprintWeb.isEmpty()) {
Uri uriUrl = Uri.parse(imprintWeb); Uri uriUrl = Uri.parse(imprintWeb);
Intent intent = new Intent(Intent.ACTION_VIEW, uriUrl); Intent intent = new Intent(Intent.ACTION_VIEW, uriUrl);
startActivity(intent); DisplayUtils.startIntentIfAppAvailable(intent, this, R.string.no_browser_available);
} }
//ImprintDialog.newInstance(true).show(preference.get, "IMPRINT_DIALOG"); //ImprintDialog.newInstance(true).show(preference.get, "IMPRINT_DIALOG");
return true; return true;
@ -460,7 +451,7 @@ public class Preferences extends PreferenceActivity
if (!helpWeb.isEmpty()) { if (!helpWeb.isEmpty()) {
Uri uriUrl = Uri.parse(helpWeb); Uri uriUrl = Uri.parse(helpWeb);
Intent intent = new Intent(Intent.ACTION_VIEW, uriUrl); Intent intent = new Intent(Intent.ACTION_VIEW, uriUrl);
startActivity(intent); DisplayUtils.startIntentIfAppAvailable(intent, this, R.string.no_browser_available);
} }
return true; return true;
}); });
@ -803,7 +794,7 @@ public class Preferences extends PreferenceActivity
// no f-droid market app or Play store installed --> launch browser for f-droid url // no f-droid market app or Play store installed --> launch browser for f-droid url
Intent downloadIntent = new Intent(Intent.ACTION_VIEW, Intent downloadIntent = new Intent(Intent.ACTION_VIEW,
Uri.parse("https://f-droid.org/repository/browse/?fdid=at.bitfire.davdroid")); Uri.parse("https://f-droid.org/repository/browse/?fdid=at.bitfire.davdroid"));
startActivity(downloadIntent); DisplayUtils.startIntentIfAppAvailable(downloadIntent, this, R.string.no_browser_available);
DisplayUtils.showSnackMessage(this, R.string.prefs_calendar_contacts_no_store_error); DisplayUtils.showSnackMessage(this, R.string.prefs_calendar_contacts_no_store_error);
} }
@ -891,7 +882,7 @@ public class Preferences extends PreferenceActivity
builder.show(); builder.show();
} }
} }
@Override @Override
@NonNull @NonNull
public MenuInflater getMenuInflater() { public MenuInflater getMenuInflater() {

View file

@ -272,7 +272,9 @@ public class NotificationListAdapter extends RecyclerView.Adapter<NotificationLi
} }
private void openLink(String link) { private void openLink(String link) {
notificationsActivity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(link))); Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(link));
DisplayUtils.startIntentIfAppAvailable(intent, notificationsActivity, R.string.no_browser_available);
} }
@Override @Override

View file

@ -23,9 +23,7 @@ package com.owncloud.android.ui.fragment;
import android.accounts.Account; import android.accounts.Account;
import android.app.SearchManager; import android.app.SearchManager;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.content.res.Resources; import android.content.res.Resources;
import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.design.widget.Snackbar; import android.support.design.widget.Snackbar;
@ -63,6 +61,7 @@ import com.owncloud.android.ui.dialog.SharePasswordDialogFragment;
import com.owncloud.android.ui.fragment.util.FileDetailSharingFragmentHelper; import com.owncloud.android.ui.fragment.util.FileDetailSharingFragmentHelper;
import com.owncloud.android.ui.fragment.util.SharingMenuHelper; import com.owncloud.android.ui.fragment.util.SharingMenuHelper;
import com.owncloud.android.utils.ClipboardUtil; import com.owncloud.android.utils.ClipboardUtil;
import com.owncloud.android.utils.DisplayUtils;
import com.owncloud.android.utils.ThemeUtils; import com.owncloud.android.utils.ThemeUtils;
import java.util.List; import java.util.List;
@ -373,11 +372,8 @@ public class FileDetailSharingFragment extends Fragment implements UserListAdapt
public void showNotSupportedByOcMessage() { public void showNotSupportedByOcMessage() {
if (getView() != null) { if (getView() != null) {
Snackbar.make(getView(), R.string.files_drop_not_supported, Snackbar.LENGTH_LONG) Snackbar.make(getView(), R.string.files_drop_not_supported, Snackbar.LENGTH_LONG)
.setAction(R.string.learn_more, v -> { .setAction(R.string.learn_more, v ->
Intent i = new Intent(Intent.ACTION_VIEW); DisplayUtils.startLinkIntent(requireActivity(), R.string.url_server_install))
i.setData(Uri.parse(getString(R.string.url_server_install)));
startActivity(i);
})
.show(); .show();
} }
} }
@ -473,7 +469,7 @@ public class FileDetailSharingFragment extends Fragment implements UserListAdapt
/** /**
* Get known server capabilities from DB * Get known server capabilities from DB
* *
* Depends on the parent Activity provides a {@link com.owncloud.android.datamodel.FileDataStorageManager} * Depends on the parent Activity provides a {@link com.owncloud.android.datamodel.FileDataStorageManager}
* instance ready to use. If not ready, does nothing. * instance ready to use. If not ready, does nothing.
*/ */
@ -485,9 +481,9 @@ public class FileDetailSharingFragment extends Fragment implements UserListAdapt
/** /**
* Get public link from the DB to fill in the "Share link" section in the UI. * Get public link from the DB to fill in the "Share link" section in the UI.
* *
* Takes into account server capabilities before reading database. * Takes into account server capabilities before reading database.
* *
* Depends on the parent Activity provides a {@link com.owncloud.android.datamodel.FileDataStorageManager} * Depends on the parent Activity provides a {@link com.owncloud.android.datamodel.FileDataStorageManager}
* instance ready to use. If not ready, does nothing. * instance ready to use. If not ready, does nothing.
*/ */

View file

@ -25,10 +25,8 @@ package com.owncloud.android.ui.fragment;
import android.accounts.Account; import android.accounts.Account;
import android.app.Activity; import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.PorterDuff; import android.graphics.PorterDuff;
import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.design.widget.Snackbar; import android.support.design.widget.Snackbar;
@ -62,8 +60,8 @@ import com.owncloud.android.utils.MimeTypeUtil;
import com.owncloud.android.utils.ThemeUtils; import com.owncloud.android.utils.ThemeUtils;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Date; import java.util.Date;
import java.util.List;
/** /**
* Fragment for Sharing a file with sharees (users or groups) or creating * Fragment for Sharing a file with sharees (users or groups) or creating
@ -543,14 +541,8 @@ public class ShareFileFragment extends Fragment implements ShareUserListAdapter.
} else { } else {
// not supported in ownCloud // not supported in ownCloud
Snackbar.make(getView(), R.string.files_drop_not_supported, Snackbar.LENGTH_LONG) Snackbar.make(getView(), R.string.files_drop_not_supported, Snackbar.LENGTH_LONG)
.setAction(R.string.learn_more, new View.OnClickListener(){ .setAction(R.string.learn_more, v ->
@Override DisplayUtils.startLinkIntent(requireActivity(), R.string.url_server_install))
public void onClick(View v) {
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(getString(R.string.url_server_install)));
startActivity(i);
}
})
.show(); .show();
} }

View file

@ -765,7 +765,7 @@ public final class DisplayUtils {
return (int) (dp * ((float) metrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT)); return (int) (dp * ((float) metrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT));
} }
static public void showServerOutdatedSnackbar(Activity activity) { static public void showServerOutdatedSnackbar(Activity activity) {
Snackbar.make(activity.findViewById(android.R.id.content), Snackbar.make(activity.findViewById(android.R.id.content),
R.string.outdated_server, Snackbar.LENGTH_INDEFINITE) R.string.outdated_server, Snackbar.LENGTH_INDEFINITE)
@ -773,4 +773,17 @@ public final class DisplayUtils {
}) })
.show(); .show();
} }
static public void startLinkIntent(Activity activity, @StringRes int link) {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(activity.getString(link)));
DisplayUtils.startIntentIfAppAvailable(intent, activity, R.string.no_browser_available);
}
static public void startIntentIfAppAvailable(Intent intent, Activity activity, @StringRes int error) {
if (intent.resolveActivity(activity.getPackageManager()) != null) {
activity.startActivity(intent);
} else {
DisplayUtils.showSnackMessage(activity, error);
}
}
} }

View file

@ -94,16 +94,6 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<ImageButton
android:id="@+id/participate_release_candidate_playstore"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/white"
android:onClick="onGetRCPlayStoreClick"
android:padding="@dimen/zero"
android:src="@drawable/playstore"
android:contentDescription="@string/participate_rc_play_store"/>
<ImageButton <ImageButton
android:id="@+id/participate_release_candidate_fdroid" android:id="@+id/participate_release_candidate_fdroid"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -114,6 +104,16 @@
android:src="@drawable/fdroid" android:src="@drawable/fdroid"
android:contentDescription="@string/participate_rc_fdroid"/> android:contentDescription="@string/participate_rc_fdroid"/>
<ImageButton
android:id="@+id/participate_release_candidate_playstore"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/white"
android:onClick="onGetRCPlayStoreClick"
android:padding="@dimen/zero"
android:src="@drawable/playstore"
android:contentDescription="@string/participate_rc_play_store"/>
</LinearLayout> </LinearLayout>
<TextView <TextView
@ -204,4 +204,4 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_gravity="start"/> android:layout_gravity="start"/>
</android.support.v4.widget.DrawerLayout> </android.support.v4.widget.DrawerLayout>

View file

@ -205,7 +205,7 @@
<string name="pass_code_enter_pass_code">Please enter your passcode</string> <string name="pass_code_enter_pass_code">Please enter your passcode</string>
<string name="default_credentials_wrong">Incorrect credentials</string> <string name="default_credentials_wrong">Incorrect credentials</string>
<string name="credentials_disabled">Credentials disabled</string> <string name="credentials_disabled">Credentials disabled</string>
<string name="pass_code_configure_your_pass_code">Enter your passcode</string> <string name="pass_code_configure_your_pass_code">Enter your passcode</string>
<string name="pass_code_configure_your_pass_code_explanation">The passcode will be requested every time the app is started</string> <string name="pass_code_configure_your_pass_code_explanation">The passcode will be requested every time the app is started</string>
<string name="pass_code_reenter_your_pass_code">Please reenter your passcode</string> <string name="pass_code_reenter_your_pass_code">Please reenter your passcode</string>
@ -214,7 +214,7 @@
<string name="pass_code_wrong">Incorrect passcode</string> <string name="pass_code_wrong">Incorrect passcode</string>
<string name="pass_code_removed">Passcode deleted</string> <string name="pass_code_removed">Passcode deleted</string>
<string name="pass_code_stored">Passcode stored</string> <string name="pass_code_stored">Passcode stored</string>
<string name="media_notif_ticker">%1$s music player</string> <string name="media_notif_ticker">%1$s music player</string>
<string name="media_state_playing">%1$s (playing)</string> <string name="media_state_playing">%1$s (playing)</string>
<string name="media_state_loading">%1$s (loading)</string> <string name="media_state_loading">%1$s (loading)</string>
@ -294,10 +294,10 @@
<string name="filedisplay_no_file_selected">No file selected</string> <string name="filedisplay_no_file_selected">No file selected</string>
<string name="activity_chooser_title">Send link to…</string> <string name="activity_chooser_title">Send link to…</string>
<string name="wait_for_tmp_copy_from_private_storage">Copying file from private storage</string> <string name="wait_for_tmp_copy_from_private_storage">Copying file from private storage</string>
<string name="oauth_check_onoff">Log in with OAuth 2.0</string> <string name="oauth_check_onoff">Log in with OAuth 2.0</string>
<string name="oauth_login_connection">Connecting to OAuth 2.0 server…</string> <string name="oauth_login_connection">Connecting to OAuth 2.0 server…</string>
<string name="ssl_validator_header">The identity of the server could not be verified</string> <string name="ssl_validator_header">The identity of the server could not be verified</string>
<string name="ssl_validator_reason_cert_not_trusted">- The server certificate is not trusted</string> <string name="ssl_validator_reason_cert_not_trusted">- The server certificate is not trusted</string>
<string name="ssl_validator_reason_cert_expired">- The server certificate expired</string> <string name="ssl_validator_reason_cert_expired">- The server certificate expired</string>
@ -723,7 +723,7 @@
<string name="notification_channel_file_sync_description">Shows file sync progress and results</string> <string name="notification_channel_file_sync_description">Shows file sync progress and results</string>
<string name="notification_channel_file_observer_name">File observer</string> <string name="notification_channel_file_observer_name">File observer</string>
<string name="notification_channel_file_observer_description">Monitors files for changes</string> <string name="notification_channel_file_observer_description">Monitors files for changes</string>
<string name="account_not_found">Account not found!</string> <string name="account_not_found">Account not found!</string>
<string name="screenshot_01_gridView">A safe home for all your data</string> <string name="screenshot_01_gridView">A safe home for all your data</string>
@ -732,12 +732,12 @@
<string name="screenshot_04_accounts">Connect to different accounts</string> <string name="screenshot_04_accounts">Connect to different accounts</string>
<string name="screenshot_05_autoUpload">Automatically upload your photos &amp; videos</string> <string name="screenshot_05_autoUpload">Automatically upload your photos &amp; videos</string>
<string name="screenshot_06_davdroid">Sync calendar &amp; contacts with DAVdroid</string> <string name="screenshot_06_davdroid">Sync calendar &amp; contacts with DAVdroid</string>
<string name="userinfo_no_info_headline">No personal info set</string> <string name="userinfo_no_info_headline">No personal info set</string>
<string name="userinfo_no_info_text">Add name, picture and contact details on your profile page.</string> <string name="userinfo_no_info_text">Add name, picture and contact details on your profile page.</string>
<string name="drawer_header_background">Background image of drawer header</string> <string name="drawer_header_background">Background image of drawer header</string>
<string name="account_icon">Account icon</string> <string name="account_icon">Account icon</string>
<string name="end_to_end_encryption_folder_not_empty">This folder is not empty.</string> <string name="end_to_end_encryption_folder_not_empty">This folder is not empty.</string>
<string name="end_to_end_encryption_wrong_password">Error while decrypting. Wrong password?</string> <string name="end_to_end_encryption_wrong_password">Error while decrypting. Wrong password?</string>
<string name="end_to_end_encryption_decrypting">Decrypting…</string> <string name="end_to_end_encryption_decrypting">Decrypting…</string>
@ -827,5 +827,7 @@
<string name="send_note">Send note to recipient</string> <string name="send_note">Send note to recipient</string>
<string name="note_could_not_sent">Could not send note</string> <string name="note_could_not_sent">Could not send note</string>
<string name="hint_note">Note</string> <string name="hint_note">Note</string>
<string name="no_browser_available">No app available to handle links</string>
<string name="no_pdf_app_available">No App available to handle PDF</string>
</resources> </resources>