Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c488052501 | |||
| 06e3d7972f | |||
| 5ec72eddd4 | |||
| c37f51bff8 |
Generated
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="CompilerConfiguration">
|
<component name="CompilerConfiguration">
|
||||||
<bytecodeTargetLevel target="1.8" />
|
<bytecodeTargetLevel target="11" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
Generated
+8
@@ -0,0 +1,8 @@
|
|||||||
|
<component name="ProjectDictionaryState">
|
||||||
|
<dictionary name="Joel">
|
||||||
|
<words>
|
||||||
|
<w>videomeetings</w>
|
||||||
|
<w>zoomhelper</w>
|
||||||
|
</words>
|
||||||
|
</dictionary>
|
||||||
|
</component>
|
||||||
Generated
+2
-2
@@ -4,10 +4,11 @@
|
|||||||
<component name="GradleSettings">
|
<component name="GradleSettings">
|
||||||
<option name="linkedExternalProjectsSettings">
|
<option name="linkedExternalProjectsSettings">
|
||||||
<GradleProjectSettings>
|
<GradleProjectSettings>
|
||||||
|
<option name="delegatedBuild" value="true" />
|
||||||
<option name="testRunner" value="PLATFORM" />
|
<option name="testRunner" value="PLATFORM" />
|
||||||
<option name="disableWrapperSourceDistributionNotification" value="true" />
|
|
||||||
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
||||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||||
|
<option name="gradleJvm" value="14" />
|
||||||
<option name="modules">
|
<option name="modules">
|
||||||
<set>
|
<set>
|
||||||
<option value="$PROJECT_DIR$" />
|
<option value="$PROJECT_DIR$" />
|
||||||
@@ -15,7 +16,6 @@
|
|||||||
</set>
|
</set>
|
||||||
</option>
|
</option>
|
||||||
<option name="resolveModulePerSourceSet" value="false" />
|
<option name="resolveModulePerSourceSet" value="false" />
|
||||||
<option name="useQualifiedModuleNames" value="true" />
|
|
||||||
</GradleProjectSettings>
|
</GradleProjectSettings>
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
|
|||||||
Generated
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="false" project-jdk-name="Android API 30 Platform" project-jdk-type="Android SDK">
|
||||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectType">
|
<component name="ProjectType">
|
||||||
|
|||||||
Generated
+10
@@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="RunConfigurationProducerService">
|
||||||
|
<option name="ignoredProducers">
|
||||||
|
<set>
|
||||||
|
<option value="com.android.tools.idea.compose.preview.runconfiguration.ComposePreviewRunConfigurationProducer" />
|
||||||
|
</set>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
+1
-1
@@ -36,7 +36,7 @@ repositories {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|
||||||
implementation 'androidx.appcompat:appcompat:1.2.0'
|
implementation 'androidx.appcompat:appcompat:1.3.0'
|
||||||
implementation 'com.google.android.material:material:1.3.0'
|
implementation 'com.google.android.material:material:1.3.0'
|
||||||
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
|
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
|
||||||
implementation 'androidx.lifecycle:lifecycle-process:2.3.1'
|
implementation 'androidx.lifecycle:lifecycle-process:2.3.1'
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:allowBackup="true"
|
android:allowBackup="false"
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
|
|||||||
@@ -0,0 +1,111 @@
|
|||||||
|
package de.joel.zoomhelper;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.os.Environment;
|
||||||
|
|
||||||
|
import androidx.annotation.RequiresApi;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.security.InvalidAlgorithmParameterException;
|
||||||
|
import java.security.InvalidKeyException;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.spec.InvalidKeySpecException;
|
||||||
|
|
||||||
|
import javax.crypto.BadPaddingException;
|
||||||
|
import javax.crypto.IllegalBlockSizeException;
|
||||||
|
import javax.crypto.NoSuchPaddingException;
|
||||||
|
|
||||||
|
public class BackupController {
|
||||||
|
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||||
|
public void backup(Activity activity) {
|
||||||
|
Encrypter encrypter = new Encrypter();
|
||||||
|
SharedPreferences mPrefs = activity.getPreferences(Context.MODE_PRIVATE);
|
||||||
|
String value = mPrefs.getString("Meetings", "");
|
||||||
|
File destination = new File(activity.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath(), "backup.tmp");
|
||||||
|
|
||||||
|
try {
|
||||||
|
writeStringToFile(value, destination.getAbsolutePath());
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
//TODO: Eingabefeld für Passwort
|
||||||
|
try {
|
||||||
|
encrypter.encrypt(destination.getAbsolutePath(), "test");
|
||||||
|
} catch (BadPaddingException | IllegalBlockSizeException | IOException | NoSuchAlgorithmException | InvalidKeySpecException | InvalidAlgorithmParameterException | InvalidKeyException | NoSuchPaddingException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
//noinspection ResultOfMethodCallIgnored
|
||||||
|
destination.delete();
|
||||||
|
destination = new File(activity.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath(), "backup.zoomhelper");
|
||||||
|
|
||||||
|
shareFile(destination, activity);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void restore(Activity activity) {
|
||||||
|
new FileChooser(activity).openFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressLint("ApplySharedPref")
|
||||||
|
public void restore(Activity activity, InputStream inp) {
|
||||||
|
Encrypter encrypter = new Encrypter();
|
||||||
|
SharedPreferences mPrefs = activity.getPreferences(Context.MODE_PRIVATE);
|
||||||
|
|
||||||
|
String decrypted = null;
|
||||||
|
|
||||||
|
//TODO: Passwort einlesen aus Eingabefeld
|
||||||
|
try {
|
||||||
|
decrypted = encrypter.decrypt(inp, "test");
|
||||||
|
} catch (IOException | InvalidAlgorithmParameterException | InvalidKeyException | NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeySpecException | IllegalBlockSizeException | BadPaddingException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: Hinweis, dass Daten mit den Daten aus dem Backup überschrieben werden...
|
||||||
|
|
||||||
|
SharedPreferences.Editor prefsEditor = mPrefs.edit();
|
||||||
|
prefsEditor.putString("Meetings",decrypted);
|
||||||
|
prefsEditor.commit();
|
||||||
|
|
||||||
|
prefsEditor.putString("lastMeeting", "0");
|
||||||
|
|
||||||
|
//TODO: Fehlermeldung bei falschem Passwort
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void writeStringToFile(String str, String fileName)
|
||||||
|
throws IOException {
|
||||||
|
FileOutputStream outputStream = new FileOutputStream(fileName);
|
||||||
|
byte[] strToBytes = str.getBytes();
|
||||||
|
outputStream.write(strToBytes);
|
||||||
|
|
||||||
|
outputStream.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void shareFile(File file, Activity activity){
|
||||||
|
Intent intentShareFile = new Intent(Intent.ACTION_SEND);
|
||||||
|
|
||||||
|
if(file.exists()) {
|
||||||
|
intentShareFile.setType("application/octet-stream");
|
||||||
|
intentShareFile.putExtra(Intent.EXTRA_STREAM, Uri.parse(file.getAbsolutePath()));
|
||||||
|
|
||||||
|
intentShareFile.putExtra(Intent.EXTRA_SUBJECT,
|
||||||
|
"Sharing File...");
|
||||||
|
intentShareFile.putExtra(Intent.EXTRA_TEXT, "Sharing File...");
|
||||||
|
|
||||||
|
activity.startActivity(Intent.createChooser(intentShareFile, "Share File"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,154 @@
|
|||||||
|
package de.joel.zoomhelper;
|
||||||
|
|
||||||
|
import android.os.Build;
|
||||||
|
import android.os.Environment;
|
||||||
|
|
||||||
|
import androidx.annotation.RequiresApi;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.security.InvalidAlgorithmParameterException;
|
||||||
|
import java.security.InvalidKeyException;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.spec.InvalidKeySpecException;
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
|
||||||
|
import javax.crypto.BadPaddingException;
|
||||||
|
import javax.crypto.Cipher;
|
||||||
|
import javax.crypto.IllegalBlockSizeException;
|
||||||
|
import javax.crypto.NoSuchPaddingException;
|
||||||
|
import javax.crypto.SecretKeyFactory;
|
||||||
|
import javax.crypto.SecretKey;
|
||||||
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
import java.security.spec.KeySpec;
|
||||||
|
import javax.crypto.spec.PBEKeySpec;
|
||||||
|
import javax.crypto.spec.IvParameterSpec;
|
||||||
|
|
||||||
|
public class Encrypter {
|
||||||
|
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||||
|
public void encrypt(String inputFile, String password) throws BadPaddingException, IllegalBlockSizeException, IOException, NoSuchAlgorithmException, InvalidKeySpecException, InvalidAlgorithmParameterException, InvalidKeyException, NoSuchPaddingException {
|
||||||
|
SecureRandom srandom = null;
|
||||||
|
try {
|
||||||
|
srandom = SecureRandom.getInstanceStrong();
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
byte[] salt = new byte[8];
|
||||||
|
assert srandom != null;
|
||||||
|
srandom.nextBytes(salt);
|
||||||
|
SecretKeyFactory factory =
|
||||||
|
SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
|
||||||
|
|
||||||
|
KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 10000, 128);
|
||||||
|
SecretKey tmp = factory.generateSecret(spec);
|
||||||
|
SecretKeySpec skey = new SecretKeySpec(tmp.getEncoded(), "AES");
|
||||||
|
|
||||||
|
byte[] iv = new byte[128 / 8];
|
||||||
|
srandom.nextBytes(iv);
|
||||||
|
IvParameterSpec ivspec = new IvParameterSpec(iv);
|
||||||
|
|
||||||
|
FileOutputStream out = null;
|
||||||
|
out = new FileOutputStream(inputFile + ".enc");
|
||||||
|
out.write(salt);
|
||||||
|
out.write(iv);
|
||||||
|
|
||||||
|
Cipher ci = null;
|
||||||
|
|
||||||
|
ci = Cipher.getInstance("AES/CBC/PKCS5Padding");
|
||||||
|
|
||||||
|
ci.init(Cipher.ENCRYPT_MODE, skey, ivspec);
|
||||||
|
|
||||||
|
try (FileInputStream in = new FileInputStream(inputFile)) {
|
||||||
|
processFile(ci, in, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static private void processFile(Cipher ci, InputStream in, OutputStream out)
|
||||||
|
throws javax.crypto.IllegalBlockSizeException,
|
||||||
|
javax.crypto.BadPaddingException,
|
||||||
|
java.io.IOException {
|
||||||
|
byte[] ibuf = new byte[1024];
|
||||||
|
int len;
|
||||||
|
while ((len = in.read(ibuf)) != -1) {
|
||||||
|
byte[] obuf = ci.update(ibuf, 0, len);
|
||||||
|
if (obuf != null) out.write(obuf);
|
||||||
|
}
|
||||||
|
byte[] obuf = ci.doFinal();
|
||||||
|
if (obuf != null) out.write(obuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("ResultOfMethodCallIgnored")
|
||||||
|
public String decrypt(String inputFile, String password) throws IOException, InvalidAlgorithmParameterException, InvalidKeyException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeySpecException, IllegalBlockSizeException, BadPaddingException {
|
||||||
|
FileInputStream in = new FileInputStream(inputFile);
|
||||||
|
byte[] salt = new byte[8], iv = new byte[128 / 8];
|
||||||
|
in.read(salt);
|
||||||
|
in.read(iv);
|
||||||
|
|
||||||
|
SecretKeyFactory factory =
|
||||||
|
SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
|
||||||
|
|
||||||
|
KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 10000, 128);
|
||||||
|
SecretKey tmp = factory.generateSecret(spec);
|
||||||
|
SecretKeySpec skey = new SecretKeySpec(tmp.getEncoded(), "AES");
|
||||||
|
|
||||||
|
Cipher ci = Cipher.getInstance("AES/CBC/PKCS5Padding");
|
||||||
|
ci.init(Cipher.DECRYPT_MODE, skey, new IvParameterSpec(iv));
|
||||||
|
|
||||||
|
|
||||||
|
OutputStream out = new OutputStream() {
|
||||||
|
private final StringBuilder string = new StringBuilder();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(int b) throws IOException {
|
||||||
|
this.string.append((char) b );
|
||||||
|
}
|
||||||
|
|
||||||
|
//Netbeans IDE automatically overrides this toString()
|
||||||
|
public String toString() {
|
||||||
|
return this.string.toString();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
processFile(ci, in, out);
|
||||||
|
return out.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String decrypt(InputStream in, String password) throws IOException, InvalidAlgorithmParameterException, InvalidKeyException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeySpecException, IllegalBlockSizeException, BadPaddingException {
|
||||||
|
byte[] salt = new byte[8], iv = new byte[128 / 8];
|
||||||
|
in.read(salt);
|
||||||
|
in.read(iv);
|
||||||
|
|
||||||
|
SecretKeyFactory factory =
|
||||||
|
SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
|
||||||
|
|
||||||
|
KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 10000, 128);
|
||||||
|
SecretKey tmp = factory.generateSecret(spec);
|
||||||
|
SecretKeySpec skey = new SecretKeySpec(tmp.getEncoded(), "AES");
|
||||||
|
|
||||||
|
Cipher ci = Cipher.getInstance("AES/CBC/PKCS5Padding");
|
||||||
|
ci.init(Cipher.DECRYPT_MODE, skey, new IvParameterSpec(iv));
|
||||||
|
|
||||||
|
|
||||||
|
OutputStream out = new OutputStream() {
|
||||||
|
private final StringBuilder string = new StringBuilder();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(int b) throws IOException {
|
||||||
|
this.string.append((char) b );
|
||||||
|
}
|
||||||
|
|
||||||
|
//Netbeans IDE automatically overrides this toString()
|
||||||
|
public String toString() {
|
||||||
|
return this.string.toString();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
processFile(ci, in, out);
|
||||||
|
return out.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package de.joel.zoomhelper;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Intent;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
public class FileChooser {
|
||||||
|
// Request code for selecting a PDF document.
|
||||||
|
private final Activity act;
|
||||||
|
|
||||||
|
public FileChooser (Activity act) {
|
||||||
|
this.act = act;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void openFile() {
|
||||||
|
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
|
||||||
|
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||||
|
intent.setType("application/octet-stream");
|
||||||
|
act.startActivityForResult(intent, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,7 +5,11 @@ import android.content.ClipData;
|
|||||||
import android.content.ClipboardManager;
|
import android.content.ClipboardManager;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.view.Menu;
|
||||||
|
import android.view.MenuInflater;
|
||||||
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.AutoCompleteTextView;
|
import android.widget.AutoCompleteTextView;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
@@ -14,6 +18,7 @@ import android.widget.LinearLayout;
|
|||||||
import android.widget.ScrollView;
|
import android.widget.ScrollView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.annotation.RequiresApi;
|
||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
import androidx.core.content.pm.ShortcutInfoCompat;
|
import androidx.core.content.pm.ShortcutInfoCompat;
|
||||||
@@ -25,6 +30,8 @@ import com.github.javiersantos.appupdater.enums.UpdateFrom;
|
|||||||
import com.google.android.material.snackbar.Snackbar;
|
import com.google.android.material.snackbar.Snackbar;
|
||||||
import com.google.android.material.textfield.TextInputLayout;
|
import com.google.android.material.textfield.TextInputLayout;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
@@ -140,6 +147,56 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
|
MenuInflater inflater = getMenuInflater();
|
||||||
|
inflater.inflate(R.menu.menu, menu);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||||
|
@Override
|
||||||
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
|
final int item_backup = R.id.menu_backup;
|
||||||
|
final int item_restore = R.id.menu_restore;
|
||||||
|
final int item_settings = R.id.menu_settings;
|
||||||
|
final int item_info = R.id.menu_info;
|
||||||
|
final BackupController backupController = new BackupController();
|
||||||
|
|
||||||
|
switch (item.getItemId()) {
|
||||||
|
case item_backup:
|
||||||
|
backupController.backup(this);
|
||||||
|
break;
|
||||||
|
case item_restore:
|
||||||
|
backupController.restore(this);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
|
super.onActivityResult(requestCode, resultCode, data);
|
||||||
|
Uri fileUri = null;
|
||||||
|
String filePath = null;
|
||||||
|
|
||||||
|
if (requestCode == 2) {
|
||||||
|
fileUri = data.getData();
|
||||||
|
filePath = fileUri.getPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
new BackupController().restore(this, getContentResolver().openInputStream(fileUri));
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
// new BackupController().restore(this, file.getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
private void importFromClipboard() {
|
private void importFromClipboard() {
|
||||||
final LinearLayout layoutBegin = findViewById(R.id.layoutBegin);
|
final LinearLayout layoutBegin = findViewById(R.id.layoutBegin);
|
||||||
final ClipboardManager clipboard = (ClipboardManager) getApplicationContext().getSystemService(CLIPBOARD_SERVICE);
|
final ClipboardManager clipboard = (ClipboardManager) getApplicationContext().getSystemService(CLIPBOARD_SERVICE);
|
||||||
@@ -154,7 +211,7 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
if (clipboard.hasPrimaryClip() && clipboard.getPrimaryClipDescription().hasMimeType(MIMETYPE_TEXT_PLAIN)) {
|
if (clipboard.hasPrimaryClip() && clipboard.getPrimaryClipDescription().hasMimeType(MIMETYPE_TEXT_PLAIN)) {
|
||||||
final String text = clipboard.getPrimaryClip().getItemAt(0).getText().toString();
|
final String text = clipboard.getPrimaryClip().getItemAt(0).getText().toString();
|
||||||
if ( meetingImportController.handleSendText(text, true)) {
|
if (meetingImportController.handleSendText(text, true)) {
|
||||||
snackbar.show();
|
snackbar.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,7 +297,7 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
@SuppressLint("ClickableViewAccessibility")
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
public void fillDropdownMeetingName() {
|
public void fillDropdownMeetingName() {
|
||||||
final ArrayList<Meeting> meetings = meetingsController.getMeetings();
|
final ArrayList<Meeting> meetings = meetingsController.getMeetings();
|
||||||
|
|
||||||
String[] meetingNames = new String[meetings.size()];
|
String[] meetingNames = new String[meetings.size()];
|
||||||
for (int i = 0; i < meetings.size(); i++) {
|
for (int i = 0; i < meetings.size(); i++) {
|
||||||
|
|||||||
@@ -119,6 +119,7 @@ public class MeetingsController {
|
|||||||
return meetingList;
|
return meetingList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: Nach Remove bleibt Meeting noch stehen
|
||||||
public void removeMeeting(int meeting) {
|
public void removeMeeting(int meeting) {
|
||||||
MainActivity act = (MainActivity)context;
|
MainActivity act = (MainActivity)context;
|
||||||
ArrayList<Meeting> meetings = getMeetings();
|
ArrayList<Meeting> meetings = getMeetings();
|
||||||
|
|||||||
@@ -11,8 +11,7 @@
|
|||||||
android:layout_marginTop="22dp"
|
android:layout_marginTop="22dp"
|
||||||
android:onClick="btnSave_onClick"
|
android:onClick="btnSave_onClick"
|
||||||
android:text="@string/Save"
|
android:text="@string/Save"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
app:layout_constraintTop_toBottomOf="@+id/imageTrash" />
|
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/btnJoin"
|
android:id="@+id/btnJoin"
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:id="@+id/menu_backup"
|
||||||
|
android:title="@string/backup" />
|
||||||
|
<item android:id="@+id/menu_restore"
|
||||||
|
android:title="@string/restore" />
|
||||||
|
<item android:id="@+id/menu_settings"
|
||||||
|
android:title="@string/settings" />
|
||||||
|
<item android:id="@+id/menu_info"
|
||||||
|
android:title="@string/info" />
|
||||||
|
</menu>
|
||||||
@@ -41,5 +41,9 @@
|
|||||||
<string name="cancel">abbrechen</string>
|
<string name="cancel">abbrechen</string>
|
||||||
<string name="meetingSaved">Meeting gespeichert</string>
|
<string name="meetingSaved">Meeting gespeichert</string>
|
||||||
<string name="meetingWithoutID">Meeting kann nicht ohne ID gespeichert werden!</string>
|
<string name="meetingWithoutID">Meeting kann nicht ohne ID gespeichert werden!</string>
|
||||||
|
<string name="backup">Daten sichern</string>
|
||||||
|
<string name="restore">Daten wiederherstellen</string>
|
||||||
|
<string name="settings">Einstellungen</string>
|
||||||
|
<string name="info">Info</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
Reference in New Issue
Block a user