nextNoteVault #23
@ -5,12 +5,13 @@ import androidx.room.Database;
 | 
			
		||||
import androidx.room.Room;
 | 
			
		||||
import androidx.room.RoomDatabase;
 | 
			
		||||
import androidx.room.TypeConverters;
 | 
			
		||||
import com.stormtales.notevault.data.entities.NoteSheet;
 | 
			
		||||
import com.stormtales.notevault.data.entities.Song;
 | 
			
		||||
import com.stormtales.notevault.data.dao.SongDao;
 | 
			
		||||
import com.stormtales.notevault.data.sync.DateConverter;
 | 
			
		||||
import com.stormtales.notevault.data.sync.SyncStatusConverter;
 | 
			
		||||
 | 
			
		||||
@Database(entities = {Song.class}, version = 1, exportSchema = false)
 | 
			
		||||
@Database(entities = {Song.class, NoteSheet.class}, version = 1, exportSchema = false)
 | 
			
		||||
@TypeConverters({SyncStatusConverter.class, DateConverter.class})
 | 
			
		||||
public abstract class MusicDatabase extends RoomDatabase {
 | 
			
		||||
    public abstract SongDao getSongTable();
 | 
			
		||||
 | 
			
		||||
@ -1,10 +1,8 @@
 | 
			
		||||
package com.stormtales.notevault.data.dao;
 | 
			
		||||
 | 
			
		||||
import androidx.lifecycle.LiveData;
 | 
			
		||||
import androidx.room.Dao;
 | 
			
		||||
import androidx.room.Insert;
 | 
			
		||||
import androidx.room.Query;
 | 
			
		||||
import androidx.room.Update;
 | 
			
		||||
import androidx.room.*;
 | 
			
		||||
import com.stormtales.notevault.data.entities.NoteSheet;
 | 
			
		||||
import com.stormtales.notevault.data.entities.Song;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
@ -12,11 +10,19 @@ import java.util.List;
 | 
			
		||||
@Dao
 | 
			
		||||
public interface SongDao {
 | 
			
		||||
    @Insert
 | 
			
		||||
    void insert(Song song);
 | 
			
		||||
    long insert(Song song);
 | 
			
		||||
 | 
			
		||||
    @Query("SELECT * FROM song WHERE syncStatus != 1")
 | 
			
		||||
    List<Song> getAllSongs();
 | 
			
		||||
 | 
			
		||||
    @Update
 | 
			
		||||
    void update(Song song);
 | 
			
		||||
 | 
			
		||||
    @Insert
 | 
			
		||||
    void insert(List<NoteSheet> noteSheets);
 | 
			
		||||
 | 
			
		||||
    @Delete
 | 
			
		||||
    void deleteNoteSheets(List<NoteSheet> noteSheets);
 | 
			
		||||
 | 
			
		||||
    List<NoteSheet> getNoteSheetsBySong(int songID);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -7,13 +7,17 @@ import java.util.Objects;
 | 
			
		||||
 | 
			
		||||
@Entity
 | 
			
		||||
public class NoteSheet {
 | 
			
		||||
    @PrimaryKey
 | 
			
		||||
    @PrimaryKey(autoGenerate = true)
 | 
			
		||||
    private int localID;
 | 
			
		||||
 | 
			
		||||
    private int songID;
 | 
			
		||||
    private String localFileName;
 | 
			
		||||
    private String hash;
 | 
			
		||||
 | 
			
