mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge.git
synced 2025-02-10 07:47:12 +01:00
parse music files
This commit is contained in:
parent
51f23a30ea
commit
6e125563db
@ -16,26 +16,30 @@
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.content.res.AssetFileDescriptor;
|
||||||
import android.content.Intent;
|
import android.media.MediaMetadataRetriever;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
|
|
||||||
import androidx.activity.result.ActivityResult;
|
|
||||||
import androidx.activity.result.ActivityResultCallback;
|
|
||||||
import androidx.activity.result.ActivityResultLauncher;
|
import androidx.activity.result.ActivityResultLauncher;
|
||||||
import androidx.activity.result.contract.ActivityResultContracts;
|
import androidx.activity.result.contract.ActivityResultContracts;
|
||||||
|
|
||||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
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.R;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
|
||||||
|
|
||||||
public class MusicFilesActivity extends AbstractGBActivity {
|
public class MusicFilesActivity extends AbstractGBActivity {
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(MusicFilesActivity.class);
|
private static final Logger LOG = LoggerFactory.getLogger(MusicFilesActivity.class);
|
||||||
@ -50,15 +54,53 @@ public class MusicFilesActivity extends AbstractGBActivity {
|
|||||||
|
|
||||||
final ActivityResultLauncher<String> activityResultLauncher = this.registerForActivityResult(
|
final ActivityResultLauncher<String> activityResultLauncher = this.registerForActivityResult(
|
||||||
new ActivityResultContracts.GetMultipleContents(),
|
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);
|
final FloatingActionButton fab = findViewById(R.id.fab);
|
||||||
fab.setOnClickListener(v -> {
|
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/*");
|
activityResultLauncher.launch("audio/*");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ import android.content.ContentResolver;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
import java.io.BufferedInputStream;
|
||||||
import java.io.BufferedOutputStream;
|
import java.io.BufferedOutputStream;
|
||||||
@ -34,12 +35,20 @@ import java.io.IOException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.math.BigInteger;
|
||||||
import java.nio.channels.FileChannel;
|
import java.nio.channels.FileChannel;
|
||||||
import java.nio.charset.StandardCharsets;
|
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.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBEnvironment;
|
import nodomain.freeyourgadget.gadgetbridge.GBEnvironment;
|
||||||
|
|
||||||
@ -349,4 +358,27 @@ public class FileUtils {
|
|||||||
}
|
}
|
||||||
return extension;
|
return extension;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user