diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/MusicFilesActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/MusicFilesActivity.java
index 2ef9cb662..746552dd8 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/MusicFilesActivity.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/MusicFilesActivity.java
@@ -16,26 +16,30 @@
along with this program. If not, see . */
package nodomain.freeyourgadget.gadgetbridge.activities;
-import android.app.Activity;
-import android.content.Intent;
+import android.content.res.AssetFileDescriptor;
+import android.media.MediaMetadataRetriever;
import android.net.Uri;
+import android.os.Build;
import android.os.Bundle;
import android.view.MenuItem;
-import androidx.activity.result.ActivityResult;
-import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
+import org.json.JSONException;
+import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.List;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
+import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
public class MusicFilesActivity extends AbstractGBActivity {
private static final Logger LOG = LoggerFactory.getLogger(MusicFilesActivity.class);
@@ -50,15 +54,53 @@ public class MusicFilesActivity extends AbstractGBActivity {
final ActivityResultLauncher activityResultLauncher = this.registerForActivityResult(
new ActivityResultContracts.GetMultipleContents(),
- urilist -> LOG.info("got {}", urilist)
+ urilist -> {
+ final MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();
+
+ LOG.info("Got {}", urilist);
+
+ for (final Uri uri : urilist) {
+ mediaMetadataRetriever.setDataSource(MusicFilesActivity.this, uri);
+
+ final String title = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE);
+ final String artist = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST);
+ final String album = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUM);
+
+ long fileSize;
+ try (AssetFileDescriptor fileDescriptor = getApplicationContext().getContentResolver().openAssetFileDescriptor(uri , "r")){
+ fileSize = fileDescriptor.getLength();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+
+ final JSONObject jsonObject = new JSONObject();
+ try {
+ jsonObject.put("title", title);
+ jsonObject.put("album", album);
+ jsonObject.put("artist", artist);
+ jsonObject.put("size", fileSize);
+ } catch (final JSONException e) {
+ throw new RuntimeException(e);
+ }
+
+ final String md5;
+ try (InputStream inputStream = getContentResolver().openInputStream(uri)) {
+ md5 = FileUtils.md5sum(inputStream);
+ } catch (final IOException e) {
+ throw new RuntimeException(e);
+ }
+
+ LOG.info("{}: {} {}", uri, md5, jsonObject);
+ }
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+ mediaMetadataRetriever.close();
+ }
+ }
);
final FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(v -> {
- final Intent intent = new Intent();
- intent.setType("audio/*");
- intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
- intent.setAction(Intent.ACTION_GET_CONTENT);
activityResultLauncher.launch("audio/*");
});
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/FileUtils.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/FileUtils.java
index 93b05e573..035aa407b 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/FileUtils.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/FileUtils.java
@@ -21,6 +21,7 @@ import android.content.ContentResolver;
import android.content.Context;
import android.net.Uri;
import android.os.Environment;
+import android.util.Log;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
@@ -34,12 +35,20 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
+import java.math.BigInteger;
import java.nio.channels.FileChannel;
import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
+import java.util.Locale;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.GBEnvironment;
@@ -349,4 +358,27 @@ public class FileUtils {
}
return extension;
}
-}
\ No newline at end of file
+
+ @Nullable
+ public static String md5sum(final InputStream is) {
+ MessageDigest digest;
+ try {
+ digest = MessageDigest.getInstance("MD5");
+ } catch (final NoSuchAlgorithmException e) {
+ Log.e(TAG, "Failed to get MD5 digest instance", e);
+ return null;
+ }
+
+ try {
+ final byte[] buffer = new byte[8192];
+ int read;
+ while ((read = is.read(buffer)) > 0) {
+ digest.update(buffer, 0, read);
+ }
+ return String.format("%1$32s", GB.hexdump(digest.digest())).replace(' ', '0').toLowerCase(Locale.ROOT);
+ } catch (final IOException e) {
+ Log.e(TAG, "Error reading file", e);
+ return null;
+ }
+ }
+}