531 lines
18 KiB
Java
531 lines
18 KiB
Java
package de.joel.zoomhelper;
|
|
|
|
import android.annotation.SuppressLint;
|
|
import android.content.ClipData;
|
|
import android.content.ClipboardManager;
|
|
import android.content.Context;
|
|
import android.content.Intent;
|
|
import android.content.SharedPreferences;
|
|
import android.net.Uri;
|
|
import android.os.Bundle;
|
|
import android.util.AttributeSet;
|
|
import android.util.Base64;
|
|
import android.view.View;
|
|
import android.widget.ArrayAdapter;
|
|
import android.widget.AutoCompleteTextView;
|
|
import android.widget.EditText;
|
|
import android.widget.ImageView;
|
|
import android.widget.ScrollView;
|
|
import android.widget.Toast;
|
|
|
|
import androidx.appcompat.app.AlertDialog;
|
|
import androidx.appcompat.app.AppCompatActivity;
|
|
|
|
import java.io.ByteArrayInputStream;
|
|
import java.io.ByteArrayOutputStream;
|
|
import java.io.EOFException;
|
|
import java.io.IOException;
|
|
import java.io.ObjectInputStream;
|
|
import java.io.ObjectOutputStream;
|
|
import java.io.Serializable;
|
|
import java.util.ArrayList;
|
|
import java.util.Objects;
|
|
|
|
class InstantAutoComplete extends androidx.appcompat.widget.AppCompatAutoCompleteTextView {
|
|
|
|
public InstantAutoComplete(Context context) {
|
|
super(context);
|
|
}
|
|
public InstantAutoComplete(Context arg0, AttributeSet arg1) {
|
|
super(arg0, arg1);
|
|
}
|
|
|
|
public InstantAutoComplete(Context arg0, AttributeSet arg1, int arg2) {
|
|
super(arg0, arg1, arg2);
|
|
}
|
|
@Override
|
|
public boolean enoughToFilter() {
|
|
return true;
|
|
}
|
|
|
|
}
|
|
|
|
public class MainActivity extends AppCompatActivity {
|
|
|
|
@Override
|
|
protected void onCreate(Bundle savedInstanceState) {
|
|
super.onCreate(savedInstanceState);
|
|
setContentView(R.layout.activity_main);
|
|
final ScrollView scrollview = ((ScrollView) findViewById(R.id.scrollArea));
|
|
scrollview.post(() -> scrollview.scrollTo(0, scrollview.getChildAt(0).getHeight()));
|
|
watchMeetingNameBox();
|
|
fillDropdownMeetingName();
|
|
if (getLastMeeting() != -1) {
|
|
try {
|
|
fillMeeting(getLastMeeting());
|
|
}
|
|
catch (IndexOutOfBoundsException e) {
|
|
AlertDialog.Builder dialog=new AlertDialog.Builder(this);
|
|
dialog.setMessage(R.string.resetDataText);
|
|
dialog.setTitle(R.string.hint);
|
|
AlertDialog alertDialog=dialog.create();
|
|
alertDialog.show();
|
|
setLastMeeting(-1);
|
|
saveMeetingList(new ArrayList<>());
|
|
}
|
|
}
|
|
watchSaveIcon();
|
|
watchAttIcon();
|
|
watchDeleteIcon();
|
|
watchNewIcon();
|
|
watchShareIcon();
|
|
}
|
|
|
|
private void watchShareIcon() {
|
|
ImageView ShareIcon = findViewById(R.id.imageShare);
|
|
ShareIcon.setOnClickListener(v -> shareMeeting(createCurrMeetingFromUI()));
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
private void watchNewIcon() {
|
|
ImageView AddIcon = findViewById(R.id.imageAdd);
|
|
AddIcon.setOnClickListener(v -> fillBlank());
|
|
}
|
|
|
|
private void watchAttIcon() {
|
|
ImageView AttIcon = findViewById(R.id.imageAttend);
|
|
AttIcon.setOnClickListener(v -> btnJoin_onClick(null));
|
|
}
|
|
|
|
private void watchDeleteIcon() {
|
|
ImageView trashIcon = findViewById(R.id.imageTrash);
|
|
trashIcon.setOnClickListener(v -> removeMeeting(getLastMeeting()));
|
|
}
|
|
|
|
private void removeMeeting(int meeting) {
|
|
ArrayList<Meeting> meetings = getMeetings();
|
|
if (meetings.size() > 0) {
|
|
|
|
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
|
|
|
builder.setTitle(R.string.app_name);
|
|
builder.setMessage(getString(R.string.suretoremove, meetings.get(meeting).meetingName));
|
|
|
|
builder.setPositiveButton(R.string.yes, (dialog, which) -> {
|
|
dialog.dismiss();
|
|
meetings.remove(meeting);
|
|
saveMeetingList(meetings);
|
|
|
|
if (meetings.size() > 1) {
|
|
fillDropdownMeetingName();
|
|
if (getLastMeeting() > meetings.size()-1) {
|
|
setLastMeeting(meetings.size()-1);
|
|
fillMeeting(getLastMeeting());
|
|
}
|
|
} else if (meetings.size() == 1) {
|
|
setLastMeeting(0);
|
|
fillDropdownMeetingName();
|
|
fillMeeting(getLastMeeting());
|
|
} else {
|
|
setLastMeeting(-1);
|
|
fillDropdownMeetingName();
|
|
fillBlank();
|
|
}
|
|
});
|
|
|
|
builder.setNegativeButton(R.string.no, (dialog, which) -> {
|
|
dialog.dismiss();
|
|
});
|
|
|
|
AlertDialog alert = builder.create();
|
|
alert.show();
|
|
|
|
}
|
|
}
|
|
|
|
|
|
private void fillBlank() {
|
|
EditText editMeetingName = findViewById(R.id.TextMeetingName);
|
|
EditText editID = findViewById(R.id.textBoxID);
|
|
EditText editPW = findViewById(R.id.editTextTextPassword2);
|
|
AutoCompleteTextView editName = findViewById(R.id.textBoxName);
|
|
EditText editAtt = findViewById(R.id.editAtt);
|
|
|
|
editMeetingName.setText("");
|
|
editID.setText("");
|
|
editPW.setText("");
|
|
editName.setText("");
|
|
editName.setAdapter(null);
|
|
editAtt.setText("");
|
|
}
|
|
|
|
private void watchSaveIcon() {
|
|
ImageView saveIcon = findViewById(R.id.imageSave);
|
|
saveIcon.setOnClickListener(v -> saveAllMeetings());
|
|
}
|
|
|
|
public void watchMeetingNameBox() {
|
|
EditText meetingNameBox = findViewById(R.id.TextMeetingName);
|
|
meetingNameBox.setOnFocusChangeListener((v, hasFocus) -> {
|
|
if (!hasFocus) {
|
|
fillWithSelectedMeeting();
|
|
}
|
|
|
|
});
|
|
}
|
|
|
|
public void fillWithSelectedMeeting() {
|
|
AutoCompleteTextView textMeetingName = findViewById(R.id.TextMeetingName);
|
|
int search = searchMeetingInList(getMeetings(), textMeetingName.getText().toString());
|
|
if (search != -1) {
|
|
fillMeeting(search);
|
|
}
|
|
}
|
|
|
|
@SuppressLint("ClickableViewAccessibility")
|
|
public void fillDropdownMeetingName() {
|
|
ArrayList<Meeting> meetings = getMeetings();
|
|
|
|
String[] meetingNames = new String[meetings.size()];
|
|
for (int i = 0; i < meetings.size(); i++) {
|
|
meetingNames[i] = meetings.get(i).meetingName;
|
|
}
|
|
|
|
AutoCompleteTextView textMeetingName = findViewById(R.id.TextMeetingName);
|
|
ImageView dropdown = findViewById(R.id.image);
|
|
ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_dropdown_item_1line, meetingNames);
|
|
textMeetingName.setAdapter(adapter);
|
|
|
|
textMeetingName.setOnTouchListener((View.OnTouchListener) (paramView, paramMotionEvent) -> {
|
|
adapter.getFilter().filter(null);
|
|
textMeetingName.showDropDown();
|
|
return false;
|
|
});
|
|
|
|
textMeetingName.setOnItemClickListener((arg0, view, arg2, arg3) -> fillWithSelectedMeeting());
|
|
|
|
dropdown.setOnClickListener(v -> {
|
|
textMeetingName.showDropDown();
|
|
adapter.getFilter().filter(null);
|
|
});
|
|
}
|
|
|
|
public void fillDropdownAttendeeName(int meetingIndex) {
|
|
Meeting meeting = getMeetings().get(meetingIndex);
|
|
ArrayList<Attendee> attendees = meeting.attendees;
|
|
|
|
String[] attNames = new String[attendees.size()];
|
|
for (int i = 0; i < attendees.size(); i++) {
|
|
attNames[i] = attendees.get(i).name;
|
|
}
|
|
|
|
AutoCompleteTextView textName = findViewById(R.id.textBoxName);
|
|
ImageView dropdown = findViewById(R.id.image2);
|
|
ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_dropdown_item_1line, attNames);
|
|
textName.setAdapter(adapter);
|
|
|
|
textName.setOnItemClickListener((arg0, view, arg2, arg3) -> fillWithSelectedAtt());
|
|
|
|
dropdown.setOnClickListener(v -> {
|
|
textName.showDropDown();
|
|
adapter.getFilter().filter(null);
|
|
});
|
|
}
|
|
|
|
private void fillWithSelectedAtt() {
|
|
AutoCompleteTextView textName = findViewById(R.id.textBoxName);
|
|
EditText editAtt = findViewById(R.id.editAtt);
|
|
int found = getMeetings().get(getLastMeeting()).searchAttendee(textName.getText().toString());
|
|
editAtt.setText(getMeetings().get(getLastMeeting()).attendees.get(found).num);
|
|
}
|
|
|
|
public void fillMeeting(int id) {
|
|
ArrayList<Meeting> meetings = getMeetings();
|
|
|
|
EditText editMeetingName = findViewById(R.id.TextMeetingName);
|
|
EditText editID = findViewById(R.id.textBoxID);
|
|
EditText editPW = findViewById(R.id.editTextTextPassword2);
|
|
EditText editName = findViewById(R.id.textBoxName);
|
|
EditText editAtt = findViewById(R.id.editAtt);
|
|
|
|
editID.setError(null);
|
|
editID.clearFocus();
|
|
|
|
editMeetingName.setText(meetings.get(id).meetingName);
|
|
editID.setText(meetings.get(id).meetingID);
|
|
editPW.setText(meetings.get(id).meetingPWD);
|
|
editName.setText(meetings.get(id).attendees.get(meetings.get(id).lastAtt).name);
|
|
editAtt.setText(meetings.get(id).attendees.get(meetings.get(id).lastAtt).num);
|
|
|
|
fillDropdownAttendeeName(id);
|
|
}
|
|
|
|
|
|
private void launchZoomUrl(String url) {
|
|
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
|
|
if (intent.resolveActivity(getPackageManager()) != null) {
|
|
startActivity(intent);
|
|
}
|
|
//For Debugging: Show URL in Alert
|
|
AlertDialog.Builder dialog=new AlertDialog.Builder(this);
|
|
dialog.setMessage(url);
|
|
dialog.setTitle("Zoom URL (for testing)");
|
|
AlertDialog alertDialog=dialog.create();
|
|
alertDialog.show();
|
|
}
|
|
|
|
|
|
private String buildZoomURL(String confno, String pwd, String name, String attendees) {
|
|
Uri.Builder builder = new Uri.Builder();
|
|
builder.scheme("zoomus")
|
|
.authority("zoom.us")
|
|
.appendPath("join")
|
|
.appendQueryParameter("confno",confno.replace(" ", ""))
|
|
.appendQueryParameter("pwd", pwd);
|
|
|
|
if (!Objects.equals(attendees, "")) {
|
|
builder.appendQueryParameter("uname", name + " (" + attendees + ")");
|
|
} else
|
|
builder.appendQueryParameter("uname", name);
|
|
return builder.build().toString();
|
|
}
|
|
|
|
public String meetingsToString(ArrayList<Meeting> listMeetings) {
|
|
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
|
ObjectOutputStream objOutputStream = null;
|
|
try {
|
|
objOutputStream = new ObjectOutputStream(byteArrayOutputStream);
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
}
|
|
for (Object obj : listMeetings) {
|
|
|
|
try {
|
|
if (objOutputStream == null) throw new AssertionError();
|
|
objOutputStream.writeObject(obj);
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
}
|
|
try {
|
|
objOutputStream.reset();
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
try {
|
|
if (objOutputStream == null) throw new AssertionError();
|
|
objOutputStream.close();
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
}
|
|
return Base64.encodeToString(byteArrayOutputStream.toByteArray(), 0);
|
|
}
|
|
|
|
|
|
public ArrayList<Meeting> stringToMeetings(String string) {
|
|
byte[] bytes = Base64.decode(string, 0);
|
|
|
|
ArrayList<Meeting> listMeetings = new ArrayList<>();
|
|
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
|
|
ObjectInputStream obj = null;
|
|
try {
|
|
obj = new ObjectInputStream(bis);
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
}
|
|
try {
|
|
while (bis.available() != -1) {
|
|
//Read object from file
|
|
if (obj == null) throw new AssertionError();
|
|
Meeting meeting = (Meeting) obj.readObject();
|
|
listMeetings.add(meeting);
|
|
}
|
|
} catch (EOFException ex) {
|
|
//ex.printStackTrace();
|
|
} catch (IOException | ClassNotFoundException e) {
|
|
e.printStackTrace();
|
|
}
|
|
return listMeetings;
|
|
}
|
|
|
|
@SuppressLint("ApplySharedPref")
|
|
public void saveMeetingList(ArrayList<Meeting> meetingList) {
|
|
SharedPreferences mPrefs = getPreferences(MODE_PRIVATE);
|
|
SharedPreferences.Editor prefsEditor = mPrefs.edit();
|
|
prefsEditor.putString("Meetings", meetingsToString(meetingList));
|
|
prefsEditor.commit();
|
|
}
|
|
|
|
@SuppressLint("ApplySharedPref")
|
|
public void setLastMeeting(int id) {
|
|
SharedPreferences mPrefs = getPreferences(MODE_PRIVATE);
|
|
SharedPreferences.Editor prefsEditor = mPrefs.edit();
|
|
prefsEditor.putInt("LastMeeting", id);
|
|
prefsEditor.commit();
|
|
}
|
|
|
|
public int getLastMeeting() {
|
|
SharedPreferences mPrefs = getPreferences(MODE_PRIVATE);
|
|
return mPrefs.getInt("LastMeeting", -1);
|
|
}
|
|
|
|
|
|
public ArrayList<Meeting> getMeetings() {
|
|
SharedPreferences mPrefs = getPreferences(MODE_PRIVATE);
|
|
String value = mPrefs.getString("Meetings", "");
|
|
ArrayList<Meeting> meetingList;
|
|
if (value.equals("")) {
|
|
meetingList = new ArrayList<>();
|
|
} else {
|
|
meetingList = stringToMeetings(value);
|
|
}
|
|
return meetingList;
|
|
}
|
|
|
|
public int searchMeetingInList(ArrayList<Meeting> meetings, String name) {
|
|
int found = -1;
|
|
for (int i = 0; i < meetings.size(); i++) {
|
|
if (meetings.get(i).meetingName.equals(name)) {
|
|
found = i;
|
|
break;
|
|
}
|
|
}
|
|
return found;
|
|
}
|
|
|
|
public void btnSave_onClick(View view) {
|
|
saveAllMeetings();
|
|
}
|
|
|
|
|
|
public void btnJoin_onClick(View view) {
|
|
saveAllMeetings();
|
|
Meeting currMeeting = createCurrMeetingFromUI();
|
|
String url = buildZoomURL(currMeeting.meetingID, currMeeting.meetingPWD, currMeeting.attendees.get(currMeeting.lastAtt).name, currMeeting.attendees.get(currMeeting.lastAtt).num);
|
|
launchZoomUrl(url);
|
|
}
|
|
|
|
public Meeting createCurrMeetingFromUI() {
|
|
EditText editMeetingName = findViewById(R.id.TextMeetingName);
|
|
EditText editID = findViewById(R.id.textBoxID);
|
|
EditText editPW = findViewById(R.id.editTextTextPassword2);
|
|
EditText editName = findViewById(R.id.textBoxName);
|
|
EditText editAtt = findViewById(R.id.editAtt);
|
|
|
|
return new Meeting(editMeetingName.getText().toString(), editID.getText().toString(), editPW.getText().toString(), editName.getText().toString(), editAtt.getText().toString());
|
|
}
|
|
|
|
public void saveAllMeetings() {
|
|
ArrayList<Meeting> listMeetings = getMeetings();
|
|
Meeting currMeetingUI = createCurrMeetingFromUI();
|
|
|
|
if (currMeetingUI.meetingID.equals("")) {
|
|
EditText editID = findViewById(R.id.textBoxID);
|
|
editID.requestFocus();
|
|
editID.setError("Meeting kann nicht ohne ID gespeichert werden!");
|
|
return;
|
|
}
|
|
else if (currMeetingUI.meetingName.equals("")) {
|
|
EditText editMName = findViewById(R.id.TextMeetingName);
|
|
editMName.setText(currMeetingUI.meetingID);
|
|
currMeetingUI.meetingName = currMeetingUI.meetingID;
|
|
}
|
|
|
|
|
|
int foundCurr = searchMeetingInList(listMeetings, currMeetingUI.meetingName);
|
|
if (foundCurr == -1) {
|
|
listMeetings.add(currMeetingUI);
|
|
if (listMeetings.size() == 1) {
|
|
setLastMeeting(0);
|
|
} else {
|
|
setLastMeeting(listMeetings.size() - 1);
|
|
}
|
|
|
|
} else {
|
|
Meeting currMeeting = getMeetings().get(foundCurr);
|
|
currMeeting.meetingID = currMeetingUI.meetingID;
|
|
currMeeting.meetingPWD = currMeetingUI.meetingPWD;
|
|
currMeeting.updateAttendee(currMeetingUI.attendees.get(0).name, currMeetingUI.attendees.get(0).num);
|
|
listMeetings.set(foundCurr, currMeeting);
|
|
setLastMeeting(foundCurr);
|
|
}
|
|
saveMeetingList(listMeetings);
|
|
fillDropdownMeetingName();
|
|
fillDropdownAttendeeName(getLastMeeting());
|
|
Toast.makeText(getApplicationContext(),"Meeting gespeichert",Toast.LENGTH_SHORT).show();
|
|
}
|
|
|
|
}
|
|
|
|
|
|
class Attendee implements Serializable {
|
|
public String name;
|
|
public String num;
|
|
|
|
public Attendee(String name, String num) {
|
|
this.name = name;
|
|
this.num = num;
|
|
}
|
|
}
|
|
|
|
class Meeting implements Serializable {
|
|
public String meetingName;
|
|
public String meetingID;
|
|
public String meetingPWD;
|
|
public ArrayList<Attendee> attendees;
|
|
public int lastAtt;
|
|
|
|
public Meeting(String meetingName, String meetingID, String meetingPWD, String nameAttendee, String numAttendee) {
|
|
this.meetingName = meetingName;
|
|
this.meetingID = meetingID;
|
|
this.meetingPWD = meetingPWD;
|
|
this.attendees = new ArrayList<>();
|
|
Attendee attendee = new Attendee(nameAttendee, numAttendee);
|
|
this.attendees.add(attendee);
|
|
this.lastAtt = 0;
|
|
}
|
|
|
|
public void addAttendee(String name, String num) {
|
|
Attendee attendee = new Attendee(name, num);
|
|
this.attendees.add(attendee);
|
|
this.lastAtt = attendees.size() - 1;
|
|
}
|
|
|
|
public int searchAttendee(String name) {
|
|
int found = -1;
|
|
for (int i = 0; i < this.attendees.size(); i++) {
|
|
if (this.attendees.get(i).name.equals(name)) {
|
|
found = i;
|
|
break;
|
|
}
|
|
}
|
|
return found;
|
|
}
|
|
|
|
public void updateAttendee(String name, String num) {
|
|
|
|
int found = searchAttendee(name);
|
|
|
|
if (found == -1) {
|
|
addAttendee(name, num);
|
|
} else {
|
|
this.attendees.get(found).num = num;
|
|
this.lastAtt = found;
|
|
}
|
|
}
|
|
|
|
public String info() {
|
|
return "Meeting Name: " + this.meetingName + "\n" +
|
|
"Meeting-ID: " + this.meetingID + "\n" +
|
|
"Kenncode: " + this.meetingPWD;
|
|
}
|
|
} |