1
0
Fork 0
mirror of https://github.com/syncthing/syncthing-android.git synced 2025-01-09 03:31:46 +00:00

Add WebView for Android TVs (fixes #227) (#225)

* WIP

* AndroidManifest: Add WebViewActivity

* Open WebViewActivity from prefs, move to "Debug" menu

* Add WebViewActivity below SettingsActivity

* Add strings for ssl security notice

* Handle web page links and ssl warnings correctly

* Mention issue tracker URL in pref summary

* Don't use ACTION_VIEW for deeplinks on syncthing's WebUI

* Rename string: report_issue_summary to open_issue_tracker_summary

* Imported translations

* Add "open in browser" drawable

* Add webview_options menu

* Add strings: web page loading, open in browser

* Add option to open webpage in browser on non-TV devices (fixes #227)

* Imported de translation
This commit is contained in:
Catfriend1 2019-01-19 14:53:36 +00:00 committed by GitHub
parent c4a3078c9c
commit a8b3e4d2a0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 264 additions and 14 deletions

View file

@ -74,6 +74,19 @@
android:name="android.support.PARENT_ACTIVITY"
android:value=".activities.MainActivity" />
</activity>
<activity
android:name=".activities.WebViewActivity"
android:label="@string/report_issue_title"
android:parentActivityName=".activities.SettingsActivity"
android:configChanges="keyboardHidden|orientation|screenSize">
<intent-filter>
<action android:name=".activities.WebViewActivity" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".activities.SettingsActivity" />
</activity>
<activity
android:name=".activities.ShareActivity"
android:label="@string/share_activity_title"

View file

@ -330,6 +330,8 @@ public class SettingsActivity extends SyncthingActivity {
stResetDatabase.setOnPreferenceClickListener(this);
stResetDeltas.setOnPreferenceClickListener(this);
screen.findPreference("open_issue_tracker").setSummary(getString(R.string.open_issue_tracker_summary, getString(R.string.issue_tracker_url)));
/* Experimental options */
mUseTor = (CheckBoxPreference) findPreference(Constants.PREF_USE_TOR);
mSocksProxyAddress = (EditTextPreference) findPreference(Constants.PREF_SOCKS_PROXY_ADDRESS);

View file

@ -26,6 +26,7 @@ import com.nutomic.syncthingandroid.service.Constants;
import com.nutomic.syncthingandroid.service.SyncthingService;
import com.nutomic.syncthingandroid.service.SyncthingServiceBinder;
import com.nutomic.syncthingandroid.util.ConfigXml;
import com.nutomic.syncthingandroid.util.Util;
import java.io.File;
import java.io.FileInputStream;
@ -108,7 +109,9 @@ public class WebGuiActivity extends SyncthingActivity
if (uri.getHost().equals(getService().getWebGuiUrl().getHost())) {
return false;
} else {
startActivity(new Intent(Intent.ACTION_VIEW, uri));
if (!Util.isRunningOnTV(WebGuiActivity.this)) {
startActivity(new Intent(Intent.ACTION_VIEW, uri));
}
return true;
}
}

View file

@ -0,0 +1,172 @@
package com.nutomic.syncthingandroid.activities;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.http.SslError;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.webkit.SslErrorHandler;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.TextView;
import com.nutomic.syncthingandroid.R;
import com.nutomic.syncthingandroid.util.Util;
/**
* Holds a WebView that shows the web ui of the local syncthing instance.
*/
public class WebViewActivity extends SyncthingActivity {
private static final String TAG = "WebViewActivity";
private AlertDialog mSecurityNoticeDialog;
private Boolean sslNoticeUserDecision = false;
private WebView mWebView;
private View mLoadingView;
private Boolean isRunningOnTV = false;
private String webPageUrl = "";
/**
* Hides the loading screen and shows the WebView once it is fully loaded.
*/
private final WebViewClient mWebViewClient = new WebViewClient() {
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
if (sslNoticeUserDecision) {
handler.proceed();
return;
}
final DialogInterface.OnClickListener listener = (dialog, which) -> {
try {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
handler.proceed();
sslNoticeUserDecision = true;
break;
case DialogInterface.BUTTON_NEGATIVE:
handler.cancel();
if (isRunningOnTV) {
// Finish as there is no other way to display the website.
finish();
}
break;
}
} catch (Exception e) {
Log.e(TAG, "onReceivedSslError:OnClickListener", e);
}
};
mSecurityNoticeDialog = new AlertDialog.Builder(WebViewActivity.this)
.setTitle(R.string.security_notice)
.setMessage(getString(R.string.ssl_cert_invalid_text, webPageUrl))
.setPositiveButton(R.string.cont, listener)
.setNegativeButton(R.string.cancel_title, listener)
.show();
}
@Override
public void onPageFinished(WebView view, String url) {
mWebView.setVisibility(View.VISIBLE);
mLoadingView.setVisibility(View.GONE);
}
};
/**
* Initialize WebView.
*/
@Override
@SuppressLint("SetJavaScriptEnabled")
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
isRunningOnTV = Util.isRunningOnTV(WebViewActivity.this);
setContentView(R.layout.activity_web_gui);
webPageUrl = getString(R.string.issue_tracker_url);
mLoadingView = findViewById(R.id.loading);
((TextView) findViewById(R.id.loading_text)).setText(getString(R.string.web_page_loading, webPageUrl));
mWebView = findViewById(R.id.webview);
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.getSettings().setDomStorageEnabled(true);
mWebView.setWebViewClient(mWebViewClient);
mWebView.clearCache(true);
if (mWebView.getUrl() == null) {
mWebView.stopLoading();
mWebView.loadUrl(webPageUrl);
}
}
/**
* Saves current tab index and fragment states.
*/
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Util.dismissDialogSafe(mSecurityNoticeDialog, this);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.webview_options, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
menu.findItem(R.id.openBrowser).setVisible(!isRunningOnTV);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.openBrowser:
// This can only be triggered on a non-TV device.
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(webPageUrl)));
finish();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public void onBackPressed() {
if (mWebView.canGoBack()) {
mWebView.goBack();
} else {
finish();
super.onBackPressed();
}
}
@Override
public void onPause() {
mWebView.onPause();
mWebView.pauseTimers();
super.onPause();
}
@Override
public void onResume() {
super.onResume();
mWebView.resumeTimers();
mWebView.onResume();
}
@Override
protected void onDestroy() {
mWebView.destroy();
mWebView = null;
super.onDestroy();
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 233 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 181 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 312 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 447 B

View file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/openBrowser"
android:icon="@drawable/ic_open_in_new_white_24"
android:title="@string/open_in_browser"
app:showAsAction="ifRoom" />
</menu>

View file

@ -310,6 +310,7 @@
<!-- Text for WebGuiActivity loading view -->
<string name="web_gui_loading">Esperant interfície gràfica</string>
<!-- SettingsFragment -->
@ -515,9 +516,6 @@
<!-- Settings item that opens issue tracker -->
<string name="report_issue_title">Informeu d\'un problema</string>
<!-- Summary for the issue tracker settings item -->
<string name="report_issue_summary">Obre el rastrejador de problemes del Syncthing-Fork</string>
<!-- Menu item to donate -->
<!-- Title of the preference showing upstream version name -->
<string name="syncthing_version_title">Versió del Syncthing</string>

View file

@ -343,6 +343,21 @@ Bitte melden Sie auftretende Probleme via GitHub.</string>
<!-- Text for WebGuiActivity loading view -->
<string name="web_gui_loading">Warte auf Weboberfläche</string>
<!-- WebViewActivity -->
<!-- Dialog title displayed when an invalid ssl certificate was found -->
<string name="security_notice">Sicherheitshinweis</string>
<!-- Dialog message if an invalid ssl certificate was detected -->
<string name="ssl_cert_invalid_text">Die Webseite \"%1$s\" scheint ein ungültiges SSL-Zertifikat zur Verschlüsselung aufzuweisen. Fortfahren?</string>
<!-- Text for WebViewActivity loading page -->
<string name="web_page_loading">Lade Webseite:\n%1$s...</string>
<!-- Text for WebViewActivity openBrowser action button -->
<string name="open_in_browser">In Browser öffnen</string>
<!-- SettingsFragment -->
@ -562,7 +577,7 @@ Bitte melden Sie auftretende Probleme via GitHub.</string>
<string name="report_issue_title">Fehler melden</string>
<!-- Summary for the issue tracker settings item -->
<string name="report_issue_summary">Syncthing-Fork Fehlersammlung öffnen</string>
<string name="open_issue_tracker_summary">Öffne die Syncthing-Fork Fehlersammlung bei %1$s</string>
<!-- Menu item to donate -->
<!-- Title of the preference showing upstream version name -->

View file

@ -199,6 +199,7 @@
<!-- Text for WebGuiActivity loading view -->
<string name="web_gui_loading">Esperando a la interfaz gráfica</string>
<!-- SettingsFragment -->

View file

@ -228,6 +228,7 @@
<!-- Text for WebGuiActivity loading view -->
<string name="web_gui_loading">En attente de l\'interface WEB</string>
<!-- SettingsFragment -->

View file

@ -225,6 +225,7 @@
<!-- Text for WebGuiActivity loading view -->
<string name="web_gui_loading">Caricamento Interfaccia Web</string>
<!-- SettingsFragment -->

View file

@ -209,6 +209,7 @@
<!-- Text for WebGuiActivity loading view -->
<string name="web_gui_loading">GUI を待機中</string>
<!-- SettingsFragment -->

View file

@ -247,6 +247,7 @@
<!-- Text for WebGuiActivity loading view -->
<string name="web_gui_loading">Wachten op interface</string>
<!-- SettingsFragment -->

View file

@ -243,6 +243,7 @@
<!-- Text for WebGuiActivity loading view -->
<string name="web_gui_loading">Se așteaptă interfața</string>
<!-- SettingsFragment -->

View file

@ -285,6 +285,7 @@
<!-- Text for WebGuiActivity loading view -->
<string name="web_gui_loading">Ожидание GUI</string>
<!-- SettingsFragment -->

View file

@ -297,6 +297,7 @@
<!-- Text for WebGuiActivity loading view -->
<string name="web_gui_loading">Väntar på gränssnitt</string>
<!-- SettingsFragment -->

View file

@ -285,6 +285,7 @@
<!-- Text for WebGuiActivity loading view -->
<string name="web_gui_loading">正在等待管理页面</string>
<!-- SettingsFragment -->
@ -301,13 +302,21 @@
<string name="run_conditions_title">运行条件</string>
<string name="run_conditions_summary">下方选项将控制 Syncthing 何时启用</string>
<string name="run_on_wifi_title">让它在Wi-Fi上运行</string>
<string name="run_on_wifi_summary">设备连接到Wi-Fi网络时运行。</string>
<string name="run_on_metered_wifi_title">让它在计量Wi-Fi上运行</string>
<string name="run_on_metered_wifi_summary">设备在付费 Wi-Fi 网络环境下启用 Syncthing
警告:可能会产生大量费用</string>
<string name="run_on_whitelisted_wifi_title">在指定的Wi-Fi网络上运行</string>
<string name="specify_wifi_ssid_whitelist">选择 Wi-Fi 网络</string>
<string name="run_on_whitelisted_wifi_networks">已选择的 Wi-Fi 网络 : %1$s</string>
<string name="wifi_ssid_whitelist_empty">未指定Wi-Fi网络。 单击以指定网络。</string>
<string name="sync_only_wifi_ssids_wifi_turn_on_wifi">请打开无线网络连接并选择网络</string>
<string name="sync_only_wifi_ssids_location_permission_rejected_dialog_title">需要许可</string>
<string name="respect_battery_saving_title">遵循 Android 电池省电模式设置</string>
<string name="respect_battery_saving_summary">省电模式启动时禁用 Syncthing</string>
@ -391,6 +400,8 @@
<string name="use_tor_summary">强制所有的流量经由 Tor 代理,需要 Orbot以及禁用其它代理选项。</string>
<string name="socks_proxy_address_title">SOCKS5 代理</string>
<string name="http_proxy_address_title">HTTP(S) 代理</string>
<string name="use_legacy_hashing_title">使用传统哈希</string>
<string name="use_legacy_hashing_summary">强制 Syncthing 使用传统哈希包以提高兼容性</string>

View file

@ -207,6 +207,7 @@
<!-- Text for WebGuiActivity loading view -->
<string name="web_gui_loading">正在等待 GUI</string>
<!-- SettingsFragment -->

View file

@ -343,6 +343,21 @@ Please report any problems you encounter via Github.</string>
<!-- Text for WebGuiActivity loading view -->
<string name="web_gui_loading">Waiting for GUI</string>
<!-- WebViewActivity -->
<!-- Dialog title displayed when an invalid ssl certificate was found -->
<string name="security_notice">Security Notice</string>
<!-- Dialog message if an invalid ssl certificate was detected -->
<string name="ssl_cert_invalid_text">Website at %1$s appears to have an invalid certificate for SSL encryption. Proceed?</string>
<!-- Text for WebViewActivity loading page -->
<string name="web_page_loading">Loading webpage:\n%1$s ...</string>
<!-- Text for WebViewActivity openBrowser action button -->
<string name="open_in_browser">Open in browser</string>
<!-- SettingsFragment -->
@ -570,7 +585,7 @@ Please report any problems you encounter via Github.</string>
<string name="report_issue_title">Report Issue</string>
<!-- Summary for the issue tracker settings item -->
<string name="report_issue_summary">Open the Syncthing-Fork issue tracker</string>
<string name="open_issue_tracker_summary">Open the Syncthing-Fork issue tracker at %1$s</string>
<!-- URL of the issue tracker -->
<string name="issue_tracker_url" translatable="false">https://github.com/Catfriend1/syncthing-android/issues</string>

View file

@ -213,6 +213,14 @@
<PreferenceScreen
android:title="@string/category_debug">
<Preference
android:key="open_issue_tracker"
android:persistent="false"
android:title="@string/report_issue_title">
<intent
android:action=".activities.WebViewActivity" />
</Preference>
<Preference
android:title="@string/open_log"
android:summary="@string/open_log_summary">
@ -285,14 +293,6 @@
<PreferenceScreen
android:title="@string/category_about">
<Preference
android:title="@string/report_issue_title"
android:summary="@string/report_issue_summary">
<intent
android:action="android.intent.action.VIEW"
android:data="@string/issue_tracker_url" />
</Preference>
<Preference
android:persistent="false"
android:selectable="false"