Compare commits
9 Commits
f539bc3184
..
master
| Author | SHA1 | Date | |
|---|---|---|---|
| c488052501 | |||
| 06e3d7972f | |||
| 5ec72eddd4 | |||
| c37f51bff8 | |||
| 75b67ea2f0 | |||
| 355f7a7758 | |||
| 42a2c353c6 | |||
| a67ed4390b | |||
| 1a8377b558 |
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>
|
||||||
+3
-3
@@ -10,8 +10,8 @@ android {
|
|||||||
applicationId "de.joel.zoomhelper"
|
applicationId "de.joel.zoomhelper"
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 30
|
targetSdkVersion 30
|
||||||
versionCode 14
|
versionCode 15
|
||||||
versionName '0.5.1 beta'
|
versionName '0.5.1'
|
||||||
|
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
}
|
}
|
||||||
@@ -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"
|
||||||
|
|||||||
@@ -4,8 +4,24 @@ import java.io.Serializable;
|
|||||||
|
|
||||||
public class Attendee implements Serializable {
|
public class Attendee implements Serializable {
|
||||||
private static final long serialVersionUID = 6196688086302483907L;
|
private static final long serialVersionUID = 6196688086302483907L;
|
||||||
public String name;
|
private String name;
|
||||||
public String num;
|
private String num;
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNum() {
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNum(String num) {
|
||||||
|
this.num = num;
|
||||||
|
}
|
||||||
|
|
||||||
public Attendee(String name, String num) {
|
public Attendee(String name, String num) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
|||||||
@@ -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,29 +30,29 @@ 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;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import static android.content.ClipDescription.MIMETYPE_TEXT_PLAIN;
|
import static android.content.ClipDescription.MIMETYPE_TEXT_PLAIN;
|
||||||
|
|
||||||
public class MainActivity extends AppCompatActivity {
|
public class MainActivity extends AppCompatActivity {
|
||||||
|
|
||||||
private final MeetingsController meetingsController = new MeetingsController(this);
|
private final MeetingsController meetingsController = new MeetingsController(this);
|
||||||
|
private final MeetingImportController meetingImportController = new MeetingImportController(meetingsController, this);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
//get intent parameters
|
//get intent parameters
|
||||||
Intent myIntent = getIntent();
|
final Intent myIntent = getIntent();
|
||||||
String action = myIntent.getAction();
|
final String action = myIntent.getAction();
|
||||||
String type = myIntent.getType();
|
final String type = myIntent.getType();
|
||||||
String meetingName = myIntent.getStringExtra("meetingName");
|
final String meetingName = myIntent.getStringExtra("meetingName");
|
||||||
boolean joinImmediately = myIntent.getBooleanExtra("joinImmediately", false);
|
boolean joinImmediately = myIntent.getBooleanExtra("joinImmediately", false);
|
||||||
//boolean testing = myIntent.getBooleanExtra("testing", false);
|
//final boolean testing = myIntent.getBooleanExtra("testing", false);
|
||||||
|
|
||||||
setContentView(R.layout.activity_main);
|
setContentView(R.layout.activity_main);
|
||||||
|
|
||||||
@@ -63,23 +68,23 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
//add event listeners to views
|
//add event listeners to views
|
||||||
saveIcon.setOnClickListener(v -> saveMeetingFromUI());
|
saveIcon.setOnClickListener(v -> saveMeetingFromUI());
|
||||||
trashIcon.setOnClickListener(v -> meetingsController.removeMeeting(meetingsController.searchMeetingInList(meetingsController.getMeetings(), createCurrMeetingFromUI().meetingName)));
|
trashIcon.setOnClickListener(v -> meetingsController.removeMeeting(meetingsController.searchMeetingInList(meetingsController.getMeetings(), createCurrMeetingFromUI().getMeetingName())));
|
||||||
AttIcon.setOnClickListener(v -> btnJoin_onClick(null));
|
AttIcon.setOnClickListener(v -> btnJoin_onClick(null));
|
||||||
AddIcon.setOnClickListener(v -> {
|
AddIcon.setOnClickListener(v -> {
|
||||||
fillBlank();
|
fillBlank();
|
||||||
meetingID.requestFocus();
|
meetingID.requestFocus();
|
||||||
});
|
});
|
||||||
ShareIcon.setOnClickListener(v -> shareMeeting(createCurrMeetingFromUI()));
|
ShareIcon.setOnClickListener(v -> startActivity(createCurrMeetingFromUI().share()));
|
||||||
ShortcutIcon.setOnClickListener(v -> showCreateShortcutUI());
|
ShortcutIcon.setOnClickListener(v -> showCreateShortcutUI());
|
||||||
|
|
||||||
//show alert if meeting from shortcut not found
|
//show alert if meeting from shortcut not found
|
||||||
int meetingIndex = meetingsController.searchMeetingInList(meetingsController.getMeetings(), meetingName);
|
final int meetingIndex = meetingsController.searchMeetingInList(meetingsController.getMeetings(), meetingName);
|
||||||
if (meetingIndex == -1) {
|
if (meetingIndex == -1) {
|
||||||
if (meetingName != null) {
|
if (meetingName != null) {
|
||||||
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
|
final AlertDialog.Builder dialog = new AlertDialog.Builder(this);
|
||||||
dialog.setMessage(R.string.shortcutLaunchFailedText);
|
dialog.setMessage(R.string.shortcutLaunchFailedText);
|
||||||
dialog.setTitle(R.string.hint);
|
dialog.setTitle(R.string.hint);
|
||||||
AlertDialog alertDialog = dialog.create();
|
final AlertDialog alertDialog = dialog.create();
|
||||||
alertDialog.show();
|
alertDialog.show();
|
||||||
}
|
}
|
||||||
joinImmediately = false;
|
joinImmediately = false;
|
||||||
@@ -88,11 +93,11 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
//adjust ui for meeting from shortcut
|
//adjust ui for meeting from shortcut
|
||||||
if (meetingIndex <= meetingsController.getMeetings().size() && meetingIndex != -1) {
|
if (meetingIndex <= meetingsController.getMeetings().size() && meetingIndex != -1) {
|
||||||
meetingsController.setLastMeeting(meetingIndex);
|
meetingsController.setLastMeeting(meetingIndex);
|
||||||
AutoCompleteTextView textMeetingName = findViewById(R.id.TextMeetingName);
|
final AutoCompleteTextView textMeetingName = findViewById(R.id.TextMeetingName);
|
||||||
textMeetingName.setEnabled(false);
|
textMeetingName.setEnabled(false);
|
||||||
textMeetingName.setAdapter(null);
|
textMeetingName.setAdapter(null);
|
||||||
trashIcon.setVisibility(View.GONE);
|
trashIcon.setVisibility(View.GONE);
|
||||||
TextInputLayout layoutMeetingName = findViewById(R.id.layoutMeetingName);
|
final TextInputLayout layoutMeetingName = findViewById(R.id.layoutMeetingName);
|
||||||
layoutMeetingName.setEndIconMode(TextInputLayout.END_ICON_NONE);
|
layoutMeetingName.setEndIconMode(TextInputLayout.END_ICON_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,10 +109,10 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
fillMeeting(meetingsController.getLastMeeting());
|
fillMeeting(meetingsController.getLastMeeting());
|
||||||
scrollview.post(() -> scrollview.scrollTo(0, scrollview.getChildAt(0).getHeight()));
|
scrollview.post(() -> scrollview.scrollTo(0, scrollview.getChildAt(0).getHeight()));
|
||||||
} catch (IndexOutOfBoundsException e) {
|
} catch (IndexOutOfBoundsException e) {
|
||||||
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
|
final AlertDialog.Builder dialog = new AlertDialog.Builder(this);
|
||||||
dialog.setMessage(R.string.resetDataText);
|
dialog.setMessage(R.string.resetDataText);
|
||||||
dialog.setTitle(R.string.hint);
|
dialog.setTitle(R.string.hint);
|
||||||
AlertDialog alertDialog = dialog.create();
|
final AlertDialog alertDialog = dialog.create();
|
||||||
alertDialog.show();
|
alertDialog.show();
|
||||||
meetingsController.setLastMeeting(-1);
|
meetingsController.setLastMeeting(-1);
|
||||||
meetingsController.saveMeetingList(new ArrayList<>());
|
meetingsController.saveMeetingList(new ArrayList<>());
|
||||||
@@ -117,18 +122,17 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
//handle meeting invitation text sent to ZoomHelper
|
//handle meeting invitation text sent to ZoomHelper
|
||||||
if (Intent.ACTION_SEND.equals(action) && type != null) {
|
if (Intent.ACTION_SEND.equals(action) && type != null) {
|
||||||
if ("text/plain".equals(type)) {
|
if ("text/plain".equals(type)) {
|
||||||
handleSendText(myIntent);
|
meetingImportController.handleSendText(myIntent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//join meeting immediately, otherwise enable app updater
|
//join meeting immediately, otherwise enable app updater
|
||||||
if (joinImmediately) {
|
if (joinImmediately) {
|
||||||
Meeting currMeeting = meetingsController.getMeetings().get(meetingIndex);
|
final Meeting currMeeting = meetingsController.getMeetings().get(meetingIndex);
|
||||||
new ZoomLink(this, currMeeting).launch();
|
new ZoomLink(this, currMeeting).launch();
|
||||||
} else {
|
} else {
|
||||||
//TODO: updatetest.xml -> update.xml when finished testing
|
final AppUpdater appUpdater = new AppUpdater(this).setUpdateFrom(UpdateFrom.XML).setUpdateXML("https://baldaufwd.de/ZoomHelper/update.xml");
|
||||||
AppUpdater appUpdater = new AppUpdater(this).setUpdateFrom(UpdateFrom.XML).setUpdateXML("https://baldaufwd.de/ZoomHelper/updatetest.xml");
|
final APKDownloader apkDownloader = new APKDownloader();
|
||||||
APKDownloader apkDownloader = new APKDownloader();
|
|
||||||
appUpdater.setButtonUpdateClickListener((dialog, which) -> apkDownloader.downloadAPK(this, "ZoomHelper.apk", Uri.parse("https://baldaufwd.de/ZoomHelper/ZoomHelper.apk")));
|
appUpdater.setButtonUpdateClickListener((dialog, which) -> apkDownloader.downloadAPK(this, "ZoomHelper.apk", Uri.parse("https://baldaufwd.de/ZoomHelper/ZoomHelper.apk")));
|
||||||
appUpdater.start();
|
appUpdater.start();
|
||||||
}
|
}
|
||||||
@@ -143,96 +147,81 @@ 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);
|
||||||
|
|
||||||
Snackbar snackbar = Snackbar.make(layoutBegin, R.string.foundImportableMeetingClipboard, Snackbar.LENGTH_INDEFINITE).setDuration(7000);
|
final Snackbar snackbar = Snackbar.make(layoutBegin, R.string.foundImportableMeetingClipboard, Snackbar.LENGTH_INDEFINITE).setDuration(7000);
|
||||||
snackbar.setAction(R.string.importMeeting, view -> {
|
snackbar.setAction(R.string.importMeeting, view -> {
|
||||||
String text = clipboard.getPrimaryClip().getItemAt(0).getText().toString();
|
String text = clipboard.getPrimaryClip().getItemAt(0).getText().toString();
|
||||||
handleSendText(text);
|
meetingImportController.handleSendText(text);
|
||||||
ClipData clipData = ClipData.newPlainText("", "");
|
ClipData clipData = ClipData.newPlainText("", "");
|
||||||
clipboard.setPrimaryClip(clipData);
|
clipboard.setPrimaryClip(clipData);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (clipboard.hasPrimaryClip() && clipboard.getPrimaryClipDescription().hasMimeType(MIMETYPE_TEXT_PLAIN)) {
|
if (clipboard.hasPrimaryClip() && clipboard.getPrimaryClipDescription().hasMimeType(MIMETYPE_TEXT_PLAIN)) {
|
||||||
String text = clipboard.getPrimaryClip().getItemAt(0).getText().toString();
|
final String text = clipboard.getPrimaryClip().getItemAt(0).getText().toString();
|
||||||
if (handleSendText(text, true)) {
|
if (meetingImportController.handleSendText(text, true)) {
|
||||||
snackbar.show();
|
snackbar.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleSendText(Intent intent) {
|
|
||||||
String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
|
|
||||||
handleSendText(sharedText);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleSendText(String sharedText) {
|
|
||||||
handleSendText(sharedText, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean handleSendText(String sharedText, boolean checkOnly) {
|
|
||||||
String meetingID = "";
|
|
||||||
String meetingPWD = "";
|
|
||||||
String meetingName = "";
|
|
||||||
|
|
||||||
if (sharedText != null) {
|
|
||||||
Matcher matcher = Pattern.compile("(?i)(?<=(Meeting-ID:)|(Meeting\\sID:)|(ID:)).+").matcher(sharedText);
|
|
||||||
if (matcher.find()) {
|
|
||||||
meetingID = Objects.requireNonNull(matcher.group(0)).trim();
|
|
||||||
}
|
|
||||||
matcher = Pattern.compile("(?i)(?<=(Kenncode:)|(Passwort:)|(Passcode:)|(Password:)).+").matcher(sharedText);
|
|
||||||
if (matcher.find()) {
|
|
||||||
meetingPWD = Objects.requireNonNull(matcher.group(0)).trim();
|
|
||||||
}
|
|
||||||
matcher = Pattern.compile("(?i)(?<=(Thema:)|(Meeting\\sName:)|(Topic:)).+").matcher(sharedText);
|
|
||||||
if (matcher.find()) {
|
|
||||||
meetingName = Objects.requireNonNull(matcher.group(0)).trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
|
||||||
builder.setTitle(R.string.app_name);
|
|
||||||
builder.setMessage(R.string.meetingAlreadyExists);
|
|
||||||
|
|
||||||
if (meetingID.equals("")) {
|
|
||||||
builder.setMessage(R.string.importError);
|
|
||||||
builder.setPositiveButton(R.string.ok, (dialog, which) -> dialog.dismiss());
|
|
||||||
AlertDialog alert = builder.create();
|
|
||||||
if (!checkOnly) alert.show();
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
|
|
||||||
Meeting mtgToImport = new Meeting(meetingName, meetingID, meetingPWD, "", "");
|
|
||||||
|
|
||||||
if (meetingsController.searchMeetingInList(meetingsController.getMeetings(), mtgToImport.meetingName) == -1 && !checkOnly) {
|
|
||||||
fillMeeting(mtgToImport);
|
|
||||||
} else {
|
|
||||||
builder.setPositiveButton(R.string.override, (dialog, which) -> {
|
|
||||||
int found = meetingsController.searchMeetingInList(meetingsController.getMeetings(), mtgToImport.meetingName);
|
|
||||||
importMeeting(mtgToImport, false);
|
|
||||||
fillMeeting(found);
|
|
||||||
dialog.dismiss();
|
|
||||||
});
|
|
||||||
builder.setNegativeButton(R.string.rename, (dialog, which) -> {
|
|
||||||
mtgToImport.meetingName = "";
|
|
||||||
fillMeeting(mtgToImport);
|
|
||||||
dialog.dismiss();
|
|
||||||
});
|
|
||||||
AlertDialog alert = builder.create();
|
|
||||||
if (!checkOnly) alert.show();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void showCreateShortcutUI() {
|
private void showCreateShortcutUI() {
|
||||||
int meeting = meetingsController.searchMeetingInList(meetingsController.getMeetings(), createCurrMeetingFromUI().meetingName);
|
final int meeting = meetingsController.searchMeetingInList(meetingsController.getMeetings(), createCurrMeetingFromUI().getMeetingName());
|
||||||
|
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||||
|
|
||||||
builder.setTitle(R.string.app_name);
|
builder.setTitle(R.string.app_name);
|
||||||
|
|
||||||
@@ -257,22 +246,22 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
createMeetingShortcut(meeting, false);
|
createMeetingShortcut(meeting, false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
AlertDialog alert = builder.create();
|
final AlertDialog alert = builder.create();
|
||||||
alert.show();
|
alert.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createMeetingShortcut(int meetingIndex, boolean joinImmediately) {
|
private void createMeetingShortcut(int meetingIndex, boolean joinImmediately) {
|
||||||
Meeting meeting = meetingsController.getMeetings().get(meetingIndex);
|
final Meeting meeting = meetingsController.getMeetings().get(meetingIndex);
|
||||||
|
|
||||||
if (ShortcutManagerCompat.isRequestPinShortcutSupported(this)) {
|
if (ShortcutManagerCompat.isRequestPinShortcutSupported(this)) {
|
||||||
ShortcutInfoCompat shortcutInfo = new ShortcutInfoCompat.Builder(this, meeting.meetingName)
|
ShortcutInfoCompat shortcutInfo = new ShortcutInfoCompat.Builder(this, meeting.getMeetingName())
|
||||||
.setShortLabel(meeting.meetingName)
|
.setShortLabel(meeting.getMeetingName())
|
||||||
.setLongLabel(meeting.meetingName)
|
.setLongLabel(meeting.getMeetingName())
|
||||||
.setIcon(IconCompat.createWithResource(this, R.mipmap.ic_launcher))
|
.setIcon(IconCompat.createWithResource(this, R.mipmap.ic_launcher))
|
||||||
.setIntents(new Intent[]{
|
.setIntents(new Intent[]{
|
||||||
new Intent(this, MainActivity.class)
|
new Intent(this, MainActivity.class)
|
||||||
.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
|
.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
|
||||||
.putExtra("meetingName", meeting.meetingName)
|
.putExtra("meetingName", meeting.getMeetingName())
|
||||||
.putExtra("joinImmediately", joinImmediately)
|
.putExtra("joinImmediately", joinImmediately)
|
||||||
.setAction("LOCATION_SHORTCUT"),
|
.setAction("LOCATION_SHORTCUT"),
|
||||||
})
|
})
|
||||||
@@ -283,22 +272,12 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void shareMeeting(Meeting meeting) {
|
|
||||||
Intent sendIntent = new Intent();
|
|
||||||
sendIntent.setAction(Intent.ACTION_SEND);
|
|
||||||
sendIntent.putExtra(Intent.EXTRA_TEXT, meeting.info());
|
|
||||||
sendIntent.setType("text/plain");
|
|
||||||
|
|
||||||
Intent shareIntent = Intent.createChooser(sendIntent, null);
|
|
||||||
startActivity(shareIntent);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void fillBlank() {
|
public void fillBlank() {
|
||||||
EditText editMeetingName = findViewById(R.id.TextMeetingName);
|
final EditText editMeetingName = findViewById(R.id.TextMeetingName);
|
||||||
EditText editID = findViewById(R.id.textBoxID);
|
final EditText editID = findViewById(R.id.textBoxID);
|
||||||
EditText editPW = findViewById(R.id.editTextTextPassword2);
|
final EditText editPW = findViewById(R.id.editTextTextPassword2);
|
||||||
AutoCompleteTextView editName = findViewById(R.id.textBoxName);
|
final AutoCompleteTextView editName = findViewById(R.id.textBoxName);
|
||||||
EditText editAtt = findViewById(R.id.editAtt);
|
final EditText editAtt = findViewById(R.id.editAtt);
|
||||||
|
|
||||||
editMeetingName.setText("");
|
editMeetingName.setText("");
|
||||||
editID.setText("");
|
editID.setText("");
|
||||||
@@ -309,8 +288,8 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void fillWithSelectedMeeting() {
|
public void fillWithSelectedMeeting() {
|
||||||
AutoCompleteTextView textMeetingName = findViewById(R.id.TextMeetingName);
|
final AutoCompleteTextView textMeetingName = findViewById(R.id.TextMeetingName);
|
||||||
int search = meetingsController.searchMeetingInList(meetingsController.getMeetings(), textMeetingName.getText().toString());
|
final int search = meetingsController.searchMeetingInList(meetingsController.getMeetings(), textMeetingName.getText().toString());
|
||||||
if (search != -1) {
|
if (search != -1) {
|
||||||
fillMeeting(search);
|
fillMeeting(search);
|
||||||
}
|
}
|
||||||
@@ -318,15 +297,15 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
@SuppressLint("ClickableViewAccessibility")
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
public void fillDropdownMeetingName() {
|
public void fillDropdownMeetingName() {
|
||||||
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++) {
|
||||||
meetingNames[i] = meetings.get(i).meetingName;
|
meetingNames[i] = meetings.get(i).getMeetingName();
|
||||||
}
|
}
|
||||||
|
|
||||||
AutoCompleteTextView textMeetingName = findViewById(R.id.TextMeetingName);
|
final AutoCompleteTextView textMeetingName = findViewById(R.id.TextMeetingName);
|
||||||
AutoSuggestAdapter adapter = new AutoSuggestAdapter(this, android.R.layout.simple_dropdown_item_1line);
|
final AutoSuggestAdapter adapter = new AutoSuggestAdapter(this, android.R.layout.simple_dropdown_item_1line);
|
||||||
adapter.setData(Arrays.asList(meetingNames));
|
adapter.setData(Arrays.asList(meetingNames));
|
||||||
textMeetingName.setAdapter(adapter);
|
textMeetingName.setAdapter(adapter);
|
||||||
|
|
||||||
@@ -337,16 +316,16 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
@SuppressLint("ClickableViewAccessibility")
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
public void fillDropdownAttendeeName(int meetingIndex) {
|
public void fillDropdownAttendeeName(int meetingIndex) {
|
||||||
Meeting meeting = meetingsController.getMeetings().get(meetingIndex);
|
final Meeting meeting = meetingsController.getMeetings().get(meetingIndex);
|
||||||
ArrayList<Attendee> attendees = meeting.attendees;
|
final ArrayList<Attendee> attendees = meeting.getAttendees();
|
||||||
|
|
||||||
String[] attNames = new String[attendees.size()];
|
String[] attNames = new String[attendees.size()];
|
||||||
for (int i = 0; i < attendees.size(); i++) {
|
for (int i = 0; i < attendees.size(); i++) {
|
||||||
attNames[i] = attendees.get(i).name;
|
attNames[i] = attendees.get(i).getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
AutoCompleteTextView textName = findViewById(R.id.textBoxName);
|
final AutoCompleteTextView textName = findViewById(R.id.textBoxName);
|
||||||
AutoSuggestAdapter adapter = new AutoSuggestAdapter(this, android.R.layout.simple_dropdown_item_1line);
|
final AutoSuggestAdapter adapter = new AutoSuggestAdapter(this, android.R.layout.simple_dropdown_item_1line);
|
||||||
|
|
||||||
adapter.setData(Arrays.asList(attNames));
|
adapter.setData(Arrays.asList(attNames));
|
||||||
textName.setAdapter(adapter);
|
textName.setAdapter(adapter);
|
||||||
@@ -357,28 +336,28 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void fillWithSelectedAtt(int meetingIndex) {
|
private void fillWithSelectedAtt(int meetingIndex) {
|
||||||
AutoCompleteTextView textName = findViewById(R.id.textBoxName);
|
final AutoCompleteTextView textName = findViewById(R.id.textBoxName);
|
||||||
EditText editAtt = findViewById(R.id.editAtt);
|
final EditText editAtt = findViewById(R.id.editAtt);
|
||||||
int found = meetingsController.getMeetings().get(meetingIndex).searchAttendee(textName.getText().toString());
|
final int found = meetingsController.getMeetings().get(meetingIndex).searchAttendee(textName.getText().toString());
|
||||||
editAtt.setText(meetingsController.getMeetings().get(meetingIndex).attendees.get(found).num);
|
editAtt.setText(meetingsController.getMeetings().get(meetingIndex).getAttendees().get(found).getNum());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void fillMeeting(Meeting meeting) {
|
public void fillMeeting(Meeting meeting) {
|
||||||
EditText editMeetingName = findViewById(R.id.TextMeetingName);
|
final EditText editMeetingName = findViewById(R.id.TextMeetingName);
|
||||||
EditText editID = findViewById(R.id.textBoxID);
|
final EditText editID = findViewById(R.id.textBoxID);
|
||||||
EditText editPW = findViewById(R.id.editTextTextPassword2);
|
final EditText editPW = findViewById(R.id.editTextTextPassword2);
|
||||||
EditText editName = findViewById(R.id.textBoxName);
|
final EditText editName = findViewById(R.id.textBoxName);
|
||||||
EditText editAtt = findViewById(R.id.editAtt);
|
final EditText editAtt = findViewById(R.id.editAtt);
|
||||||
|
|
||||||
editID.setError(null);
|
editID.setError(null);
|
||||||
editID.clearFocus();
|
editID.clearFocus();
|
||||||
|
|
||||||
|
|
||||||
editMeetingName.setText(meeting.meetingName);
|
editMeetingName.setText(meeting.getMeetingName());
|
||||||
editID.setText(meeting.meetingID);
|
editID.setText(meeting.getMeetingID());
|
||||||
editPW.setText(meeting.meetingPWD);
|
editPW.setText(meeting.getMeetingPWD());
|
||||||
editName.setText(meeting.attendees.get(meeting.lastAtt).name);
|
editName.setText(meeting.getAttendees().get(meeting.getLastAtt()).getName());
|
||||||
editAtt.setText(meeting.attendees.get(meeting.lastAtt).num);
|
editAtt.setText(meeting.getAttendees().get(meeting.getLastAtt()).getNum());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void fillMeeting(int id) {
|
public void fillMeeting(int id) {
|
||||||
@@ -392,63 +371,33 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
public void btnJoin_onClick(View view) {
|
public void btnJoin_onClick(View view) {
|
||||||
saveMeetingFromUI();
|
saveMeetingFromUI();
|
||||||
Meeting currMeeting = createCurrMeetingFromUI();
|
final Meeting currMeeting = createCurrMeetingFromUI();
|
||||||
new ZoomLink(this, currMeeting).launch();
|
new ZoomLink(this, currMeeting).launch();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Meeting createCurrMeetingFromUI() {
|
public Meeting createCurrMeetingFromUI() {
|
||||||
EditText editMeetingName = findViewById(R.id.TextMeetingName);
|
final EditText editMeetingName = findViewById(R.id.TextMeetingName);
|
||||||
EditText editID = findViewById(R.id.textBoxID);
|
final EditText editID = findViewById(R.id.textBoxID);
|
||||||
EditText editPW = findViewById(R.id.editTextTextPassword2);
|
final EditText editPW = findViewById(R.id.editTextTextPassword2);
|
||||||
EditText editName = findViewById(R.id.textBoxName);
|
final EditText editName = findViewById(R.id.textBoxName);
|
||||||
EditText editAtt = findViewById(R.id.editAtt);
|
final EditText editAtt = findViewById(R.id.editAtt);
|
||||||
|
|
||||||
return new Meeting(editMeetingName.getText().toString(), editID.getText().toString(), editPW.getText().toString(), editName.getText().toString(), editAtt.getText().toString());
|
return new Meeting(editMeetingName.getText().toString(), editID.getText().toString(), editPW.getText().toString(), editName.getText().toString(), editAtt.getText().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void importMeeting(Meeting meeting, boolean updateAttendee) {
|
|
||||||
ArrayList<Meeting> listMeetings = meetingsController.getMeetings();
|
|
||||||
int foundCurr = meetingsController.searchMeetingInList(listMeetings, meeting.meetingName);
|
|
||||||
if (foundCurr == -1) {
|
|
||||||
listMeetings.add(meeting);
|
|
||||||
if (listMeetings.size() == 1) {
|
|
||||||
meetingsController.setLastMeeting(0);
|
|
||||||
} else {
|
|
||||||
meetingsController.setLastMeeting(listMeetings.size() - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
Meeting currMeeting = meetingsController.getMeetings().get(foundCurr);
|
|
||||||
currMeeting.meetingID = meeting.meetingID;
|
|
||||||
currMeeting.meetingPWD = meeting.meetingPWD;
|
|
||||||
if (updateAttendee)
|
|
||||||
currMeeting.updateAttendee(meeting.attendees.get(0).name, meeting.attendees.get(0).num);
|
|
||||||
listMeetings.set(foundCurr, currMeeting);
|
|
||||||
meetingsController.setLastMeeting(foundCurr);
|
|
||||||
}
|
|
||||||
meetingsController.saveMeetingList(listMeetings);
|
|
||||||
fillDropdownMeetingName();
|
|
||||||
fillDropdownAttendeeName(meetingsController.getLastMeeting());
|
|
||||||
Toast.makeText(getApplicationContext(), R.string.meetingSaved, Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void importMeeting(Meeting meeting) {
|
|
||||||
importMeeting(meeting, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void saveMeetingFromUI() {
|
public void saveMeetingFromUI() {
|
||||||
Meeting currMeetingUI = createCurrMeetingFromUI();
|
final Meeting currMeetingUI = createCurrMeetingFromUI();
|
||||||
|
|
||||||
if (currMeetingUI.meetingID.equals("")) {
|
if (currMeetingUI.getMeetingID().equals("")) {
|
||||||
EditText editID = findViewById(R.id.textBoxID);
|
final EditText editID = findViewById(R.id.textBoxID);
|
||||||
editID.requestFocus();
|
editID.requestFocus();
|
||||||
editID.setError(getString(R.string.meetingWithoutID));
|
editID.setError(getString(R.string.meetingWithoutID));
|
||||||
return;
|
return;
|
||||||
} else if (currMeetingUI.meetingName.equals("")) {
|
} else if (currMeetingUI.getMeetingName().equals("")) {
|
||||||
EditText editMName = findViewById(R.id.TextMeetingName);
|
final EditText editMName = findViewById(R.id.TextMeetingName);
|
||||||
editMName.setText(currMeetingUI.meetingID);
|
editMName.setText(currMeetingUI.getMeetingID());
|
||||||
currMeetingUI.meetingName = currMeetingUI.meetingID;
|
currMeetingUI.setMeetingName(currMeetingUI.getMeetingID());
|
||||||
}
|
}
|
||||||
importMeeting(currMeetingUI);
|
meetingImportController.importMeeting(createCurrMeetingFromUI());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,15 +1,57 @@
|
|||||||
package de.joel.zoomhelper;
|
package de.joel.zoomhelper;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
public class Meeting implements Serializable {
|
public class Meeting implements Serializable {
|
||||||
private static final long serialVersionUID = 2606722401897866931L;
|
private static final long serialVersionUID = 2606722401897866931L;
|
||||||
public String meetingName;
|
private String meetingName;
|
||||||
public String meetingID;
|
private String meetingID;
|
||||||
public String meetingPWD;
|
private String meetingPWD;
|
||||||
public ArrayList<Attendee> attendees;
|
private ArrayList<Attendee> attendees;
|
||||||
public int lastAtt;
|
private int lastAtt;
|
||||||
|
|
||||||
|
public String getMeetingName() {
|
||||||
|
return meetingName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMeetingName(String meetingName) {
|
||||||
|
this.meetingName = meetingName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMeetingID() {
|
||||||
|
return meetingID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMeetingID(String meetingID) {
|
||||||
|
this.meetingID = meetingID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMeetingPWD() {
|
||||||
|
return meetingPWD;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMeetingPWD(String meetingPWD) {
|
||||||
|
this.meetingPWD = meetingPWD;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayList<Attendee> getAttendees() {
|
||||||
|
return attendees;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAttendees(ArrayList<Attendee> attendees) {
|
||||||
|
this.attendees = attendees;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLastAtt() {
|
||||||
|
return lastAtt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastAtt(int lastAtt) {
|
||||||
|
this.lastAtt = lastAtt;
|
||||||
|
}
|
||||||
|
|
||||||
public Meeting(String meetingName, String meetingID, String meetingPWD, String nameAttendee, String numAttendee) {
|
public Meeting(String meetingName, String meetingID, String meetingPWD, String nameAttendee, String numAttendee) {
|
||||||
this.meetingName = meetingName;
|
this.meetingName = meetingName;
|
||||||
@@ -30,7 +72,7 @@ public class Meeting implements Serializable {
|
|||||||
public int searchAttendee(String name) {
|
public int searchAttendee(String name) {
|
||||||
int found = -1;
|
int found = -1;
|
||||||
for (int i = 0; i < this.attendees.size(); i++) {
|
for (int i = 0; i < this.attendees.size(); i++) {
|
||||||
if (this.attendees.get(i).name.equals(name)) {
|
if (this.attendees.get(i).getName().equals(name)) {
|
||||||
found = i;
|
found = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -45,7 +87,7 @@ public class Meeting implements Serializable {
|
|||||||
if (found == -1) {
|
if (found == -1) {
|
||||||
addAttendee(name, num);
|
addAttendee(name, num);
|
||||||
} else {
|
} else {
|
||||||
this.attendees.get(found).num = num;
|
this.attendees.get(found).setNum(num);
|
||||||
this.lastAtt = found;
|
this.lastAtt = found;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -55,4 +97,13 @@ public class Meeting implements Serializable {
|
|||||||
"Meeting-ID: " + this.meetingID + "\n" +
|
"Meeting-ID: " + this.meetingID + "\n" +
|
||||||
"Kenncode: " + this.meetingPWD;
|
"Kenncode: " + this.meetingPWD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Intent share() {
|
||||||
|
final Intent sendIntent = new Intent();
|
||||||
|
sendIntent.setAction(Intent.ACTION_SEND);
|
||||||
|
sendIntent.putExtra(Intent.EXTRA_TEXT, this.info());
|
||||||
|
sendIntent.setType("text/plain");
|
||||||
|
|
||||||
|
return Intent.createChooser(sendIntent, null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,118 @@
|
|||||||
|
package de.joel.zoomhelper;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.appcompat.app.AlertDialog;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class MeetingImportController {
|
||||||
|
private final MeetingsController meetingsController;
|
||||||
|
private final MainActivity act;
|
||||||
|
|
||||||
|
public MeetingImportController(MeetingsController meetingsController, MainActivity act) {
|
||||||
|
this.meetingsController = meetingsController;
|
||||||
|
this.act = act;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handleSendText(Intent intent) {
|
||||||
|
final String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
|
||||||
|
handleSendText(sharedText);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handleSendText(String sharedText) {
|
||||||
|
handleSendText(sharedText, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean handleSendText(String sharedText, boolean checkOnly) {
|
||||||
|
String meetingID = "";
|
||||||
|
String meetingPWD = "";
|
||||||
|
String meetingName = "";
|
||||||
|
|
||||||
|
if (sharedText != null) {
|
||||||
|
Matcher matcher = Pattern.compile("(?i)(?<=(Meeting-ID:)|(Meeting\\sID:)|(ID:)).+").matcher(sharedText);
|
||||||
|
if (matcher.find()) {
|
||||||
|
meetingID = Objects.requireNonNull(matcher.group(0)).trim();
|
||||||
|
}
|
||||||
|
matcher = Pattern.compile("(?i)(?<=(Kenncode:)|(Passwort:)|(Passcode:)|(Password:)).+").matcher(sharedText);
|
||||||
|
if (matcher.find()) {
|
||||||
|
meetingPWD = Objects.requireNonNull(matcher.group(0)).trim();
|
||||||
|
}
|
||||||
|
matcher = Pattern.compile("(?i)(?<=(Thema:)|(Meeting\\sName:)|(Topic:)).+").matcher(sharedText);
|
||||||
|
if (matcher.find()) {
|
||||||
|
meetingName = Objects.requireNonNull(matcher.group(0)).trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
final AlertDialog.Builder builder = new AlertDialog.Builder(act);
|
||||||
|
builder.setTitle(R.string.app_name);
|
||||||
|
builder.setMessage(R.string.meetingAlreadyExists);
|
||||||
|
|
||||||
|
if (meetingID.equals("")) {
|
||||||
|
builder.setMessage(R.string.importError);
|
||||||
|
builder.setPositiveButton(R.string.ok, (dialog, which) -> dialog.dismiss());
|
||||||
|
final AlertDialog alert = builder.create();
|
||||||
|
if (!checkOnly) alert.show();
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
|
||||||
|
final Meeting mtgToImport = new Meeting(meetingName, meetingID, meetingPWD, "", "");
|
||||||
|
|
||||||
|
if (meetingsController.searchMeetingInList(meetingsController.getMeetings(), mtgToImport.getMeetingName()) == -1 && !checkOnly) {
|
||||||
|
act.fillMeeting(mtgToImport);
|
||||||
|
} else {
|
||||||
|
builder.setPositiveButton(R.string.override, (dialog, which) -> {
|
||||||
|
final int found = meetingsController.searchMeetingInList(meetingsController.getMeetings(), mtgToImport.getMeetingName());
|
||||||
|
importMeeting(mtgToImport, false);
|
||||||
|
act.fillMeeting(found);
|
||||||
|
dialog.dismiss();
|
||||||
|
});
|
||||||
|
builder.setNegativeButton(R.string.rename, (dialog, which) -> {
|
||||||
|
mtgToImport.setMeetingName("");
|
||||||
|
act.fillMeeting(mtgToImport);
|
||||||
|
dialog.dismiss();
|
||||||
|
});
|
||||||
|
final AlertDialog alert = builder.create();
|
||||||
|
if (!checkOnly) alert.show();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void importMeeting(Meeting meeting, boolean updateAttendee) {
|
||||||
|
final ArrayList<Meeting> listMeetings = meetingsController.getMeetings();
|
||||||
|
final int foundCurr = meetingsController.searchMeetingInList(listMeetings, meeting.getMeetingName());
|
||||||
|
|
||||||
|
if (foundCurr == -1) {
|
||||||
|
listMeetings.add(meeting);
|
||||||
|
if (listMeetings.size() == 1) {
|
||||||
|
meetingsController.setLastMeeting(0);
|
||||||
|
} else {
|
||||||
|
meetingsController.setLastMeeting(listMeetings.size() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
final Meeting currMeeting = meetingsController.getMeetings().get(foundCurr);
|
||||||
|
currMeeting.setMeetingID(meeting.getMeetingID());
|
||||||
|
currMeeting.setMeetingPWD(meeting.getMeetingPWD());
|
||||||
|
if (updateAttendee)
|
||||||
|
currMeeting.updateAttendee(meeting.getAttendees().get(0).getName(), meeting.getAttendees().get(0).getNum());
|
||||||
|
listMeetings.set(foundCurr, currMeeting);
|
||||||
|
meetingsController.setLastMeeting(foundCurr);
|
||||||
|
}
|
||||||
|
meetingsController.saveMeetingList(listMeetings);
|
||||||
|
act.fillDropdownMeetingName();
|
||||||
|
act.fillDropdownAttendeeName(meetingsController.getLastMeeting());
|
||||||
|
Toast.makeText(act, R.string.meetingSaved, Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void importMeeting(Meeting meeting) {
|
||||||
|
importMeeting(meeting, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
@@ -127,7 +128,7 @@ public class MeetingsController {
|
|||||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||||
|
|
||||||
builder.setTitle(R.string.app_name);
|
builder.setTitle(R.string.app_name);
|
||||||
builder.setMessage(context.getString(R.string.suretoremove, meetings.get(meeting).meetingName));
|
builder.setMessage(context.getString(R.string.suretoremove, meetings.get(meeting).getMeetingName()));
|
||||||
|
|
||||||
builder.setPositiveButton(R.string.yes, (dialog, which) -> {
|
builder.setPositiveButton(R.string.yes, (dialog, which) -> {
|
||||||
dialog.dismiss();
|
dialog.dismiss();
|
||||||
@@ -162,7 +163,7 @@ public class MeetingsController {
|
|||||||
public int searchMeetingInList(ArrayList<Meeting> meetings, String name) {
|
public int searchMeetingInList(ArrayList<Meeting> meetings, String name) {
|
||||||
int found = -1;
|
int found = -1;
|
||||||
for (int i = 0; i < meetings.size(); i++) {
|
for (int i = 0; i < meetings.size(); i++) {
|
||||||
if (meetings.get(i).meetingName.equals(name)) {
|
if (meetings.get(i).getMeetingName().equals(name)) {
|
||||||
found = i;
|
found = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,13 +23,13 @@ public class ZoomLink {
|
|||||||
builder.scheme("zoomus")
|
builder.scheme("zoomus")
|
||||||
.authority("zoom.us")
|
.authority("zoom.us")
|
||||||
.appendPath("join")
|
.appendPath("join")
|
||||||
.appendQueryParameter("confno", this.meeting.meetingID.replace(" ", ""))
|
.appendQueryParameter("confno", this.meeting.getMeetingID().replace(" ", ""))
|
||||||
.appendQueryParameter("pwd", this.meeting.meetingPWD);
|
.appendQueryParameter("pwd", this.meeting.getMeetingPWD());
|
||||||
|
|
||||||
if (!Objects.equals(this.meeting.attendees.get(this.meeting.lastAtt).num, "")) {
|
if (!Objects.equals(this.meeting.getAttendees().get(this.meeting.getLastAtt()).getNum(), "")) {
|
||||||
builder.appendQueryParameter("uname", this.meeting.attendees.get(this.meeting.lastAtt).name + " (" + this.meeting.attendees.get(this.meeting.lastAtt).num + ")");
|
builder.appendQueryParameter("uname", this.meeting.getAttendees().get(this.meeting.getLastAtt()).getName() + " (" + this.meeting.getAttendees().get(this.meeting.getLastAtt()).getNum() + ")");
|
||||||
} else
|
} else
|
||||||
builder.appendQueryParameter("uname", this.meeting.attendees.get(this.meeting.lastAtt).name);
|
builder.appendQueryParameter("uname", this.meeting.getAttendees().get(this.meeting.getLastAtt()).getName());
|
||||||
return builder.build().toString();
|
return builder.build().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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