Enable Notes with multiple Sheets

This commit is contained in:
sebastian 2024-11-01 08:48:30 +01:00
parent 6a7eb2f8ca
commit 288e06be7c
16 changed files with 236 additions and 51 deletions

15
.idea/dataSources.xml Normal file
View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
<data-source source="LOCAL" name="music_database" uuid="7fd8322d-6535-44e0-a663-86c7b54f4fbd">
<driver-ref>sqlite.xerial</driver-ref>
<synchronize>true</synchronize>
<jdbc-driver>org.sqlite.JDBC</jdbc-driver>
<jdbc-url>jdbc:sqlite:$PROJECT_DIR$/music_database</jdbc-url>
<jdbc-additional-properties>
<property name="com.intellij.clouds.kubernetes.db.enabled" value="false" />
</jdbc-additional-properties>
<working-dir>$ProjectFileDir$</working-dir>
</data-source>
</component>
</project>

View File

@ -16,6 +16,7 @@ import androidx.drawerlayout.widget.DrawerLayout;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import core.notevault.data.MusicDatabase; import core.notevault.data.MusicDatabase;
import core.notevault.data.MusicNote; import core.notevault.data.MusicNote;
import core.notevault.data.NoteSheet;
import core.notevault.databinding.ActivityMainBinding; import core.notevault.databinding.ActivityMainBinding;
import core.notevault.ui.metadatadialog.MetaDataDialog; import core.notevault.ui.metadatadialog.MetaDataDialog;
@ -67,14 +68,16 @@ public class MainActivity extends AppCompatActivity implements MetaDataDialog.On
} }
@Override @Override
public void onMetadataEntered(Uri uri, String title, String composer, int year, String genre) { public void onMetadataEntered(Uri[] uris, String title, String composer, int year, String genre) {
String path = saveImageInternally(uri);
MusicNote musicNote = new MusicNote(title, path, composer, year, genre);
// Anfordern der dauerhaften Lese-/Schreibberechtigungen für die URI
new Thread(() -> { new Thread(() -> {
musicDB.musicNoteDao().insert(musicNote); MusicNote musicNote = new MusicNote(title, composer, year, genre);
long musicNoteID = musicDB.musicNoteDao().insert(musicNote);
for(Uri uri: uris) {
String filePath = saveImageInternally(uri);
NoteSheet noteSheet = new NoteSheet(musicNoteID, filePath);
musicDB.musicNoteDao().insertNoteSheet(noteSheet);
}
}).start(); }).start();
} }

View File

