import meetings from clipboard and other fixes

This commit is contained in:
2021-04-07 19:55:11 +02:00
parent e3dc1a161b
commit 230949d778
5 changed files with 142 additions and 39 deletions
+1
View File
@@ -39,6 +39,7 @@ dependencies {
implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'androidx.appcompat:appcompat:1.2.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.2.0'
testImplementation 'junit:junit:4.13.2' testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.2' androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
-2
View File
@@ -5,9 +5,7 @@
<package android:name="us.zoom.videomeetings" /> <package android:name="us.zoom.videomeetings" />
</queries> </queries>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" /> <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
@@ -1,31 +1,32 @@
package de.joel.zoomhelper; package de.joel.zoomhelper;
import android.Manifest;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.DownloadManager; import android.app.DownloadManager;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.net.Uri; import android.net.Uri;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.Environment; import android.os.Environment;
import android.provider.Settings;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.util.Base64; import android.util.Base64;
import android.util.Log;
import android.view.View; import android.view.View;
import android.widget.AutoCompleteTextView; import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ScrollView; import android.widget.ScrollView;
import android.widget.Toast; import android.widget.Toast;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.FileProvider; import androidx.core.content.FileProvider;
import androidx.core.content.pm.ShortcutInfoCompat; import androidx.core.content.pm.ShortcutInfoCompat;
import androidx.core.content.pm.ShortcutManagerCompat; import androidx.core.content.pm.ShortcutManagerCompat;
@@ -33,6 +34,7 @@ import androidx.core.graphics.drawable.IconCompat;
import com.github.javiersantos.appupdater.AppUpdater; import com.github.javiersantos.appupdater.AppUpdater;
import com.github.javiersantos.appupdater.enums.UpdateFrom; import com.github.javiersantos.appupdater.enums.UpdateFrom;
import com.google.android.material.snackbar.Snackbar;
import com.google.android.material.textfield.TextInputLayout; import com.google.android.material.textfield.TextInputLayout;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
@@ -46,9 +48,13 @@ import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Objects; import java.util.Objects;
import java.util.Timer;
import java.util.TimerTask;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import static android.content.ClipDescription.MIMETYPE_TEXT_PLAIN;
class InstantAutoComplete extends androidx.appcompat.widget.AppCompatAutoCompleteTextView { class InstantAutoComplete extends androidx.appcompat.widget.AppCompatAutoCompleteTextView {
@@ -76,6 +82,7 @@ public class MainActivity extends AppCompatActivity {
public boolean testing; public boolean testing;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
@@ -89,6 +96,7 @@ public class MainActivity extends AppCompatActivity {
testing = myIntent.getBooleanExtra("testing", false); testing = myIntent.getBooleanExtra("testing", false);
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); setContentView(R.layout.activity_main);
final ScrollView scrollview = findViewById(R.id.scrollArea); final ScrollView scrollview = findViewById(R.id.scrollArea);
@@ -140,7 +148,6 @@ public class MainActivity extends AppCompatActivity {
watchShareIcon(); watchShareIcon();
watchShortcutIcon(); watchShortcutIcon();
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); // Handle text being sent handleSendText(myIntent); // Handle text being sent
@@ -152,40 +159,104 @@ public class MainActivity extends AppCompatActivity {
String url = buildZoomURL(currMeeting.meetingID, currMeeting.meetingPWD, currMeeting.attendees.get(currMeeting.lastAtt).name, currMeeting.attendees.get(currMeeting.lastAtt).num); String url = buildZoomURL(currMeeting.meetingID, currMeeting.meetingPWD, currMeeting.attendees.get(currMeeting.lastAtt).name, currMeeting.attendees.get(currMeeting.lastAtt).num);
launchZoomUrl(url); launchZoomUrl(url);
} else { } else {
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");
appUpdater.setButtonUpdateClickListener((dialog, which) -> downloadAPK()); appUpdater.setButtonUpdateClickListener((dialog, which) -> downloadAPK());
appUpdater.start(); appUpdater.start();
} }
} }
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
importFromClipboard();
}
}
/* private void watchImportIcon() {
ImageView ImportIcon = findViewById(R.id.imageImport);
ImportIcon.setOnClickListener(v -> importFromClipboard());
}
void importFromClipboard() {
Log.d("import", "ImportFromClipboard");
ClipboardManager clipboard = (ClipboardManager) getApplicationContext().getSystemService(CLIPBOARD_SERVICE);
Log.d("clipboardManager", clipboard.toString());
if (clipboard.hasPrimaryClip() && clipboard.getPrimaryClipDescription().hasMimeType(MIMETYPE_TEXT_PLAIN)) {
String text = clipboard.getPrimaryClip().getItemAt(0).getText().toString();
Log.d("text", text);
handleSendText(text);
}
} */
private void importFromClipboard() {
LinearLayout layoutBegin = findViewById(R.id.layoutBegin);
ClipboardManager clipboard = (ClipboardManager) getApplicationContext().getSystemService(CLIPBOARD_SERVICE);
Snackbar snackbar = Snackbar.make(layoutBegin,R.string.foundImportableMeetingClipboard,Snackbar.LENGTH_INDEFINITE).setDuration(7000);
snackbar.setAction(R.string.importMeeting, view -> {
String text = clipboard.getPrimaryClip().getItemAt(0).getText().toString();
handleSendText(text);
ClipData clipData = ClipData.newPlainText("", "");
clipboard.setPrimaryClip(clipData);
});
if (clipboard.hasPrimaryClip() && clipboard.getPrimaryClipDescription().hasMimeType(MIMETYPE_TEXT_PLAIN)) {
String text = clipboard.getPrimaryClip().getItemAt(0).getText().toString();
if (handleSendText(text, true)) {
snackbar.show();
}
}
}
private void downloadAPK() { private void downloadAPK() {
String destination = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/";
String fileName = "ZoomHelper.apk"; String fileName = "ZoomHelper.apk";
destination += fileName; File destination = new File(getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath(), fileName);
/*
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
|| ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { || ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
// this will request for permission when user has not granted permission for the app // this will request for permission when user has not granted permission for the app
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1); ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
} else { downloadAPK();
} else {*/
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O) {
if (!getPackageManager().canRequestPackageInstalls()) {
Toast.makeText(this, R.string.PleaseAllowUnknownSources, Toast.LENGTH_LONG).show();
startActivityForResult(new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, Uri.parse("package:de.joel.zoomhelper")), 101);
Timer timer = new Timer(true);
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
if (getPackageManager().canRequestPackageInstalls()) {
finishActivity(101);
downloadAPK();
timer.cancel();
}
}
}, 0, 1000);
return;
}
}
//Delete update file if exists //Delete update file if exists
File file = new File(destination); final Uri localUri = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID + ".provider", destination);
final Uri localUri = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID + ".provider", file); if (destination.exists())
if (file.exists())
//file.delete() - test this, I think sometimes it doesnt work //file.delete() - test this, I think sometimes it doesnt work
file.delete(); destination.delete();
//Download Script //Download Script
DownloadManager downloadManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE); DownloadManager downloadManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
Uri uri = Uri.parse("https://baldaufwd.de/ZoomHelper/ZoomHelper.apk"); Uri uri = Uri.parse("https://baldaufwd.de/ZoomHelper/ZoomHelper.apk");
DownloadManager.Request request = new DownloadManager.Request(uri); DownloadManager.Request request = new DownloadManager.Request(uri);
request.setVisibleInDownloadsUi(true);
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, uri.getLastPathSegment()); Log.d("Desturi", localUri.getPath());
request.setDestinationInExternalFilesDir(this, Environment.DIRECTORY_DOWNLOADS, fileName);
final long downloadID = downloadManager.enqueue(request); final long downloadID = downloadManager.enqueue(request);
BroadcastReceiver onDownloadComplete = new BroadcastReceiver() { BroadcastReceiver onDownloadComplete = new BroadcastReceiver() {
@@ -209,13 +280,18 @@ public class MainActivity extends AppCompatActivity {
}; };
registerReceiver(onDownloadComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)); registerReceiver(onDownloadComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
} }
//}
}
private void handleSendText(Intent intent) { private void handleSendText(Intent intent) {
String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT); 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 meetingID = "";
String meetingPWD = ""; String meetingPWD = "";
String meetingName = ""; String meetingName = "";
@@ -244,12 +320,13 @@ public class MainActivity extends AppCompatActivity {
dialog.dismiss(); dialog.dismiss();
}); });
AlertDialog alert = builder.create(); AlertDialog alert = builder.create();
alert.show(); if (!checkOnly) alert.show();
return false;
} else { } else {
Meeting mtgToImport = new Meeting(meetingName, meetingID, meetingPWD, "", ""); Meeting mtgToImport = new Meeting(meetingName, meetingID, meetingPWD, "", "");
if (searchMeetingInList(getMeetings(), mtgToImport.meetingName) == -1) { if (searchMeetingInList(getMeetings(), mtgToImport.meetingName) == -1 && !checkOnly) {
fillMeeting(mtgToImport); fillMeeting(mtgToImport);
} else { } else {
builder.setPositiveButton(R.string.override, (dialog, which) -> { builder.setPositiveButton(R.string.override, (dialog, which) -> {
@@ -264,7 +341,8 @@ public class MainActivity extends AppCompatActivity {
dialog.dismiss(); dialog.dismiss();
}); });
AlertDialog alert = builder.create(); AlertDialog alert = builder.create();
alert.show(); if (!checkOnly) alert.show();
return true;
} }
} }
@@ -294,33 +372,49 @@ public class MainActivity extends AppCompatActivity {
AlertDialog alert = builder.create(); AlertDialog alert = builder.create();
alert.show();*/ alert.show();*/
} }
return true;
} }
private void watchShortcutIcon() { private void watchShortcutIcon() {
ImageView ShortcutIcon = findViewById(R.id.imageCreateShortcut); ImageView ShortcutIcon = findViewById(R.id.imageCreateShortcut);
ShortcutIcon.setOnClickListener(v -> showCreateShortcutUI());
}
ShortcutIcon.setOnClickListener(v -> { private void showCreateShortcutUI() {
int meeting = searchMeetingInList(getMeetings(), createCurrMeetingFromUI().meetingName);
AlertDialog.Builder builder = new AlertDialog.Builder(this); AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.app_name); builder.setTitle(R.string.app_name);
builder.setMessage(R.string.WantToJoinImmediately);
if (meeting == -1) {
builder.setMessage(R.string.cantCreateShortcut);
builder.setPositiveButton(R.string.saveMeeting, (dialog, which) -> {
dialog.dismiss();
saveMeetingFromUI();
showCreateShortcutUI();
});
builder.setNegativeButton(R.string.cancel, (dialog, which) -> {
dialog.dismiss();
});
}
else {
builder.setMessage(R.string.WantToJoinImmediately);
builder.setPositiveButton(R.string.joinImmediately, (dialog, which) -> { builder.setPositiveButton(R.string.joinImmediately, (dialog, which) -> {
dialog.dismiss(); dialog.dismiss();
createMeetingShortcut(searchMeetingInList(getMeetings(), createCurrMeetingFromUI().meetingName), true); createMeetingShortcut(meeting, true);
}); });
builder.setNegativeButton(R.string.alwaysAsk, (dialog, which) -> { builder.setNegativeButton(R.string.alwaysAsk, (dialog, which) -> {
dialog.dismiss(); dialog.dismiss();
createMeetingShortcut(searchMeetingInList(getMeetings(), createCurrMeetingFromUI().meetingName), false); createMeetingShortcut(meeting, false);
}); });
}
AlertDialog alert = builder.create(); AlertDialog alert = builder.create();
alert.show(); alert.show();
//createMeetingShortcut(searchMeetingInList(getMeetings(), createCurrMeetingFromUI().meetingName), false); //createMeetingShortcut(searchMeetingInList(getMeetings(), createCurrMeetingFromUI().meetingName), false);
});
} }
private void createMeetingShortcut(int meetingIndex, boolean joinImmediately) { private void createMeetingShortcut(int meetingIndex, boolean joinImmediately) {
@@ -383,7 +477,7 @@ public class MainActivity extends AppCompatActivity {
private void removeMeeting(int meeting) { private void removeMeeting(int meeting) {
ArrayList<Meeting> meetings = getMeetings(); ArrayList<Meeting> meetings = getMeetings();
if (meetings.size() > 0) { if (meetings.size() > 0 && meeting != -1) {
AlertDialog.Builder builder = new AlertDialog.Builder(this); AlertDialog.Builder builder = new AlertDialog.Builder(this);
+7
View File
@@ -32,5 +32,12 @@
<string name="meetingAlreadyExists">Meeting unter diesem Namen existiert schon. Bitte umbenennen, ansonsten wird es beim Speichern überschrieben</string> <string name="meetingAlreadyExists">Meeting unter diesem Namen existiert schon. Bitte umbenennen, ansonsten wird es beim Speichern überschrieben</string>
<string name="override">überschreiben</string> <string name="override">überschreiben</string>
<string name="rename">umbenennen</string> <string name="rename">umbenennen</string>
<string name="PleaseAllowUnknownSources">Bitte erlaube ZoomHelper, Apps zu installieren</string>
<string name="importTooltip">Meeting aus Zwischenablage importieren</string>
<string name="foundImportableMeetingClipboard">importierbares Meeting in Zwischenablage</string>
<string name="importMeeting">IMPORTIEREN</string>
<string name="cantCreateShortcut">Du musst das Meeting zunächst speichern, bevor du eine Verknüpfung dazu erstellen kannst</string>
<string name="saveMeeting">Meeting speichern</string>
<string name="cancel">abbrechen</string>
</resources> </resources>
+3
View File
@@ -17,6 +17,9 @@ allprojects {
google() google()
jcenter() jcenter()
} }
tasks.withType(JavaCompile) {
options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"
}
} }
task clean(type: Delete) { task clean(type: Delete) {