]> gitweb.stoutner.com Git - PrivacyBrowserAndroid.git/blobdiff - app/src/main/java/com/stoutner/privacybrowser/activities/ImportExportActivity.java
Switch to using AndroidX's ProxyController. https://redmine.stoutner.com/issues/486
[PrivacyBrowserAndroid.git] / app / src / main / java / com / stoutner / privacybrowser / activities / ImportExportActivity.java
index 80a3a98f8e5b059b9b924ea969c1898499935cd7..1c328c4d07119e759f3fb60b6a01a66781c02fe9 100644 (file)
@@ -22,24 +22,16 @@ package com.stoutner.privacybrowser.activities;
 import android.Manifest;
 import android.app.Activity;
 import android.content.Intent;
+import android.content.SharedPreferences;
 import android.content.pm.PackageManager;
 import android.media.MediaScannerConnection;
 import android.net.Uri;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Environment;
+import android.os.Handler;
+import android.preference.PreferenceManager;
 import android.provider.DocumentsContract;
-import android.support.annotation.NonNull;
-import android.support.design.widget.Snackbar;
-import android.support.design.widget.TextInputLayout;
-import android.support.v4.app.ActivityCompat;
-import android.support.v4.app.DialogFragment;
-import android.support.v4.content.ContextCompat;
-import android.support.v4.content.FileProvider;
-import android.support.v7.app.ActionBar;
-import android.support.v7.app.AppCompatActivity;
-import android.support.v7.widget.CardView;
-import android.support.v7.widget.Toolbar;
 import android.text.Editable;
 import android.text.TextWatcher;
 import android.view.View;
@@ -53,8 +45,22 @@ import android.widget.RadioButton;
 import android.widget.Spinner;
 import android.widget.TextView;
 
+import androidx.annotation.NonNull;
+import androidx.appcompat.app.ActionBar;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.widget.Toolbar;
+import androidx.cardview.widget.CardView;
+import androidx.core.app.ActivityCompat;
+import androidx.core.content.ContextCompat;
+import androidx.core.content.FileProvider;
+import androidx.fragment.app.DialogFragment;
+
+import com.google.android.material.snackbar.Snackbar;
+import com.google.android.material.textfield.TextInputLayout;
+
 import com.stoutner.privacybrowser.R;
 import com.stoutner.privacybrowser.dialogs.StoragePermissionDialog;
+import com.stoutner.privacybrowser.helpers.FileNameHelper;
 import com.stoutner.privacybrowser.helpers.ImportExportDatabaseHelper;
 
 import java.io.File;
@@ -86,13 +92,20 @@ public class ImportExportActivity extends AppCompatActivity implements StoragePe
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
+        // Get a handle for the shared preferences.
+        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
+
+        // Get the theme and screenshot preferences.
+        boolean darkTheme = sharedPreferences.getBoolean("dark_theme", false);
+        boolean allowScreenshots = sharedPreferences.getBoolean("allow_screenshots", false);
+
         // Disable screenshots if not allowed.