@ -5,7 +5,7 @@ import androidx.room.Room;
import androidx.room.RoomDatabase; import androidx.room.RoomDatabase;
import androidx.room.Database; import androidx.room.Database;
@Database(entities = {MusicNote.class}, version = 1, exportSchema = false) @Database(entities = {MusicNote.class, NoteSheet.class}, version = 1, exportSchema = false)
public abstract class MusicDatabase extends RoomDatabase { public abstract class MusicDatabase extends RoomDatabase {
public abstract MusicNoteDAO musicNoteDao(); public abstract MusicNoteDAO musicNoteDao();

View File

@ -1,22 +1,22 @@
package core.notevault.data; package core.notevault.data;
import androidx.room.Entity; import androidx.room.Entity;
import androidx.room.Ignore;
import androidx.room.PrimaryKey; import androidx.room.PrimaryKey;
@Entity(tableName = "music_notes") @Entity(tableName = "music_notes")
public class MusicNote { public class MusicNote {
@PrimaryKey(autoGenerate = true) @PrimaryKey(autoGenerate = true)
private int id; private long musicNoteId;
private String title; private String title;
private String filePath;
private String composer; private String composer;
private int year; private int year;
private String genre; private String genre;
public MusicNote(String title, String filePath, String composer, int year, String genre) { @Ignore
public MusicNote(String title, String composer, int year, String genre) {
this.title = title; this.title = title;
this.filePath = filePath;
this.composer = composer; this.composer = composer;
this.year = year; this.year = year;
this.genre = genre; this.genre = genre;
@ -25,12 +25,12 @@ public class MusicNote {
public MusicNote() { public MusicNote() {
} }
public int getId() { public long getMusicNoteId() {
return id; return musicNoteId;
} }
public void setId(int id) { public void setMusicNoteId(long musicNoteId) {
this.id = id; this.musicNoteId = musicNoteId;
} }
public String getTitle() { public String getTitle() {
@ -41,14 +41,6 @@ public class MusicNote {
this.title = title; this.title = title;
} }
public String getFilePath() {
return filePath;
}
public void setFilePath(String filePath) {
this.filePath = filePath;
}
public String getComposer() { public String getComposer() {
return composer; return composer;
} }

View File

@ -10,8 +10,14 @@ import java.util.List;
public interface MusicNoteDAO { public interface MusicNoteDAO {
@Insert @Insert
void insert(MusicNote musicNote); long insert(MusicNote musicNote);
@Insert
void insertNoteSheet(NoteSheet noteSheet);
@Query("SELECT * FROM music_notes") @Query("SELECT * FROM music_notes")
List<MusicNote> getAllNotes(); List<MusicNote> getAllNotes();
@Query("SELECT * FROM note_sheets")
List<NoteSheet> getNoteSheetsForMusicSong();
} }

View File

@ -0,0 +1,46 @@
package core.notevault.data;
import androidx.room.Entity;
import androidx.room.PrimaryKey;
@Entity(tableName = "note_sheets")
public class NoteSheet {
@PrimaryKey(autoGenerate = true)
private int id;
private long musicNoteId;
private String filePath;
public NoteSheet(long musicNoteID, String filePath) {
this.musicNoteId = musicNoteID;
this.filePath = filePath;
}
public NoteSheet() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public long getMusicNoteId() {
return musicNoteId;
}
public void setMusicNoteId(long musicNoteId) {
this.musicNoteId = musicNoteId;
}
public String getFilePath() {
return filePath;
}
public void setFilePath(String filePath) {
this.filePath = filePath;
}
}

View File

@ -5,7 +5,12 @@ import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.widget.ImageView; import android.widget.ImageView;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager2.widget.ViewPager2;
import core.notevault.R; import core.notevault.R;
import core.notevault.ui.noteviewer.ImagePagerAdapter;
import java.util.Arrays;
import java.util.List;
public class FullScreenImageActivity extends AppCompatActivity { public class FullScreenImageActivity extends AppCompatActivity {
@ -14,14 +19,17 @@ public class FullScreenImageActivity extends AppCompatActivity {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fullscreen_image); // Erstelle eine Layout-Datei setContentView(R.layout.activity_fullscreen_image); // Erstelle eine Layout-Datei
ImageView imageView = findViewById(R.id.fullscreen_image_view); // Angenommen, du hast ein ImageView ViewPager2 imageView = findViewById(R.id.viewPager); // Angenommen, du hast ein ImageView
// Die URI aus dem Intent erhalten // Die URI aus dem Intent erhalten
Intent intent = getIntent(); Intent intent = getIntent();
String imageUriString = intent.getStringExtra("imageUri"); String[] imageUris = intent.getStringArrayExtra("imageUris");
if (imageUriString != null) { if (imageUris != null) {
Uri imageUri = Uri.parse(imageUriString); List<String> uriList = Arrays.asList(imageUris);
imageView.setImageURI(imageUri); // Setze die URI in das ImageView ImagePagerAdapter adapter = new ImagePagerAdapter(this, uriList);
imageView.setAdapter(adapter); // Setze die URI in das ImageView
} else {
throw new NullPointerException();
} }
} }
} }

View File

@ -76,21 +76,27 @@ public class HomeFragment extends Fragment {
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data); super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_FILE_REQUEST_CODE && resultCode == getActivity().RESULT_OK && data != null) { if (requestCode == PICK_FILE_REQUEST_CODE && resultCode == getActivity().RESULT_OK && data != null) {
Uri uri = data.getData(); if(data.getClipData() != null) {
if (uri != null) { int count = data.getClipData().getItemCount();
Uri[] uris = new Uri[count];
for(int i = 0; i < count; i++) {
uris[i] = data.getClipData().getItemAt(i).getUri();
}
handleFile(uris);
} else if(data.getData() != null) {
Uri uri = data.getData();
handleFile(uri); handleFile(uri);
} }
} }
} }
private void handleFile(Uri uri) { private void handleFile(Uri... uris) {
// Hier kannst du die Logik zum Speichern oder Anzeigen der Datei implementieren // Hier kannst du die Logik zum Speichern oder Anzeigen der Datei implementieren
MetaDataDialog metaDataDialog = new MetaDataDialog(); MetaDataDialog metaDataDialog = new MetaDataDialog();
metaDataDialog.setFileUri(uri); metaDataDialog.setFileUri(uris);
metaDataDialog.show(getParentFragmentManager(), MetaDataDialog.TAG); metaDataDialog.show(getParentFragmentManager(), MetaDataDialog.TAG);
homeViewModel.addNote(uri); // Speichere die URI im ViewModel Toast.makeText(getActivity(), "Datei ausgewählt: " + uris[0].getPath(), Toast.LENGTH_SHORT).show();
Toast.makeText(getActivity(), "Datei ausgewählt: " + uri.getPath(), Toast.LENGTH_SHORT).show();
} }
private void openFileChooser() { private void openFileChooser() {
@ -99,6 +105,7 @@ public class HomeFragment extends Fragment {
String[] mimeTypes = {"application/pdf", "image/png", "image/jpeg"}; String[] mimeTypes = {"application/pdf", "image/png", "image/jpeg"};
intent.putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes); intent.putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes);
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
intent.addCategory(Intent.CATEGORY_OPENABLE); intent.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(intent, PICK_FILE_REQUEST_CODE); startActivityForResult(intent, PICK_FILE_REQUEST_CODE);

View File

@ -1,6 +1,8 @@
package core.notevault.ui.home; package core.notevault.ui.home;
import android.content.Intent; import android.content.Intent;
import android.os.AsyncTask;
import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -8,7 +10,10 @@ import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import core.notevault.R; import core.notevault.R;
import core.notevault.data.MusicDatabase;
import core.notevault.data.MusicNote; import core.notevault.data.MusicNote;
import core.notevault.data.MusicNoteDAO;
import core.notevault.data.NoteSheet;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -49,7 +54,7 @@ public class NoteSongAdapter extends RecyclerView.Adapter<NoteSongAdapter.NoteVi
notifyDataSetChanged(); notifyDataSetChanged();
} }
public class NoteViewHolder extends RecyclerView.ViewHolder { public class NoteViewHolder extends RecyclerView.ViewHolder{
TextView titleTextView; TextView titleTextView;
NoteViewHolder(View itemView) { NoteViewHolder(View itemView) {
@ -62,8 +67,19 @@ public class NoteSongAdapter extends RecyclerView.Adapter<NoteSongAdapter.NoteVi
MusicNote musicNote = noteTitles.get(position); MusicNote musicNote = noteTitles.get(position);
Intent intent = new Intent(itemView.getContext(), FullScreenImageActivity.class); Intent intent = new Intent(itemView.getContext(), FullScreenImageActivity.class);
intent.putExtra("imageUri", musicNote.getFilePath()); // Hier URI hinzufügen new LoadNoteSheetsTask(musicNote.getMusicNoteId(),
itemView.getContext().startActivity(intent); MusicDatabase.getDatabase(itemView.getContext()).musicNoteDao(), new OnNoteSheedsLoadedListener() {
@Override
public void onNoteSheetsLoaded(List<NoteSheet> noteSheets) {
String[] noteSheetFiles = new String[noteSheets.size()];
for (int i = 0; i < noteSheets.size(); i++) {
noteSheetFiles[i] = noteSheets.get(i).getFilePath();
}
intent.putExtra("imageUris", noteSheetFiles);
itemView.getContext().startActivity(intent);
}
}).execute();
} }
}); });
} }
@ -71,5 +87,37 @@ public class NoteSongAdapter extends RecyclerView.Adapter<NoteSongAdapter.NoteVi
public void bind(MusicNote note) { public void bind(MusicNote note) {
titleTextView.setText(note.getTitle()); titleTextView.setText(note.getTitle());
} }
}
public interface OnNoteSheedsLoadedListener {
void onNoteSheetsLoaded(List<NoteSheet> noteSheets);
}
private class LoadNoteSheetsTask extends AsyncTask<Void, Void, List<NoteSheet>> {
private final long musicNoteId;
private final MusicNoteDAO musicNoteDAO;
private final OnNoteSheedsLoadedListener listener;
public LoadNoteSheetsTask(long musicNoteId, MusicNoteDAO musicNoteDAO, OnNoteSheedsLoadedListener listener) {
this.musicNoteId = musicNoteId;
this.musicNoteDAO = musicNoteDAO;
this.listener = listener;
}
@Override
protected List<NoteSheet> doInBackground(Void... voids) {
List<NoteSheet> sheets = musicNoteDAO.getNoteSheetsForMusicSong();
Log.d("LoadNoteSheetsTask", "Loaded NoteSheets: " + sheets.get(0));
return sheets;
}
@Override
protected void onPostExecute(List<NoteSheet> sheets) {
listener.onNoteSheetsLoaded(sheets);
}
} }
} }

