From 448b02d672000cdd7911c505c5a0ce1fc0a508b3 Mon Sep 17 00:00:00 2001 From: ed Date: Sun, 23 Jan 2022 23:12:44 +0100 Subject: [PATCH] v1.6.0 --- app/build.gradle | 11 +- app/release/output-metadata.json | 4 +- app/src/main/AndroidManifest.xml | 1 + .../java/me/ocv/partyup/XferActivity.java | 137 +++++++++++++----- app/src/main/res/layout/activity_xfer.xml | 8 +- app/src/main/res/xml/root_preferences.xml | 2 +- metadata/en-US/changelogs/10600.txt | 3 +- 7 files changed, 107 insertions(+), 59 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index ef31b2c..53962d4 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -17,8 +17,8 @@ android { applicationId "me.ocv.partyup" minSdk 28 targetSdk 28 - versionCode 10500 - versionName "1.5.0" + versionCode 10600 + versionName "1.6.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" signingConfig signingConfigs.release @@ -28,7 +28,7 @@ android { buildTypes { release { - minifyEnabled false + minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } @@ -51,13 +51,8 @@ android { } dependencies { - - implementation 'androidx.appcompat:appcompat:1.3.1' implementation 'com.google.android.material:material:1.4.0' implementation 'androidx.preference:preference:1.1.1' - implementation 'androidx.constraintlayout:constraintlayout:2.1.2' - implementation 'androidx.navigation:navigation-fragment:2.3.5' - implementation 'androidx.navigation:navigation-ui:2.3.5' testImplementation 'junit:junit:4.+' androidTestImplementation 'androidx.test.ext:junit:1.1.3' androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' diff --git a/app/release/output-metadata.json b/app/release/output-metadata.json index facb657..1be60b2 100644 --- a/app/release/output-metadata.json +++ b/app/release/output-metadata.json @@ -11,8 +11,8 @@ "type": "SINGLE", "filters": [], "attributes": [], - "versionCode": 10500, - "versionName": "1.5.0", + "versionCode": 10600, + "versionName": "1.6.0", "outputFile": "app-release.apk" } ], diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 03e819a..368059d 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -3,6 +3,7 @@ package="me.ocv.partyup"> + x = the_intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM); handles = x.toArray(new Uri[0]); - } - else if (one) { + } else if (one) { Uri uri = (Uri) the_intent.getParcelableExtra(Intent.EXTRA_STREAM); if (uri != null) - handles = new Uri[]{ uri }; + handles = new Uri[]{uri}; else the_msg = the_intent.getStringExtra(Intent.EXTRA_TEXT); } @@ -115,7 +120,7 @@ else if (one) { password = ""; // necessary in the emulator, not on real devices(?) password = password.isEmpty() ? null : - "Basic " + new String(Base64.getEncoder().encode(password.getBytes())); + "Basic " + new String(Base64.getEncoder().encode(password.getBytes())); final FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); fab.setOnClickListener(v -> { @@ -125,14 +130,57 @@ else if (one) { } private void show_msg(String txt) { - ((TextView)findViewById(R.id.upper_info)).setText(txt); + ((TextView) findViewById(R.id.upper_info)).setText(txt); } private void tshow_msg(String txt) { - final TextView tv = (TextView)findViewById(R.id.upper_info); + final TextView tv = (TextView) findViewById(R.id.upper_info); tv.post(() -> tv.setText(txt)); } + void need_storage() { + String perm = Manifest.permission.READ_EXTERNAL_STORAGE; + if (!shouldShowRequestPermissionRationale(perm)) { + request_storage(); + return; + } + AlertDialog.Builder ab = new AlertDialog.Builder(findViewById(R.id.upper_info).getContext()); + ab.setMessage("PartyUP! needs additional permissions to read that file, because the app you shared it from is using old APIs." + ).setPositiveButton("OK", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + request_storage(); + } + }).setNegativeButton("Cancel", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + + } + }).show(); + } + + void request_storage() { + String perm = Manifest.permission.READ_EXTERNAL_STORAGE; + requestPermissions(new String[]{perm}, 573); + } + + @Override + public void onRequestPermissionsResult(int permRequestCode, String perms[], int[] grantRes) { + String perm = Manifest.permission.READ_EXTERNAL_STORAGE; + if (permRequestCode != 573) + return; + + for (int a = 0; a < grantRes.length; a++) { + if (!perms[a].equals(perm)) + continue; + + if (grantRes[a] != PackageManager.PERMISSION_GRANTED) + return; + + handleSendImage(); + } + } + String getext(String mime) { if (mime == null) return "bin"; @@ -140,10 +188,14 @@ String getext(String mime) { mime = mime.replace(';', ' ').split(" ")[0]; switch (mime) { - case "audio/ogg": return "ogg"; - case "audio/mpeg": return "mp3"; - case "audio/mp4": return "m4a"; - case "image/jpeg": return "jpg"; + case "audio/ogg": + return "ogg"; + case "audio/mpeg": + return "mp3"; + case "audio/mp4": + return "m4a"; + case "image/jpeg": + return "jpg"; } if (mime.startsWith("text/")) @@ -167,28 +219,32 @@ private void handleSendText() { @SuppressLint("DefaultLocale") private void handleSendImage() { for (F f : files) { - // contentresolver returns the wrong filesize (off by 626 bytes) - // but we want the name so lets go - try { - Cursor cur = getContentResolver().query(f.handle, null, null, null, null); - assert cur != null; - int iname = cur.getColumnIndex(OpenableColumns.DISPLAY_NAME); - int isize = cur.getColumnIndex(OpenableColumns.SIZE); - cur.moveToFirst(); - f.name = cur.getString(iname); - f.size = cur.getLong(isize); - cur.close(); - } - catch (Exception ex) { - Log.w("me.ocv.partyup", "contentresolver: " + ex.toString()); + Log.d("me.ocv.partyup", format("handle [%s]", f.handle)); + if (f.handle.toString().startsWith("file:///")) { + f.name = Paths.get(f.handle.getPath()).getFileName().toString(); + } else { + // contentresolver returns the wrong filesize (off by 626 bytes) + // but we want the name so lets go + try { + Cursor cur = getContentResolver().query(f.handle, null, null, null, null); + assert cur != null; + int iname = cur.getColumnIndex(OpenableColumns.DISPLAY_NAME); + int isize = cur.getColumnIndex(OpenableColumns.SIZE); + cur.moveToFirst(); + f.name = cur.getString(iname); + f.size = cur.getLong(isize); + cur.close(); + } catch (Exception ex) { + Log.w("me.ocv.partyup", "contentresolver: " + ex.toString()); + } } MessageDigest md = null; if (f.name == null) { try { md = MessageDigest.getInstance("SHA-512"); + } catch (Exception ex) { } - catch (Exception ex) { } } // get correct filesize @@ -209,6 +265,10 @@ private void handleSendImage() { f.size = sz; } catch (Exception ex) { show_msg("Error3: " + ex.toString()); + if (this.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { + need_storage(); + return; + } return; } @@ -225,18 +285,17 @@ private void handleSendImage() { if (files.length == 1) { msg = "Upload the following file?\n\n" + files[0].desc; bytes_total = files[0].size; - } - else { + } else { msg = "Upload the following " + files.length + " files?\n\n"; for (int a = 0; a < Math.min(10, files.length); a++) { - msg += files[a].name + "\n"; + msg += " ► " + files[a].name + "\n"; bytes_total += files[a].size; } if (files.length > 10) msg += "[...]\n"; - msg += format("--- total %,d bytes ---", bytes_total); + msg += format("\n(total %,d bytes)", bytes_total); } show_msg(msg); if (prefs.getBoolean("autosend", false)) @@ -284,13 +343,11 @@ private void do_up2() { if (files == null) do_textmsg(conn); - else - if (!do_fileput(conn, a)) - return; + else if (!do_fileput(conn, a)) + return; } findViewById(R.id.upper_info).post(() -> onsuccess()); - } - catch (Exception ex) { + } catch (Exception ex) { tshow_msg("Error2: " + ex.toString() + "\n\nmaybe wrong password?"); } } @@ -350,7 +407,7 @@ private boolean do_fileput(HttpURLConnection conn, int nfile) throws Exception { double perc = ((double) bytes_done * 1000) / bytes_total; long td = 1 + System.currentTimeMillis() - t0; double spd = bytes_done / (td / 1000.0); - long left = (long)((bytes_total - bytes_done) / spd); + long left = (long) ((bytes_total - bytes_done) / spd); tv.setText(format("Sending to %s ...\n\nFile %d of %d:\n%s\n\nbytes done: %,d\nbytes left: %,d\nspeed: %.2f MiB/s\nprogress: %.2f %%\nETA: %d sec", base_url, nfile + 1, @@ -406,7 +463,7 @@ void onsuccess() { msg += "\n\n" + files.length + " files OK"; } show_msg(msg); - ((TextView)findViewById(R.id.upper_info)).setGravity(Gravity.CENTER); + ((TextView) findViewById(R.id.upper_info)).setGravity(Gravity.CENTER); String act = prefs.getString("on_up_ok", "menu"); if (act != null && !act.equals("menu")) { @@ -424,11 +481,11 @@ else if (act.equals("share")) findViewById(R.id.progbar).setVisibility(View.GONE); findViewById(R.id.successbuttons).setVisibility(View.VISIBLE); - Button btn = (Button)findViewById(R.id.btnExit); + Button btn = (Button) findViewById(R.id.btnExit); btn.setOnClickListener(v -> finishAndRemoveTask()); - Button vcopy = (Button)findViewById(R.id.btnCopyLink); - Button vshare = (Button)findViewById(R.id.btnShareLink); + Button vcopy = (Button) findViewById(R.id.btnCopyLink); + Button vshare = (Button) findViewById(R.id.btnShareLink); if (files == null) { vcopy.setVisibility(View.GONE); vshare.setVisibility(View.GONE); @@ -470,7 +527,7 @@ void sharelink() { view.setData(Uri.parse(f.share_url)); Intent i = Intent.createChooser(send, "Share file link"); - i.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[] { view }); + i.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[]{view}); startActivity(i); } } diff --git a/app/src/main/res/layout/activity_xfer.xml b/app/src/main/res/layout/activity_xfer.xml index 0ce9f47..fe6ffb3 100644 --- a/app/src/main/res/layout/activity_xfer.xml +++ b/app/src/main/res/layout/activity_xfer.xml @@ -27,6 +27,7 @@ android:layout_gravity="bottom|end" android:layout_marginEnd="@dimen/fab_margin" android:layout_marginBottom="16dp" + android:contentDescription="initiate upload" app:srcCompat="@android:drawable/ic_dialog_email" /> - - - - \ No newline at end of file diff --git a/app/src/main/res/xml/root_preferences.xml b/app/src/main/res/xml/root_preferences.xml index 696ce36..e661e8b 100644 --- a/app/src/main/res/xml/root_preferences.xml +++ b/app/src/main/res/xml/root_preferences.xml @@ -25,7 +25,7 @@ android:defaultValue="false" android:key="autosend" android:title="Just go" - app:summary="Upload right away, don't ask" /> + app:summary="Skip confirmation screen" />