mirror of
https://github.com/PranshulGG/WeatherMaster.git
synced 2026-10-22 02:52:37 -05:00
Added an option to export or import the app data
This commit is contained in:
1 parent
d616a5ce25
commit
20c4f77eae
3 files changed
+239
-11
No files matched your search
@@ -22,9 +22,12 @@ function handleStorageChange(event) {
|
||||
break;
|
||||
case 'selectedMainWeatherProvider':
|
||||
setTimeout(() => {
|
||||
window.location.reload();
|
||||
sendThemeToAndroid('overcast')
|
||||
}, 1500);
|
||||
if(localStorage.getItem('selectedMainWeatherProvider') === 'Accuweather' && !localStorage.getItem('ApiForAccu')){
|
||||
} else{
|
||||
window.location.reload();
|
||||
sendThemeToAndroid('overcast')
|
||||
}
|
||||
}, 1500);
|
||||
break;
|
||||
case 'ApiForAccu':
|
||||
setTimeout(() => {
|
||||
@@ -53,14 +56,18 @@ window.addEventListener('storage', handleStorageChange);
|
||||
|
||||
// apply when options are changed
|
||||
|
||||
function HandleNoReloadSettings() {
|
||||
let debounceTimer;
|
||||
|
||||
const renderLocation = localStorage.getItem('CurrentLocationName')
|
||||
setTimeout(() =>{
|
||||
LoadLocationOnRequest(localStorage.getItem('currentLat'), localStorage.getItem('currentLong'), renderLocation)
|
||||
onAllLocationsLoaded()
|
||||
}, 300);
|
||||
}
|
||||
function HandleNoReloadSettings() {
|
||||
const renderLocation = localStorage.getItem('CurrentLocationName');
|
||||
|
||||
clearTimeout(debounceTimer);
|
||||
|
||||
debounceTimer = setTimeout(() => {
|
||||
LoadLocationOnRequest(localStorage.getItem('currentLat'), localStorage.getItem('currentLong'), renderLocation);
|
||||
onAllLocationsLoaded();
|
||||
}, 500);
|
||||
}
|
||||
|
||||
|
||||
function RemoveDisplayedAnimations() {
|
||||
|
||||
@@ -324,6 +324,20 @@
|
||||
<md-icon icon-outlined slot="end">open_in_new</md-icon>
|
||||
</md-list-item>
|
||||
|
||||
<md-list-item type="button" id="exportAppData">
|
||||
<md-icon icon-filled slot="start">upgrade</md-icon>
|
||||
<div slot="headline">Export data</div>
|
||||
<div slot="supporting-text">Export all your settings, locations, and their last fetched weather data—literally everything!</div>
|
||||
</md-list-item>
|
||||
|
||||
|
||||
<md-list-item type="button" id="importAppData">
|
||||
<md-icon icon-filled slot="start">download</md-icon>
|
||||
<div slot="headline">Import data</div>
|
||||
<div slot="supporting-text" style="color: var(--Error);">Warning: Importing will erase your current app data</div>
|
||||
</md-list-item>
|
||||
<input type="file" id="ImportFile" style="display:none;" accept="application/json">
|
||||
|
||||
</md-list>
|
||||
|
||||
|
||||
@@ -1093,6 +1107,59 @@ function ChangeSelectedMainProviderName() {
|
||||
} else{
|
||||
document.getElementById('useWeatherAlerts').selected = true
|
||||
}
|
||||
|
||||
document.getElementById("exportAppData").addEventListener("click", () => {
|
||||
|
||||
|
||||
|
||||
const data = { ...localStorage };
|
||||
|
||||
// Check if local storage has data
|
||||
if (Object.keys(data).length > 0) {
|
||||
// Convert data to JSON string
|
||||
const jsonData = JSON.stringify(data, null, 2);
|
||||
|
||||
// Use Android interface to save the file
|
||||
Android.saveFile(jsonData);
|
||||
} else {
|
||||
// Show toast message if no data is found
|
||||
ShowSnackMessage.ShowSnack("No data found", "short");
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById('importAppData').addEventListener('click', () => {
|
||||
Android.importFile();
|
||||
});
|
||||
|
||||
function handleImportedData(importedData) {
|
||||
try {
|
||||
const data = JSON.parse(importedData);
|
||||
|
||||
if (typeof data !== "object" || data === null) {
|
||||
throw new Error("Invalid data format");
|
||||
}
|
||||
|
||||
localStorage.clear();
|
||||
|
||||
|
||||
setTimeout(() => {
|
||||
for (const [key, value] of Object.entries(data)) {
|
||||
localStorage.setItem(key, value);
|
||||
|
||||
}
|
||||
ShowSnackMessage.ShowSnack("Data imported successfully!", "short");
|
||||
|
||||
}, 1000);
|
||||
setTimeout(() => {
|
||||
Android.reloadTheApp();
|
||||
}, 1500);
|
||||
|
||||
} catch (error) {
|
||||
ShowSnackMessage.ShowSnack("Error parsing the imported JSON data. Please ensure it is valid and correctly formatted.", "long");
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
</script>
|
||||
|
||||
|
||||
@@ -21,6 +21,8 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.WindowManager;
|
||||
import android.webkit.JavascriptInterface;
|
||||
import android.webkit.ValueCallback;
|
||||
import android.webkit.WebChromeClient;
|
||||
import android.webkit.WebSettings;
|
||||
import android.webkit.WebView;
|
||||
import android.webkit.WebViewClient;
|
||||
@@ -30,6 +32,7 @@ import android.widget.Toast;
|
||||
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
@@ -38,9 +41,26 @@ import androidx.core.content.res.ResourcesCompat;
|
||||
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class SettingsActivity extends AppCompatActivity {
|
||||
|
||||
private WebView webview;
|
||||
|
||||
private ValueCallback<Uri[]> filePathCallback;
|
||||
private final static int FILECHOOSER_RESULTCODE = 1;
|
||||
private final static int EXPORT_REQUEST_CODE = 2;
|
||||
private static final int PERMISSION_REQUEST_CODE = 1;
|
||||
private static final int SAVE_DOCUMENT_REQUEST_CODE = 2;
|
||||
private static final int IMPORT_REQUEST_CODE = 3;
|
||||
|
||||
private String dataToSave;
|
||||
private boolean isFirstLoad = true;
|
||||
|
||||
public void onBackPressed() {
|
||||
@@ -75,6 +95,7 @@ public class SettingsActivity extends AppCompatActivity {
|
||||
webview.addJavascriptInterface(androidInterface, "AndroidInterface");
|
||||
webview.addJavascriptInterface(new ShowToastInterface(this), "ToastAndroidShow");
|
||||
webview.addJavascriptInterface(new ShowSnackInterface(this), "ShowSnackMessage");
|
||||
webview.addJavascriptInterface(new WebAppInterface(), "Android");
|
||||
webview.setBackgroundColor(getResources().getColor(R.color.yellowBg));
|
||||
|
||||
webview.loadUrl("file:///android_asset/pages/settings.html");
|
||||
@@ -107,12 +128,141 @@ public class SettingsActivity extends AppCompatActivity {
|
||||
webview.evaluateJavascript(jsCodePrimaryColor, null);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
|
||||
if (requestCode == FILECHOOSER_RESULTCODE) {
|
||||
if (filePathCallback != null) {
|
||||
Uri[] results = null;
|
||||
if (resultCode == RESULT_OK && data != null) {
|
||||
String dataString = data.getDataString();
|
||||
if (dataString != null) {
|
||||
results = new Uri[]{Uri.parse(dataString)};
|
||||
}
|
||||
}
|
||||
filePathCallback.onReceiveValue(results);
|
||||
filePathCallback = null;
|
||||
}
|
||||
} else if (requestCode == SAVE_DOCUMENT_REQUEST_CODE) {
|
||||
if (resultCode == RESULT_OK && data != null && data.getData() != null) {
|
||||
saveToUri(data.getData());
|
||||
} else {
|
||||
Toast.makeText(this, "Error exporting", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
} else if (requestCode == IMPORT_REQUEST_CODE) {
|
||||
if (resultCode == RESULT_OK && data != null && data.getData() != null) {
|
||||
importFromUri(data.getData());
|
||||
} else {
|
||||
Toast.makeText(this, "Error importing file", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void restartApp() {
|
||||
Toast.makeText(this, "App is restarting...", Toast.LENGTH_SHORT).show();
|
||||
|
||||
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
|
||||
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||
|
||||
startActivity(intent);
|
||||
|
||||
finish();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public class WebAppInterface {
|
||||
@JavascriptInterface
|
||||
public void saveFile(String data) {
|
||||
dataToSave = data;
|
||||
openFilePickerExport();
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
public void importFile() {
|
||||
openFilePickerImport(); // Open file picker for importing JSON data
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
public void reloadTheApp() {
|
||||
restartApp(); // Open file picker for importing JSON data
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private void openFilePickerExport() {
|
||||
Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
intent.setType("application/json");
|
||||
intent.putExtra(Intent.EXTRA_TITLE, "WeatherMasterData.json");
|
||||
startActivityForResult(intent, SAVE_DOCUMENT_REQUEST_CODE);
|
||||
}
|
||||
|
||||
private void openFilePickerImport() {
|
||||
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
intent.setType("application/json");
|
||||
startActivityForResult(intent, IMPORT_REQUEST_CODE);
|
||||
}
|
||||
|
||||
private void importFromUri(Uri uri) {
|
||||
try {
|
||||
InputStream inputStream = getContentResolver().openInputStream(uri);
|
||||
if (inputStream != null) {
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
stringBuilder.append(line);
|
||||
}
|
||||
reader.close();
|
||||
inputStream.close();
|
||||
|
||||
String importedData = stringBuilder.toString();
|
||||
|
||||
String escapedData = importedData.replace("'", "\\'").replace("\"", "\\\"");
|
||||
|
||||
runOnUiThread(() -> {
|
||||
String jsCode = "handleImportedData('" + escapedData + "');";
|
||||
webview.evaluateJavascript(jsCode, null);
|
||||
});
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Toast.makeText(this, "Error reading file", Toast.LENGTH_LONG).show();
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void saveToUri(Uri uri) {
|
||||
try {
|
||||
OutputStream outputStream = getContentResolver().openOutputStream(uri);
|
||||
if (outputStream != null) {
|
||||
outputStream.write(dataToSave.getBytes());
|
||||
outputStream.close();
|
||||
Toast.makeText(this, "Backup saved", Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
Toast.makeText(this, "Error", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Toast.makeText(this, "Error saving file", Toast.LENGTH_LONG).show();
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
private void requestNotificationPermissions() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.POST_NOTIFICATIONS)
|
||||
@@ -201,6 +351,10 @@ public class SettingsActivity extends AppCompatActivity {
|
||||
}
|
||||
}
|
||||
|
||||
// export or import data
|
||||
|
||||
|
||||
|
||||
public class AndroidInterface {
|
||||
private SettingsActivity sActivity;
|
||||
|
||||
|
||||
Reference in new issue
Block a user