View File

@ -16,10 +16,10 @@ import androidx.fragment.app.DialogFragment;
import core.notevault.R; import core.notevault.R;
public class MetaDataDialog extends DialogFragment { public class MetaDataDialog extends DialogFragment {
private Uri fileUri; private Uri[] fileUri;
public interface OnMetadataListener { public interface OnMetadataListener {
void onMetadataEntered(Uri uri, String title, String composer, int year, String genre); void onMetadataEntered(Uri[] uri, String title, String composer, int year, String genre);
} }
private OnMetadataListener listener; private OnMetadataListener listener;
@ -67,11 +67,11 @@ public class MetaDataDialog extends DialogFragment {
} }
} }
public Uri getFileUri() { public Uri[] getFileUri() {
return fileUri; return fileUri;
} }
public void setFileUri(Uri fileUri) { public void setFileUri(Uri[] fileUri) {
this.fileUri = fileUri; this.fileUri = fileUri;
} }
@ -79,9 +79,9 @@ public class MetaDataDialog extends DialogFragment {
String fileName = ""; String fileName = "";
// Überprüfen, ob die Uri ein Content-Uri ist // Überprüfen, ob die Uri ein Content-Uri ist
if (this.fileUri.getScheme().equals("content")) { if (this.fileUri[0].getScheme().equals("content")) {
// ContentResolver verwenden, um die Datei zu finden // ContentResolver verwenden, um die Datei zu finden
Cursor cursor = requireContext().getContentResolver().query(this.fileUri, null, null, null, null); Cursor cursor = requireContext().getContentResolver().query(this.fileUri[0], null, null, null, null);
if (cursor != null) { if (cursor != null) {
int nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME); int nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
if (cursor.moveToFirst()) { if (cursor.moveToFirst()) {
@ -90,9 +90,9 @@ public class MetaDataDialog extends DialogFragment {
} }
cursor.close(); cursor.close();
} }
} else if (this.fileUri.getScheme().equals("file")) { } else if (this.fileUri[0].getScheme().equals("file")) {
// Bei einer Datei-Uri einfach den letzten Pfadsegment verwenden // Bei einer Datei-Uri einfach den letzten Pfadsegment verwenden
fileName = this.fileUri.getLastPathSegment(); fileName = this.fileUri[0].getLastPathSegment();
} }
if(fileName.contains(".")) { if(fileName.contains(".")) {

View File

@ -0,0 +1,50 @@
package core.notevault.ui.noteviewer;
import android.content.Context;
import android.net.Uri;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.github.chrisbanes.photoview.PhotoView;
import core.notevault.R;
import java.util.List;
public class ImagePagerAdapter extends RecyclerView.Adapter<ImagePagerAdapter.ImageViewHolder> {
private final List<String> imageUris;
private final Context context;
public ImagePagerAdapter(Context context, List<String> imageUris) {
this.context = context;
this.imageUris = imageUris;
}
@NonNull
@Override
public ImageViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.item_image, parent, false);
return new ImageViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ImageViewHolder holder, int position) {
Uri uri = Uri.parse(imageUris.get(position));
holder.photoView.setImageURI(uri);
}
@Override
public int getItemCount() {
return imageUris.size();
}
static class ImageViewHolder extends RecyclerView.ViewHolder {
PhotoView photoView;
ImageViewHolder(View itemView) {
super(itemView);
photoView = itemView.findViewById(R.id.photoView);
}
}
}

View File

@ -4,9 +4,8 @@
android:layout_height="match_parent"> android:layout_height="match_parent">
<com.github.chrisbanes.photoview.PhotoView <androidx.viewpager2.widget.ViewPager2
android:id="@+id/fullscreen_image_view" android:id="@+id/viewPager"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent" />
android:scaleType="fitCenter" />
</RelativeLayout> </RelativeLayout>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.github.chrisbanes.photoview.PhotoView
android:id="@+id/photoView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitCenter" />
</FrameLayout>

BIN
music_database Normal file

Binary file not shown.

BIN
music_database-shm Normal file

Binary file not shown.

0
music_database-wal Normal file
View File