		||||
    public NoteSheet(String localFileName, String hash) {
 | 
			
		||||
        this.localFileName = localFileName;
 | 
			
		||||
        this.hash = hash;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getLocalID() {
 | 
			
		||||
        return localID;
 | 
			
		||||
    }
 | 
			
		||||
@ -49,4 +53,12 @@ public class NoteSheet {
 | 
			
		||||
    public int hashCode() {
 | 
			
		||||
        return Objects.hash(localID, localFileName, hash);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getSongID() {
 | 
			
		||||
        return songID;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setSongID(int songID) {
 | 
			
		||||
        this.songID = songID;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -7,7 +7,9 @@ import android.os.Looper;
 | 
			
		||||
import androidx.lifecycle.LiveData;
 | 
			
		||||
import com.stormtales.notevault.data.MusicDatabase;
 | 
			
		||||
import com.stormtales.notevault.data.dao.SongDao;
 | 
			
		||||
import com.stormtales.notevault.data.entities.NoteSheet;
 | 
			
		||||
import com.stormtales.notevault.data.entities.Song;
 | 
			
		||||
import com.stormtales.notevault.data.sync.SyncStatus;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.concurrent.ExecutorService;
 | 
			
		||||
@ -19,9 +21,11 @@ public class SongRepository {
 | 
			
		||||
        MusicDatabase database = MusicDatabase.getDatabase(context);
 | 
			
		||||
        songDao = database.getSongTable();
 | 
			
		||||
    }
 | 
			
		||||
    public void insert(Song song) {
 | 
			
		||||
    public void insert(Song song, Callback<Long> callback) {
 | 
			
		||||
        Executors.newSingleThreadExecutor().execute(() -> {
 | 
			
		||||
            songDao.insert(song);
 | 
			
		||||
            long result = songDao.insert(song);
 | 
			
		||||
            Handler mainHandler = new Handler(Looper.getMainLooper());
 | 
			
		||||
            mainHandler.post(()-> callback.onResult(result));
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -43,4 +47,19 @@ public class SongRepository {
 | 
			
		||||
            songDao.update(song);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void insertNoteSheets(List<NoteSheet> noteSheets) {
 | 
			
		||||
        Executors.newSingleThreadExecutor().execute(() -> {
 | 
			
		||||
            songDao.insert(noteSheets);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public interface Callback<T> {
 | 
			
		||||
        void onResult(T result);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void deleteSong(Song song) {
 | 
			
		||||
        song.setSyncStatus(SyncStatus.DELETED);
 | 
			
		||||
        songDao.update(song);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,15 +1,13 @@
 | 
			
		||||
package com.stormtales.notevault.ui.home;
 | 
			
		||||
 | 
			
		||||
import android.app.Application;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.lifecycle.LiveData;
 | 
			
		||||
import androidx.lifecycle.MutableLiveData;
 | 
			
		||||
import androidx.lifecycle.ViewModel;
 | 
			
		||||
import com.stormtales.notevault.data.entities.NoteSheet;
 | 
			
		||||
import com.stormtales.notevault.data.entities.Song;
 | 
			
		||||
import com.stormtales.notevault.data.repositories.SongRepository;
 | 
			
		||||
import com.stormtales.notevault.data.sync.SyncStatus;
 | 
			
		||||
import kotlinx.coroutines.CoroutineScope;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
@ -25,8 +23,15 @@ public class HomeViewModel extends ViewModel {
 | 
			
		||||
        /*this.allSongs.setValue(songRepository.getAllSongs());*/
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void addSong(Song song) {
 | 
			
		||||
        songRepository.insert(song);
 | 
			
		||||
    public void addSong(Song song, List<NoteSheet> noteSheetList) {
 | 
			
		||||
        songRepository.insert(song, internalSongID -> {
 | 
			
		||||
            for(NoteSheet noteSheet : noteSheetList) {
 | 
			
		||||
                noteSheet.setSongID(Math.toIntExact(internalSongID));
 | 
			
		||||
            }
 | 
			
		||||
            songRepository.insertNoteSheets(noteSheetList);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        List<Song> currentSongs = allSongs.getValue();
 | 
			
		||||
        if(currentSongs == null) {
 | 
			
		||||
            currentSongs = new ArrayList<>();
 | 
			
		||||
@ -54,8 +59,7 @@ public class HomeViewModel extends ViewModel {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void deleteSong(Song song) {
 | 
			
		||||
        song.setSyncStatus(SyncStatus.DELETED);
 | 
			
		||||
        songRepository.updateSong(song);
 | 
			
		||||
        songRepository.deleteSong(song);
 | 
			
		||||
 | 
			
		||||
        List<Song> currentSongs = allSongs.getValue();
 | 
			
		||||
        if(currentSongs != null) {
 | 
			
		||||
 | 
			
		||||
@ -2,6 +2,7 @@ package com.stormtales.notevault.ui.songeditor;
 | 
			
		||||
 | 
			
		||||
import android.app.AlertDialog;
 | 
			
		||||
import android.app.Dialog;
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.net.Uri;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import android.text.Layout;
 | 
			
		||||
@ -16,11 +17,17 @@ import android.view.View;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
import androidx.lifecycle.ViewModelProvider;
 | 
			
		||||
import com.stormtales.notevault.R;
 | 
			
		||||
import com.stormtales.notevault.data.entities.NoteSheet;
 | 
			
		||||
import com.stormtales.notevault.data.entities.Song;
 | 
			
		||||
import com.stormtales.notevault.data.sync.SyncStatus;
 | 
			
		||||
import com.stormtales.notevault.ui.home.HomeViewModel;
 | 
			
		||||
import com.stormtales.notevault.utils.NoteSheetsUtil;
 | 
			
		||||
import com.stormtales.notevault.utils.Tupel;
 | 
			
		||||
import org.jetbrains.annotations.NotNull;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
public class SongEditorDialog extends DialogFragment {
 | 
			
		||||
 | 
			
		||||
@ -89,7 +96,15 @@ public class SongEditorDialog extends DialogFragment {
 | 
			
		||||
            homeViewModel.updateSong(editedSong);
 | 
			
		||||
        } else {
 | 
			
		||||
            Song song = new Song(title, composer, genre, releaseYear);
 | 
			
		||||
            homeViewModel.addSong(song);
 | 
			
		||||
 | 
			
		||||
            List<NoteSheet> noteSheetList = new ArrayList<>();
 | 
			
		||||
            Context context = this.getContext();
 | 
			
		||||
            for(Uri uri : noteSheetFiles) {
 | 
			
		||||
                Tupel<String, String> result = NoteSheetsUtil.saveImageInternally(context.getContentResolver(), uri, context.getFilesDir());
 | 
			
		||||
                noteSheetList.add(new NoteSheet(result.getValue00(), result.getValue01()));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            homeViewModel.addSong(song, noteSheetList);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,6 @@
 | 
			
		||||
package com.stormtales.notevault.utils;
 | 
			
		||||
 | 
			
		||||
import android.content.ContentResolver;
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.media.ExifInterface;
 | 
			
		||||
import android.net.Uri;
 | 
			
		||||
@ -7,6 +8,10 @@ import android.net.Uri;
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.io.OutputStream;
 | 
			
		||||
import java.nio.file.Files;
 | 
			
		||||
import java.security.MessageDigest;
 | 
			
		||||
import java.security.NoSuchAlgorithmException;
 | 
			
		||||
import java.text.ParseException;
 | 
			
		||||
import java.text.SimpleDateFormat;
 | 
			
		||||
import java.util.*;
 | 
			
		||||
@ -46,4 +51,37 @@ public class NoteSheetsUtil {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static Tupel<String, String> saveImageInternally(ContentResolver contentResolver, Uri uri, File filesDir) {
 | 
			
		||||
        try (InputStream inputStream = contentResolver.openInputStream(uri)) {
 | 
			
		||||
            // Datei erstellen
 | 
			
		||||
            File imageFile = new File(filesDir, "saved_image_" + System.currentTimeMillis() + ".jpg");
 | 
			
		||||
            try (OutputStream outputStream = Files.newOutputStream(imageFile.toPath())) {
 | 
			
		||||
                // SHA-256 Hash-Funktion initialisieren
 | 
			
		||||
                MessageDigest digest = MessageDigest.getInstance("SHA-256");
 | 
			
		||||
 | 
			
		||||
                // Daten blockweise lesen und gleichzeitig schreiben und hashen
 | 
			
		||||
                byte[] buffer = new byte[4096];
 | 
			
		||||
                int bytesRead;
 | 
			
		||||
                while ((bytesRead = inputStream.read(buffer)) != -1) {
 | 
			
		||||
                    outputStream.write(buffer, 0, bytesRead);
 | 
			
		||||
                    digest.update(buffer, 0, bytesRead); // Hash aktualisieren
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Hash berechnen
 | 
			
		||||
                byte[] hashBytes = digest.digest();
 | 
			
		||||
                StringBuilder hashString = new StringBuilder();
 | 
			
		||||
                for (byte b : hashBytes) {
 | 
			
		||||
                    hashString.append(String.format("%02x", b)); // Bytes in Hexadezimal umwandeln
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Hashwert zurückgeben (kann auch zusammen mit dem Pfad gespeichert werden)
 | 
			
		||||
                return new Tupel<>(imageFile.getAbsolutePath(), hashString.toString());
 | 
			
		||||
            } catch (NoSuchAlgorithmException e) {
 | 
			
		||||
                throw new RuntimeException(e);
 | 
			
		||||
            }
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										33
									
								
								app/src/main/java/com/stormtales/notevault/utils/Tupel.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								app/src/main/java/com/stormtales/notevault/utils/Tupel.java
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,33 @@
 | 
			
		||||
package com.stormtales.notevault.utils;
 | 
			
		||||
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
 | 
			
		||||
public class Tupel<A,B> {
 | 
			
		||||
    private final A value00;
 | 
			
		||||
    private final B value01;
 | 
			
		||||
 | 
			
		||||
    public Tupel(A value00, B value01) {
 | 
			
		||||
        this.value00 = value00;
 | 
			
		||||
        this.value01 = value01;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public A getValue00() {
 | 
			
		||||
        return value00;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public B getValue01() {
 | 
			
		||||
        return value01;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean equals(Object o) {
 | 
			
		||||
        if (o == null || getClass() != o.getClass()) return false;
 | 
			
		||||
        Tupel<?, ?> tupel = (Tupel<?, ?>) o;
 | 
			
		||||
        return Objects.equals(value00, tupel.value00) && Objects.equals(value01, tupel.value01);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int hashCode() {
 | 
			
		||||
        return Objects.hash(value00, value01);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user