-        if (!MainWebViewActivity.allowScreenshots) {
+        if (!allowScreenshots) {
             getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
         }
 
         // Set the activity theme.
-        if (MainWebViewActivity.darkTheme) {
+        if (darkTheme) {
             setTheme(R.style.PrivacyBrowserDark_SecondaryActivity);
         } else {
             setTheme(R.style.PrivacyBrowserLight_SecondaryActivity);
@@ -105,13 +118,17 @@ public class ImportExportActivity extends AppCompatActivity implements StoragePe
         setContentView(R.layout.import_export_coordinatorlayout);
 
         // Use the `SupportActionBar` from `android.support.v7.app.ActionBar` until the minimum API is >= 21.
-        Toolbar importExportAppBar = findViewById(R.id.import_export_toolbar);
-        setSupportActionBar(importExportAppBar);
+        Toolbar toolbar = findViewById(R.id.import_export_toolbar);
+        setSupportActionBar(toolbar);
+
+        // Get a handle for the action bar.
+        ActionBar actionBar = getSupportActionBar();
+
+        // Remove the incorrect lint warning that the action bar might be null.
+        assert actionBar != null;
 
         // Display the home arrow on the support action bar.
-        ActionBar appBar = getSupportActionBar();
-        assert appBar != null;// This assert removes the incorrect warning in Android Studio on the following line that `appBar` might be null.
-        appBar.setDisplayHomeAsUpEnabled(true);
+        actionBar.setDisplayHomeAsUpEnabled(true);
 
         // Find out if we are running KitKat
         boolean runningKitKat = (Build.VERSION.SDK_INT == 19);
@@ -162,11 +179,11 @@ public class ImportExportActivity extends AppCompatActivity implements StoragePe
         // Set the default file paths according to the storage permission status.
         if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {  // The storage permission has been granted.
             // Set the default file paths to use the external public directory.
-            defaultFilePath = Environment.getExternalStorageDirectory() + "/" + getString(R.string.privacy_browser_settings_pbs);
+            defaultFilePath = Environment.getExternalStorageDirectory() + "/" + getString(R.string.settings_pbs);
             defaultPasswordEncryptionFilePath = defaultFilePath + ".aes";
         } else {  // The storage permission has not been granted.
             // Set the default file paths to use the external private directory.
-            defaultFilePath = getApplicationContext().getExternalFilesDir(null) + "/" + getString(R.string.privacy_browser_settings_pbs);
+            defaultFilePath = getApplicationContext().getExternalFilesDir(null) + "/" + getString(R.string.settings_pbs);
             defaultPasswordEncryptionFilePath = defaultFilePath + ".aes";
         }
 
@@ -438,7 +455,7 @@ public class ImportExportActivity extends AppCompatActivity implements StoragePe
             exportBrowseIntent.setType("*/*");
 
             // Set the initial export file name.
-            exportBrowseIntent.putExtra(Intent.EXTRA_TITLE, getString(R.string.privacy_browser_settings_pbs));
+            exportBrowseIntent.putExtra(Intent.EXTRA_TITLE, getString(R.string.settings_pbs));
 
             // Set the initial directory if the minimum API >= 26.
             if (Build.VERSION.SDK_INT >= 26) {
@@ -542,7 +559,10 @@ public class ImportExportActivity extends AppCompatActivity implements StoragePe
     }
 
     @Override
-    public void onActivityResult(int requestCode, int resultCode, Intent data) {
+    public void onActivityResult(int requestCode, int resultCode, Intent intent) {
+        // Run the default commands.
+        super.onActivityResult(requestCode, resultCode, intent);
+
         switch (requestCode) {
             case (BROWSE_RESULT_CODE):
                 // Don't do anything if the user pressed back from the file picker.
@@ -550,56 +570,26 @@ public class ImportExportActivity extends AppCompatActivity implements StoragePe
                     // Get a handle for the file name edit text.
                     EditText fileNameEditText = findViewById(R.id.file_name_edittext);
 
-                    // Get the file name URI.
-                    Uri fileNameUri = data.getData();
-
-                    // Remove the lint warning that the file name URI might be null.
-                    assert fileNameUri != null;
-
-                    // Get the raw file name path.
-                    String rawFileNamePath = fileNameUri.getPath();
+                    // Instantiate the file name helper.
+                    FileNameHelper fileNameHelper = new FileNameHelper();
 
-                    // Remove the incorrect lint warning that the file name path might be null.
-                    assert rawFileNamePath != null;
+                    // Get the file path URI from the intent.
+                    Uri filePathUri = intent.getData();
 
-                    // Check to see if the file name Path includes a valid storage location.
-                    if (rawFileNamePath.contains(":")) {  // The path is valid.
-                        // Split the path into the initial content uri and the final path information.
-                        String fileNameContentPath = rawFileNamePath.substring(0, rawFileNamePath.indexOf(":"));
-                        String fileNameFinalPath = rawFileNamePath.substring(rawFileNamePath.indexOf(":") + 1);
+                    // Use the file path from the intent if it exists.
+                    if (filePathUri != null) {
+                        // Convert the file name URI to a file name path.
+                        String fileNamePath = fileNameHelper.convertUriToFileNamePath(filePathUri);
 
-                        // Create the file name path string.
-                        String fileNamePath;
-
-                        // Construct the file name path.
-                        switch (fileNameContentPath) {
-                            // The documents home has a special content path.
-                            case "/document/home":
-                                fileNamePath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS) + "/" + fileNameFinalPath;
-                                break;
-
-                            // Everything else for the primary user should be in `/document/primary`.
-                            case "/document/primary":
-                                fileNamePath = Environment.getExternalStorageDirectory() + "/" + fileNameFinalPath;
-                                break;
-
-                            // Just in case, catch everything else and place it in the external storage directory.
-                            default:
-                                fileNamePath = Environment.getExternalStorageDirectory() + "/" + fileNameFinalPath;
-                                break;
-                        }
-
-                        // Set the file name path as the text of the file name EditText.
+                        // Set the file name path as the text of the file name edit text.
                         fileNameEditText.setText(fileNamePath);
-                    } else {  // The path is invalid.
-                        Snackbar.make(fileNameEditText, rawFileNamePath + " " + getString(R.string.invalid_location), Snackbar.LENGTH_INDEFINITE).show();
                     }
                 }
                 break;
 
             case OPENPGP_EXPORT_RESULT_CODE:
                 // Get the temporary unencrypted export file.
-                File temporaryUnencryptedExportFile = new File(getApplicationContext().getCacheDir() + "/" + getString(R.string.privacy_browser_settings_pbs));
+                File temporaryUnencryptedExportFile = new File(getApplicationContext().getCacheDir() + "/" + getString(R.string.settings_pbs));
 
                 // Delete the temporary unencrypted export file if it exists.
                 if (temporaryUnencryptedExportFile.exists()) {
@@ -623,7 +613,7 @@ public class ImportExportActivity extends AppCompatActivity implements StoragePe
 
         // Get the export and temporary unencrypted export files.
         File exportFile = new File(exportFileString);
-        File temporaryUnencryptedExportFile = new File(getApplicationContext().getCacheDir() + "/" + getString(R.string.privacy_browser_settings_pbs));
+        File temporaryUnencryptedExportFile = new File(getApplicationContext().getCacheDir() + "/" + getString(R.string.settings_pbs));
 
         // Create an export status string.
         String exportStatus;
@@ -802,7 +792,7 @@ public class ImportExportActivity extends AppCompatActivity implements StoragePe
 
             case PASSWORD_ENCRYPTION:
                 // Use a private temporary import location.
-                File temporaryUnencryptedImportFile = new File(getApplicationContext().getCacheDir() + "/" + getString(R.string.privacy_browser_settings_pbs));
+                File temporaryUnencryptedImportFile = new File(getApplicationContext().getCacheDir() + "/" + getString(R.string.settings_pbs));
 
                 try {
                     // Create an encrypted import file input stream.
@@ -937,8 +927,21 @@ public class ImportExportActivity extends AppCompatActivity implements StoragePe
             // `Intent.FLAG_ACTIVITY_CLEAR_TASK` removes all activities from the stack.  It requires `Intent.FLAG_ACTIVITY_NEW_TASK`.
             restartIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
 
-            // Make it so.
-            startActivity(restartIntent);
+            // Create a restart handler.
+            Handler restartHandler = new Handler();
+
+            // Create a restart runnable.
+            Runnable restartRunnable =  () -> {
+                // Restart Privacy Browser.
+                startActivity(restartIntent);
+
+                // Kill this instance of Privacy Browser.  Otherwise, the app exhibits sporadic behavior after the restart.
+                System.exit(0);
+            };
+
+            // Restart Privacy Browser after 150 milliseconds to allow enough time for the preferences to be saved.
+            restartHandler.postDelayed(restartRunnable, 150);
+
         } else if (!(encryptionSpinner.getSelectedItemPosition() == OPENPGP_ENCRYPTION)){  // The import was not successful.
             // Display a snack bar with the import error.
             Snackbar.make(fileNameEditText, getString(R.string.import_failed) + "  " + importStatus, Snackbar.LENGTH_INDEFINITE).show();