<w>amiunique</w>
<w>amoled</w>
<w>androidcentral</w>
+ <w>androidplatform</w>
<w>androidversion</w>
<w>anonymized</w>
<w>apng</w>
+ <w>appassets</w>
<w>appbarlayout</w>
<w>aren</w>
<w>autofill</w>
<!--
Copyright © 2016-2021 Soren Stoutner <soren@stoutner.com>.
- Translation 2020 Thiago Nazareno Conceição Silva de Jesus <mochileiro2006-trilhas@yahoo.com.br>. Copyright assigned to Soren Stoutner <soren@stoutner.com>.
+ Translation 2020-2021 Thiago Nazareno Conceição Silva de Jesus <mochileiro2006-trilhas@yahoo.com.br>. Copyright assigned to Soren Stoutner <soren@stoutner.com>.
This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
<h3><a href="https://www.stoutner.com/privacy-browser-3-7/">3.7</a> (código da versão 54)</h3>
<p><a href="https://gitweb.stoutner.com/?p=PrivacyBrowser.git;a=commitdiff;h=f3b9172adedd74f705ddc0beac80798ae84f2920">29 March 2021</a> - minimum API 19, target API 30</p>
<ul>
- <li>Redesign file access to work with <a href="https://redmine.stoutner.com/issues/546">scoped storage and the Storage Access Framework</a>.
- This allows the target API to be bumped to 30 and removes the need for the dangerous READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE permissions.
- Unfortunately, due to a bug in Android’s WebView, this also temporarily removes the ability to <a href="https://redmine.stoutner.com/issues/677">save a web archive</a>.</li>
- <li>Update <a href="https://redmine.stoutner.com/issues/678">About > Permissions</a>.</li>
- <li>Improve the descriptiveness of the <a href="https://redmine.stoutner.com/issues/676">save URL snackbar</a>.</li>
- <li>Add <a href="https://redmine.stoutner.com/issues/568">Metager</a> to the list of search engines.</li>
- <li>Fix <a href="https://redmine.stoutner.com/issues/674">I2P detection</a>.</li>
- <li>Fix the alignment of <a href="https://redmine.stoutner.com/issues/228">icons and radio buttons</a> in the dialogs.</li>
- <li>Update the URL bar when switching tabs <a href="https://redmine.stoutner.com/issues/654">even if it is being edited</a>.</li>
- <li>Allow <a href="https://redmine.stoutner.com/issues/620">displaying of the password</a> in the HTTP authentication dialog.</li>
- <li>Fix a <a href="https://redmine.stoutner.com/issues/645">number</a> <a href="https://redmine.stoutner.com/issues/646">of</a> <a href="https://redmine.stoutner.com/issues/651">rare</a>
- <a href="https://redmine.stoutner.com/issues/663">crashes</a>.</li>
- <li>Fix the hamburger icon <a href="https://redmine.stoutner.com/issues/616">turning into an arrow</a> if the drawer is open when the app is restarted.</li>
- <li>Speed up the opening of the <a href="https://redmine.stoutner.com/issues/650">options menu</a>.</li>
- <li>Updated Brazilian Portuguese translation provided by <a href="mailto:mochileiro2006-trilhas@yahoo.com.br">Thiago Nazareno Conceição Silva de Jesus</a>.</li>
+ <li>Remodele o acesso ao arquivo para funcionar com <a href="https://redmine.stoutner.com/issues/546">escopo de armazenamento definido e Estrutura de Acesso ao Armazenamento</a>.
+ Isso permite que a API de destino seja aumentada para 30 e remove a necessidade das perigosas permissões READ_EXTERNAL_STORAGE e WRITE_EXTERNAL_STORAGE.
+ Infelizmente, devido a um bug no WebView do Android, isso também remove temporariamente a capacidade de <a href="https://redmine.stoutner.com/issues/677">salvar um arquivo da web</a>.</li>
+ <li>Atualiza <a href="https://redmine.stoutner.com/issues/678">Sobre > Permissões</a>.</li>
+ <li>Melhora o texto da descrição da <a href="https://redmine.stoutner.com/issues/676">barra de salve URL</a>.</li>
+ <li>Adicione <a href="https://redmine.stoutner.com/issues/568">Metager</a> à lista de mecanismos de pesquisa.</li>
+ <li>Corrija a <a href="https://redmine.stoutner.com/issues/674">detecção I2P</a>.</li>
+ <li>Corrija o alinhamento de <a href="https://redmine.stoutner.com/issues/228">ícones e botões de opção</a> nas caixas de diálogo.</li>
+ <li>Atualize a barra de URL ao alternar entre as guias <a href="https://redmine.stoutner.com/issues/654">mesmo se estiver sendo editada</a>.</li>
+ <li>Permite <a href="https://redmine.stoutner.com/issues/620">a exibição da senha</a> na caixa de diálogo de autenticação HTTP.</li>
+ <li>Corrija um <a href="https://redmine.stoutner.com/issues/645">número</a> <a href="https://redmine.stoutner.com/issues/646">de</a> <a href="https://redmine.stoutner.com/issues/651">raro</a>
+ <a href="https://redmine.stoutner.com/issues/663">trava</a>.</li>
+ <li>Corrija o ícone de hambúrguer <a href="https://redmine.stoutner.com/issues/616">transformando-se em uma seta</a> se a gaveta for aberta quando o aplicativo for reiniciado.</li>
+ <li>Acelere a abertura do <a href="https://redmine.stoutner.com/issues/650">menu de opções</a>.</li>
+ <li>Tradução atualizada para o português do Brasil fornecida por <a href="mailto:mochileiro2006-trilhas@yahoo.com.br">Thiago Nazareno Conceição Silva de Jesus</a>.</li>
<li>Tradução francesa atualizada fornecida por <a href="mailto:kevinliste@framalistes.org">Kévin L</a>.</li>
<li>Tradução alemã atualizada fornecida por Bernhard G. Keller.</li>
<li>Tradução italiana atualizada fornecida por Francesco Buratti.</li>
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
// Get the screenshot preference.
- boolean allowScreenshots = sharedPreferences.getBoolean("allow_screenshots", false);
+ boolean allowScreenshots = sharedPreferences.getBoolean(getString(R.string.allow_screenshots_key), false);
// Disable screenshots if not allowed.
if (!allowScreenshots) {
import android.widget.TextView;
import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.app.AppCompatActivity;
// Consume the event.
return true;
} else if (menuItemId == R.id.save_archive) {
- // Instantiate the save dialog. TODO. Replace the hard coded file name.
- DialogFragment saveArchiveFragment = SaveWebpageDialog.saveWebpage(SaveWebpageDialog.SAVE_ARCHIVE, null, null, "Webpage.mht", null,
+ // Instantiate the save dialog.
+ DialogFragment saveArchiveFragment = SaveWebpageDialog.saveWebpage(SaveWebpageDialog.SAVE_ARCHIVE, currentWebView.getCurrentUrl(), null, null, null,
false);
// Show the save dialog. It must be named `save_dialog` so that the file picker can update the file name.
return true;
} else if (menuItemId == R.id.save_image) { // Save image.
// Instantiate the save dialog.
- DialogFragment saveImageFragment = SaveWebpageDialog.saveWebpage(SaveWebpageDialog.SAVE_IMAGE, null, null, getString(R.string.webpage_png), null,
+ DialogFragment saveImageFragment = SaveWebpageDialog.saveWebpage(SaveWebpageDialog.SAVE_IMAGE, currentWebView.getCurrentUrl(), null, null, null,
false);
// Show the save dialog. It must be named `save_dialog` so that the file picker can update the file name.
}
@Override
- public void onSaveWebpage(int saveType, @Nullable String originalUrlString, DialogFragment dialogFragment) {
+ public void onSaveWebpage(int saveType, @NonNull String originalUrlString, DialogFragment dialogFragment) {
// Get the dialog.
Dialog dialog = dialogFragment.getDialog();
String saveWebpageUrl;
// Store the URL.
- if ((originalUrlString != null) && originalUrlString.startsWith("data:")) {
+ if (originalUrlString.startsWith("data:")) {
// Save the original URL.
saveWebpageUrl = originalUrlString;
} else {
temporaryMhtFileInputStream.close();
// Display a snackbar.
- Snackbar.make(currentWebView, getString(R.string.file_saved) + " " + saveWebpageFilePath, Snackbar.LENGTH_SHORT).show();
+ Snackbar.make(currentWebView, getString(R.string.file_saved) + " " + currentWebView.getCurrentUrl(), Snackbar.LENGTH_SHORT).show();
} catch (Exception exception) {
// Display a snackbar with the exception.
Snackbar.make(currentWebView, getString(R.string.error_saving_file) + " " + exception.toString(), Snackbar.LENGTH_INDEFINITE).show();
}
// Prevent the dialog from displaying if the app window is not visible.
- // The asynctask continues to function even when the app is paused. Attempting to display a dialog in that state leads to a crash.
+ // The async task continues to function even when the app is paused. Attempting to display a dialog in that state leads to a crash.
while (!activity.getWindow().isActive()) {
try {
// The window is not active. Wait 1 second.
import android.content.DialogInterface
import android.content.Intent
import android.content.res.Configuration
+import android.net.Uri
import android.os.AsyncTask
import android.os.Bundle
import android.text.Editable
// The public interface is used to send information back to the parent activity.
interface SaveWebpageListener {
- fun onSaveWebpage(saveType: Int, originalUrlString: String?, dialogFragment: DialogFragment)
+ fun onSaveWebpage(saveType: Int, originalUrlString: String, dialogFragment: DialogFragment)
}
override fun onAttach(context: Context) {
// `@JvmStatic` will no longer be required once all the code has transitioned to Kotlin.
@JvmStatic
- fun saveWebpage(saveType: Int, urlString: String?, fileSizeString: String?, fileNameString: String, userAgentString: String?, cookiesEnabled: Boolean): SaveWebpageDialog {
+ fun saveWebpage(saveType: Int, urlString: String, fileSizeString: String?, fileNameString: String?, userAgentString: String?, cookiesEnabled: Boolean): SaveWebpageDialog {
// Create an arguments bundle.
val argumentsBundle = Bundle()
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
// Get the arguments from the bundle.
val saveType = requireArguments().getInt(SAVE_TYPE)
- val originalUrlString = requireArguments().getString(URL_STRING)
+ val originalUrlString = requireArguments().getString(URL_STRING)!!
val fileSizeString = requireArguments().getString(FILE_SIZE_STRING)
- val fileNameString = requireArguments().getString(FILE_NAME_STRING)!!
+ var fileNameString = requireArguments().getString(FILE_NAME_STRING)
val userAgentString = requireArguments().getString(USER_AGENT_STRING)
val cookiesEnabled = requireArguments().getBoolean(COOKIES_ENABLED)
// Get the current theme status.
val currentThemeStatus = resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK
- // Set the title and icon according to the save type.
+ // Configure the dialog according to the save type.
when (saveType) {
SAVE_URL -> {
// Set the title.
} else {
dialogBuilder.setIcon(R.drawable.dom_storage_cleared_night)
}
+
+ // Convert the URL to a URI.
+ val uri = Uri.parse(originalUrlString)
+
+ // Build a file name string based on the host from the URI.
+ fileNameString = uri.host + ".mht"
}
SAVE_IMAGE -> {
} else {
dialogBuilder.setIcon(R.drawable.images_enabled_night)
}
+
+ // Convert the URL to a URI.
+ val uri = Uri.parse(originalUrlString)
+
+ // Build a file name string based on the host from the URI.
+ fileNameString = uri.host + ".png"
}
}
// Modify the layout based on the save type.
if (saveType == SAVE_URL) { // A URL is being saved.
// Populate the URL edit text according to the type. This must be done before the text change listener is created below so that the file size isn't requested again.
- if (originalUrlString!!.startsWith("data:")) { // The URL contains the entire data of an image.
+ if (originalUrlString.startsWith("data:")) { // The URL contains the entire data of an image.
// Get a substring of the data URL with the first 100 characters. Otherwise, the user interface will freeze while trying to layout the edit text.
val urlSubstring = originalUrlString.substring(0, 100) + "…"
}
override fun shouldInterceptRequest(webView: WebView, url: String): WebResourceResponse? {
- // Have the WebView asset loader process the request. This allows the loading of SVG files, which otherwise is prevented by the CORS policy.
+ // Have the WebView asset loader process the request.
+ // This allows using the `appassets.androidplatform.net` URL, which handles the loading of SVG files, which otherwise is prevented by the CORS policy.
return webViewAssetLoader.shouldInterceptRequest(Uri.parse(url))
}
}
/*
- * Copyright © 2016-2020 Soren Stoutner <soren@stoutner.com>.
+ * Copyright © 2016-2021 Soren Stoutner <soren@stoutner.com>.
*
* This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
*
@Override
public WebResourceResponse shouldInterceptRequest(WebView webView, String url) {
- // Have the WebView asset loader process the request. This allows loading of SVG files, which otherwise is prevented by the CORS policy.
+ // Have the WebView asset loader process the request.
+ // This allows using the `appassets.androidplatform.net` URL, which handles the loading of SVG files, which otherwise is prevented by the CORS policy.
return webViewAssetLoader.shouldInterceptRequest(Uri.parse(url));
}
});
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright © 2016-2017 Soren Stoutner <soren@stoutner.com>.
+ Copyright © 2016-2017,2021 Soren Stoutner <soren@stoutner.com>.
This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
<WebView
android:id="@+id/bare_webview"
xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent" />
\ No newline at end of file
+ android:layout_height="match_parent"
+ android:layout_width="match_parent" />
\ No newline at end of file
<string name="save_image">Grafik speichern</string>
<string name="save_logcat">Logcat speichern</string>
<string name="file_name">Dateiname</string>
- <string name="webpage_png">Webseite.png</string>
<string name="privacy_browser_logcat_txt">Privacy Browser Logcat.txt</string>
<string name="privacy_browser_version_txt">Privacy Browser Version.txt</string>
<string name="privacy_browser_version_png">Privacy Browser Version.png</string>
<string name="save_image">Guardar imagen</string>
<string name="save_logcat">Guardar logcat</string>
<string name="file_name">Nombre de archivo</string>
- <string name="webpage_png">PaginaWeb.png</string>
<string name="privacy_browser_logcat_txt">Navegador Privado Logcat.txt</string>
<string name="privacy_browser_version_txt">Versión de Navegador Privado.txt</string>
<string name="privacy_browser_version_png">Versiótoutnern de Navegador Privado.png</string>
<string name="save_image">Sauvegarder en tant qu\'image</string>
<string name="save_logcat">Sauvegarder le journal système</string>
<string name="file_name">Nom du fichier</string>
- <string name="webpage_png">PageWeb.png</string>
<string name="privacy_browser_logcat_txt">Privacy Browser Logcat.txt</string>
<string name="privacy_browser_version_txt">Privacy Browser Version.txt</string>
<string name="privacy_browser_version_png">Privacy Browser Version.png</string>
<string name="save_image">Salva Immagine</string>
<string name="save_logcat">Salva il log</string>
<string name="file_name">Nome File</string>
- <string name="webpage_png">PaginaWeb.png</string>
<string name="privacy_browser_logcat_txt">Privacy Browser Logcat.txt</string>
<string name="privacy_browser_version_txt">Versione di Privacy Browser.txt</string>
<string name="privacy_browser_version_png">Versione di Privacy Browser.png</string>
<string name="save_image">Salvar Imagem</string>
<string name="save_logcat">Salvar logcat</string>
<string name="file_name">Nome do Arquivo</string>
- <string name="webpage_png">Pagina_Web.png</string>
<string name="privacy_browser_logcat_txt">Privacy Browser Logcat.txt</string>
<string name="privacy_browser_version_txt">Privacy Browser Versão.txt</string>
<string name="privacy_browser_version_png">Privacy Browser Versão.png</string>
<string name="save_image">Сохранить изображение</string>
<string name="save_logcat">Сохранить logcat</string>
<string name="file_name">Имя файла</string>
- <string name="webpage_png">Webpage.png</string>
<string name="privacy_browser_logcat_txt">Privacy Browser Logcat.txt</string>
<string name="privacy_browser_version_txt">Версия Privacy Browser.txt</string>
<string name="privacy_browser_version_png">Версия Privacy Browser.png</string>
<string name="save_image">Resmi kaydet</string>
<string name="save_logcat">Logcat kaydet</string>
<string name="file_name">Dosya adı</string>
- <string name="webpage_png">Websayfası.png</string>
<string name="unknown_size">Bilinmeyen boyut</string>
<string name="privacy_browser_logcat_txt">Privacy Browser Logcat.txt</string>
<string name="save_image">Save Image</string>
<string name="save_logcat">Save Logcat</string>
<string name="file_name">File name</string>
- <string name="webpage_png">Webpage.png</string>
<string name="privacy_browser_logcat_txt">Privacy Browser Logcat.txt</string>
<string name="privacy_browser_version_txt">Privacy Browser Version.txt</string>
<string name="privacy_browser_version_png">Privacy Browser Version.png</string>
-• Redesign file access to work with scoped storage and the Storage Access Framework. This allows the target API to be bumped to 30 and removes the need for the dangerous READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE permissions. Unfortunately, due to a bug in Android’s WebView, this also temporarily removes the ability to save a web archive.
-• Update About > Permissions.
-• Improve the descriptiveness of the save URL snackbar.
-• Add Metager to the list of search engines.
-• Fix I2P detection.
-• Fix the alignment of icons and radio buttons in the dialogs.
-• Update the URL bar when switching tabs even if it is being edited.
-• Allow displaying of the password in the HTTP authentication dialog.
-• Fix a number of rare crashes.
-• Fix the hamburger icon turning into an arrow if the drawer is open when the app is restarted.
-• Speed up the opening of the options menu.
-• Updated Brazilian Portuguese translation provided by Thiago Nazareno Conceição Silva de Jesus.
+• Remodele o acesso ao arquivo para funcionar com escopo de armazenamento definido e Estrutura de Acesso ao Armazenamento. Isso permite que a API de destino seja aumentada para 30 e remove a necessidade das perigosas permissões READ_EXTERNAL_STORAGE e WRITE_EXTERNAL_STORAGE. Infelizmente, devido a um bug no WebView do Android, isso também remove temporariamente a capacidade de salvar um arquivo da web.
+• Atualiza Sobre > Permissões.
+• Melhora o texto da descrição da barra de salve URL.
+• Adicione Metager à lista de mecanismos de pesquisa.
+• Corrija a detecção I2P.
+• Corrija o alinhamento de ícones e botões de opção nas caixas de diálogo.
+• Atualize a barra de URL ao alternar entre as guias mesmo se estiver sendo editada.
+• Permite a exibição da senha na caixa de diálogo de autenticação HTTP.
+• Corrija um número de raro trava.
+• Corrija o ícone de hambúrguer transformando-se em uma seta se a gaveta for aberta quando o aplicativo for reiniciado.
+• Acelere a abertura do menu de opções.
+• Tradução atualizada para o português do Brasil fornecida por Thiago Nazareno Conceição Silva de Jesus.
• Tradução francesa atualizada fornecida por Kévin L.
• Tradução alemã atualizada fornecida por Bernhard G. Keller.
• Tradução italiana atualizada fornecida por Francesco Buratti.