mirror of
https://github.com/playmusicexporter/playmusicexporter
synced 2024-05-15 17:46:42 +00:00
Merge branch 'overwrite_preference' of github.com:jcgruenhage/PlayMusicExporter into overwrite_preference
This commit is contained in:
commit
dc87dc7c4b
31
README.md
31
README.md
|
@ -1,21 +1,38 @@
|
|||
# Play Music Exporter
|
||||
|
||||
This Android app exports your Play Music mp3 files directly to your sdcard using root permissions.
|
||||
This Android app exports your Play Music mp3 files directly to your sdcard
|
||||
or a documents provider using root permissions.
|
||||
You can also setup automatic export, that exports all currently cached not yet exported music.
|
||||
|
||||
## About
|
||||
|
||||
This AndroidStudio project allow you to access the database from Google's PlayMusic and also allows you to export the music files as mp3 to your sdcard. There is also a nice library you can simply use in your projects.
|
||||
This AndroidStudio project allow you to access the database from Google's PlayMusic
|
||||
and also allows you to export the music files as mp3 to your sdcard or a documents provider.
|
||||
There is also a nice library you can simply use in your projects.
|
||||
|
||||
### Requirements
|
||||
|
||||
**This app and its library will require root access to your device! If your device is not rooted you can't use this app neither the lib.**
|
||||
**This app and the included library will require root access to your device!
|
||||
If your device is not rooted you can neither use this app nor the library.**
|
||||
|
||||
This project uses the [mp3agic library](https://github.com/mpatric/mp3agic) by [Michael Patricios (mpatric)](https://github.com/mpatric).
|
||||
This app uses API Level 21, which has been introduced by Android Lollipop. If you use KitKat
|
||||
or lower, this app will not work.
|
||||
|
||||
### Notice
|
||||
### Credits
|
||||
|
||||
I recently forked this repository and most of the work has been done by [David Schulte](https://www.david-schulte.de/).
|
||||
You can find his old/inactive repository [here](https://github.com/Arcus92/PlayMusicExporter).
|
||||
This is a fork off [David Schulte's original project](https://github.com/Arcus92/PlayMusicExporter).
|
||||
Most of the work has been done by him, me and the other collaborators just have improved his work
|
||||
in some minor ways, like making the app more usable and configurable. The exporting itself, the hard
|
||||
part, has been done by him.
|
||||
|
||||
This project uses the [mp3agic library](https://github.com/mpatric/mp3agic)
|
||||
by [Michael Patricios (mpatric)](https://github.com/mpatric).
|
||||
|
||||
### Contributing
|
||||
|
||||
If you want to contribute to this project, fork off of develop,
|
||||
implement what you want to implement, and submit a pull request back into develop.
|
||||
After testing it, if enough of the collaborators like it, we will merge it.
|
||||
|
||||
### Copyright
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK"/>
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
|
|
|
@ -22,8 +22,10 @@
|
|||
|
||||
package re.jcg.playmusicexporter.fragments;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.PowerManager;
|
||||
import android.support.design.widget.FloatingActionButton;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.text.TextUtils;
|
||||
|
@ -63,6 +65,7 @@ public class MusicTrackListFragment extends Fragment {
|
|||
*/
|
||||
public static final String ARG_MUSIC_TRACK_LIST_ID = "music_track_list_id";
|
||||
public static final String ARG_MUSIC_TRACK_LIST_TYPE = "music_track_list_type";
|
||||
private PowerManager.WakeLock m_CPULock;
|
||||
|
||||
/**
|
||||
* The track list
|
||||
|
@ -138,6 +141,8 @@ public class MusicTrackListFragment extends Fragment {
|
|||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
PowerManager powerManager = (PowerManager)this.getContext().getSystemService(Context.POWER_SERVICE);
|
||||
m_CPULock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ExportAllService");
|
||||
if (getArguments().containsKey(ARG_MUSIC_TRACK_LIST_ID)
|
||||
&& getArguments().containsKey(ARG_MUSIC_TRACK_LIST_TYPE)) {
|
||||
|
||||
|
@ -213,12 +218,19 @@ public class MusicTrackListFragment extends Fragment {
|
|||
mFloatingButtonExport = (FloatingActionButton) rootView.findViewById(R.id.floating_button_export);
|
||||
mFloatingButtonExport.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
public void onClick(View v)
|
||||
{
|
||||
m_CPULock.acquire();
|
||||
// Export all selected tracks
|
||||
for (SelectedTrack selectedTrack : SelectedTrackList.getInstance().getSelectedItems()) {
|
||||
selectedTrack.export(getActivity());
|
||||
}
|
||||
|
||||
if ( m_CPULock.isHeld())
|
||||
{
|
||||
m_CPULock.release();
|
||||
}
|
||||
|
||||
// Clear the selection
|
||||
SelectedTrackList.getInstance().clear(true);
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import android.app.IntentService;
|
|||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.PowerManager;
|
||||
import android.support.v4.provider.DocumentFile;
|
||||
import android.util.Log;
|
||||
|
||||
|
@ -24,6 +25,7 @@ public class ExportAllService extends IntentService {
|
|||
public static final String TAG = "AutoGPME_ExportService";
|
||||
public static final String ACTION_EXPORT = "re.jcg.playmusicexporter.action.EXPORT";
|
||||
public static final String ACTION_SET_EXPORT_JOB = "re.jcg.playmusicexporter.action.SET_EXPORT_JOB";
|
||||
private PowerManager.WakeLock m_CPULock;
|
||||
|
||||
public static void startExport(Context pContext) {
|
||||
Intent lIntent = new Intent(pContext, ExportAllService.class);
|
||||
|
@ -32,8 +34,11 @@ public class ExportAllService extends IntentService {
|
|||
Log.i(TAG, "Intent sent!");
|
||||
}
|
||||
|
||||
public ExportAllService() {
|
||||
public ExportAllService()
|
||||
{
|
||||
super("AutoGPME-ExportService");
|
||||
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
|
||||
m_CPULock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ExportAllService");
|
||||
}
|
||||
|
||||
protected void onHandleIntent(Intent intent) {
|
||||
|
@ -62,21 +67,19 @@ public class ExportAllService extends IntentService {
|
|||
Log.i(TAG, lUri.toString());
|
||||
AlbumDataSource lAlbumDataSource = new AlbumDataSource(lPlayMusicManager);
|
||||
lAlbumDataSource.setOfflineOnly(true);
|
||||
m_CPULock.acquire();
|
||||
List<Album> lAlba = lAlbumDataSource.getAll();
|
||||
for (Album lAlbum : lAlba) {
|
||||
for (MusicTrack lTrack : lAlbum.getMusicTrackList()) {
|
||||
if (lTrack.isOfflineAvailable()) {
|
||||
String lPath = MusicPathBuilder.Build(lTrack, lExportStructure);
|
||||
try {
|
||||
if (!isAlreadyThere(lUri, lPath)) {
|
||||
if (lPlayMusicManager.exportMusicTrack(lTrack, lUri, lPath)) {
|
||||
Log.i(TAG, "Exported Music Track: " + getStringForTrack(lTrack));
|
||||
} else {
|
||||
Log.i(TAG, "Failed to export Music Track: " + getStringForTrack(lTrack));
|
||||
}
|
||||
if (lPlayMusicManager.exportMusicTrack(lTrack, lUri, lPath, PlayMusicExporterPreferences.getFileOverwritePreference())) {
|
||||
Log.i(TAG, "Exported Music Track: " + getStringForTrack(lTrack));
|
||||
} else {
|
||||
Log.i(TAG, lPath + " already exists.");
|
||||
Log.i(TAG, "Failed to export Music Track: " + getStringForTrack(lTrack));
|
||||
}
|
||||
|
||||
} catch (IllegalArgumentException e) {
|
||||
if (e.getMessage().contains("Invalid URI:")) {
|
||||
/*
|
||||
|
@ -87,22 +90,20 @@ public class ExportAllService extends IntentService {
|
|||
Log.i(TAG, "Automatic export failed, because the URI is invalid.");
|
||||
} else throw e;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if ( m_CPULock.isHeld())
|
||||
{
|
||||
m_CPULock.release();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isAlreadyThere(Uri pUri, String pPath) {
|
||||
DocumentFile lDocumentFile = DocumentFile.fromTreeUri(this, pUri);
|
||||
for (String lDisplayName: pPath.split("/")) {
|
||||
if (lDocumentFile.findFile(lDisplayName) != null) {
|
||||
lDocumentFile = lDocumentFile.findFile(lDisplayName);
|
||||
} else {
|
||||
Log.i(TAG, pPath + " does not exist yet.");
|
||||
return false;
|
||||
}
|
||||
if ( m_CPULock.isHeld())
|
||||
{
|
||||
m_CPULock.release();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private String getStringForTrack(MusicTrack pTrack) {
|
||||
|
|
|
@ -35,6 +35,7 @@ import re.jcg.playmusicexporter.R;
|
|||
import de.arcus.playmusiclib.PlayMusicManager;
|
||||
import de.arcus.playmusiclib.datasources.MusicTrackDataSource;
|
||||
import de.arcus.playmusiclib.items.MusicTrack;
|
||||
import re.jcg.playmusicexporter.settings.PlayMusicExporterPreferences;
|
||||
|
||||
/**
|
||||
* The export service
|
||||
|
@ -199,7 +200,7 @@ public class ExportService extends IntentService {
|
|||
updateNotification();
|
||||
|
||||
// Exports the song
|
||||
if(!playMusicManager.exportMusicTrack(mTrackCurrent, uri, path)) {
|
||||
if(!playMusicManager.exportMusicTrack(mTrackCurrent, uri, path, PlayMusicExporterPreferences.getFileOverwritePreference())) {
|
||||
// Export failed
|
||||
mTracksFailed ++;
|
||||
}
|
||||
|
|
|
@ -16,6 +16,8 @@ public class PlayMusicExporterPreferences {
|
|||
public static final boolean AUTO_EXPORT_ENABLED_DEFAULT = false;
|
||||
public static final String AUTO_EXPORT_USES_DIFFERENT_PATH = "preference_auto_export_use_different_path";
|
||||
public static final boolean AUTO_EXPORT_USES_DIFFERENT_PATH_DEFAULT = false;
|
||||
private static final String FORCE_EXPORT_OVERWRITE = "preference_overwrite_existing_files";
|
||||
private static final boolean FORCE_EXPORT_OVERWRITE_DEFAULT = false;
|
||||
public static final String AUTO_EXPORT_USES_DIFFERENT_STRUCTURE = "preference_auto_export_use_different_structure";
|
||||
public static final boolean AUTO_EXPORT_USES_DIFFERENT_STRUCTURE_DEFAULT = false;
|
||||
public static final String AUTO_EXPORT_FREQUENCY = "preference_auto_export_frequency";
|
||||
|
@ -63,6 +65,10 @@ public class PlayMusicExporterPreferences {
|
|||
}
|
||||
}
|
||||
|
||||
public static boolean getFileOverwritePreference() {
|
||||
return preferences.getBoolean(FORCE_EXPORT_OVERWRITE, FORCE_EXPORT_OVERWRITE_DEFAULT);
|
||||
}
|
||||
|
||||
public static boolean getAutoExportUsesDifferentPath() {
|
||||
return preferences.getBoolean(AUTO_EXPORT_USES_DIFFERENT_PATH, AUTO_EXPORT_USES_DIFFERENT_PATH_DEFAULT);
|
||||
}
|
||||
|
|
|
@ -101,4 +101,8 @@
|
|||
<string name="dialog_superuser_access_denied_title">Administrator-Zugriff verweigert</string>
|
||||
<string name="dialog_superuser_access_denied">Der Play Music Exporter benötigt Administrator Rechte, ohne diese Rechte kann die App nicht genutzt werden.</string>
|
||||
<string name="settings_auto_export_different_structure_dialog_title">Verzeichnisbaum</string>
|
||||
<string name="settings_export_overwrite_existing">Bestehende Dateien überschreiben</string>
|
||||
<string name="file_handling_category">Dateiverarbeitung</string>
|
||||
<string name="overwrite_summary">Überschreiben Sie die exportierte Datei immer, auch wenn sie bereits existiert.</string>
|
||||
<string name="overwrite_title">Bestehende Dateien überschreiben.</string>
|
||||
</resources>
|
|
@ -73,7 +73,7 @@
|
|||
<string name="settings_category_auto_export_path_subdir">Export path and subdirectory structure</string>
|
||||
<string name="settings_category_debug">Debug</string>
|
||||
<string name="settings_category_alba_export">Export location albums</string>
|
||||
<string name="settings_category_groups_export">Export location groups</string>
|
||||
<string name="settings_category_groups_export">Export location playlists</string>
|
||||
|
||||
|
||||
<string name="settings_version_number">Version Number</string>
|
||||
|
@ -101,7 +101,7 @@
|
|||
<string name="settings_export_structure_alba_dialog_title">Set your subdirectory structure</string>
|
||||
<string name="settings_export_subdirectory_structure_album_example">Example: Beatles/Help!/13. Yesterday.mp3</string>
|
||||
|
||||
<string name="settings_export_path_groups">Export path for groups</string>
|
||||
<string name="settings_export_path_groups">Export path for playlists</string>
|
||||
<string name="settings_export_structure_groups">Subdirectory structure for playlists</string>
|
||||
<string name="settings_export_structure_groups_dialog_title">Set your subdirectory structure</string>
|
||||
<string name="settings_export_subdirectory_structure_group_example">Example: Great Songs/4. Beatles - Yesterday.mp3</string>
|
||||
|
@ -116,6 +116,7 @@
|
|||
<string name="settings_export_id3_artwork_size_summary">If the artwork original size is larger than this setting the app will size down the artwork to this size.</string>
|
||||
|
||||
<string name="settings_export_path_custom">Custom path</string>
|
||||
<string name="settings_export_overwrite_existing">Overwrite existing files</string>
|
||||
|
||||
<string name="settings_open_old_homepage_title" translatable="false">David-Schulte.de</string>
|
||||
<string name="settings_open_old_homepage_url" translatable="false"><![CDATA[http://www.david-schulte.de/]]></string>
|
||||
|
@ -142,4 +143,7 @@
|
|||
<string name="settings_export_structure_groups_default_value" translatable="false">{group}/{group-no=$$.} {artist} - {title}.mp3</string>
|
||||
|
||||
<string name="debug_trigger_export_all_title">Trigger ExportAllService now</string>
|
||||
<string name="file_handling_category">File Handling</string>
|
||||
<string name="overwrite_summary">Always overwrite the exported file, even if it already exists.</string>
|
||||
<string name="overwrite_title">Overwrite Existing Files</string>
|
||||
</resources>
|
||||
|
|
|
@ -49,4 +49,10 @@
|
|||
android:summary="@string/settings_export_id3_artwork_size_summary"
|
||||
android:title="@string/settings_export_id3_artwork_size" />
|
||||
</PreferenceCategory>
|
||||
<PreferenceCategory android:title="@string/file_handling_category">
|
||||
<SwitchPreference
|
||||
android:key="preference_overwrite_existing_files"
|
||||
android:summary="@string/overwrite_summary"
|
||||
android:title="@string/overwrite_title" />
|
||||
</PreferenceCategory>
|
||||
</PreferenceScreen>
|
||||
|
|
|
@ -34,6 +34,7 @@ import android.os.Environment;
|
|||
import android.os.ParcelFileDescriptor;
|
||||
import android.support.v4.provider.DocumentFile;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import com.mpatric.mp3agic.ID3v1Genres;
|
||||
import com.mpatric.mp3agic.ID3v1Tag;
|
||||
|
@ -467,9 +468,10 @@ public class PlayMusicManager {
|
|||
* Exports a track to the sd card
|
||||
* @param musicTrack The music track you want to export
|
||||
* @param dest The destination path
|
||||
* @param forceOverwrite Forces overwrite of the destination file
|
||||
* @return Returns whether the export was successful
|
||||
*/
|
||||
public boolean exportMusicTrack(MusicTrack musicTrack, String dest) {
|
||||
public boolean exportMusicTrack(MusicTrack musicTrack, String dest, boolean forceOverwrite ) {
|
||||
// Creates the destination directory
|
||||
File directory = new File(dest).getParentFile();
|
||||
|
||||
|
@ -477,16 +479,17 @@ public class PlayMusicManager {
|
|||
// Filename
|
||||
String filename = new File(dest).getName();
|
||||
|
||||
return exportMusicTrack(musicTrack, Uri.fromFile(directory), filename);
|
||||
return exportMusicTrack(musicTrack, Uri.fromFile(directory), filename, forceOverwrite);
|
||||
}
|
||||
|
||||
/**
|
||||
* Exports a track to the sd card
|
||||
* @param musicTrack The music track you want to export
|
||||
* @param uri The document tree
|
||||
* @param forceOverwrite Forces overwrite of the destination file
|
||||
* @return Returns whether the export was successful
|
||||
*/
|
||||
public boolean exportMusicTrack(MusicTrack musicTrack, Uri uri, String path) {
|
||||
public boolean exportMusicTrack(MusicTrack musicTrack, Uri uri, String path, boolean forceOverwrite) {
|
||||
|
||||
// Check for null
|
||||
if (musicTrack == null) return false;
|
||||
|
@ -496,94 +499,109 @@ public class PlayMusicManager {
|
|||
// Could not find the source file
|
||||
if (srcFile == null) return false;
|
||||
|
||||
String fileTmp = getTempPath() + "tmp.mp3";
|
||||
if ( forceOverwrite || !isAlreadyThere(uri, path) )
|
||||
{
|
||||
|
||||
// Copy to temp path failed
|
||||
if (!SuperUserTools.fileCopy(srcFile, fileTmp))
|
||||
return false;
|
||||
String fileTmp = getTempPath() + "tmp.mp3";
|
||||
|
||||
// Encrypt the file
|
||||
if (musicTrack.isEncoded()) {
|
||||
String fileTmpCrypt = getTempPath() + "crypt.mp3";
|
||||
// Copy to temp path failed
|
||||
if (!SuperUserTools.fileCopy(srcFile, fileTmp))
|
||||
return false;
|
||||
|
||||
// Encrypts the file
|
||||
if (trackEncrypt(musicTrack, fileTmp, fileTmpCrypt)) {
|
||||
// Remove the old tmp file
|
||||
FileTools.fileDelete(fileTmp);
|
||||
// Encrypt the file
|
||||
if (musicTrack.isEncoded()) {
|
||||
String fileTmpCrypt = getTempPath() + "crypt.mp3";
|
||||
|
||||
// New tmp file
|
||||
fileTmp = fileTmpCrypt;
|
||||
} else {
|
||||
Logger.getInstance().logWarning("ExportMusicTrack", "Encrypting failed! Continue with decrypted file.");
|
||||
// Encrypts the file
|
||||
if (trackEncrypt(musicTrack, fileTmp, fileTmpCrypt)) {
|
||||
// Remove the old tmp file
|
||||
FileTools.fileDelete(fileTmp);
|
||||
|
||||
// New tmp file
|
||||
fileTmp = fileTmpCrypt;
|
||||
} else {
|
||||
Logger.getInstance().logWarning("ExportMusicTrack", "Encrypting failed! Continue with decrypted file.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
String dest;
|
||||
Uri copyUri = null;
|
||||
if (uri.toString().startsWith("file://")) {
|
||||
// Build the full path
|
||||
dest = uri.buildUpon().appendPath(path).build().getPath();
|
||||
String dest;
|
||||
Uri copyUri = null;
|
||||
if (uri.toString().startsWith("file://")) {
|
||||
// Build the full path
|
||||
dest = uri.buildUpon().appendPath(path).build().getPath();
|
||||
|
||||
String parentDirectory = new File(dest).getParent();
|
||||
FileTools.directoryCreate(parentDirectory);
|
||||
} else {
|
||||
// Complex uri (Lollipop)
|
||||
dest = getTempPath() + "final.mp3";
|
||||
String parentDirectory = new File(dest).getParent();
|
||||
FileTools.directoryCreate(parentDirectory);
|
||||
} else {
|
||||
// Complex uri (Lollipop)
|
||||
dest = getTempPath() + "final.mp3";
|
||||
|
||||
// The root
|
||||
DocumentFile document = DocumentFile.fromTreeUri(mContext, uri);
|
||||
// The root
|
||||
DocumentFile document = DocumentFile.fromTreeUri(mContext, uri);
|
||||
|
||||
// Creates the subdirectories
|
||||
String[] directories = path.split("\\/");
|
||||
for(int i=0; i<directories.length - 1; i++) {
|
||||
String directoryName = directories[i];
|
||||
boolean found = false;
|
||||
// Creates the subdirectories
|
||||
String[] directories = path.split("\\/");
|
||||
for(int i=0; i<directories.length - 1; i++) {
|
||||
String directoryName = directories[i];
|
||||
boolean found = false;
|
||||
|
||||
// Search all sub elements
|
||||
for (DocumentFile subDocument: document.listFiles()) {
|
||||
// Search all sub elements
|
||||
for (DocumentFile subDocument: document.listFiles()) {
|
||||
// Directory exists
|
||||
if (subDocument.isDirectory() && subDocument.getName().equalsIgnoreCase(directoryName)) {
|
||||
document = subDocument;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
// Create the directory
|
||||
document = document.createDirectory(directoryName);
|
||||
}
|
||||
}
|
||||
|
||||
// Gets the filename
|
||||
String filename = directories[directories.length - 1];
|
||||
|
||||
for (DocumentFile subDocument: document.listFiles()) {
|
||||
// Directory exists
|
||||
if (subDocument.isDirectory() && subDocument.getName().equals(directoryName)) {
|
||||
document = subDocument;
|
||||
found = true;
|
||||
if (subDocument.isFile() && subDocument.getName().equalsIgnoreCase(filename)) {
|
||||
// Delete the file
|
||||
if ( forceOverwrite ) {
|
||||
Logger.getInstance().logWarning("ExportMusicTrack", "(forceOverwrite) Deleting original file: " + filename);
|
||||
}
|
||||
subDocument.delete();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
// Create the directory
|
||||
document = document.createDirectory(directoryName);
|
||||
}
|
||||
// Create the mp3 file
|
||||
document = document.createFile("music/mp3", filename);
|
||||
|
||||
// Create the directories
|
||||
copyUri = document.getUri();
|
||||
}
|
||||
|
||||
// Gets the filename
|
||||
String filename = directories[directories.length - 1];
|
||||
|
||||
for (DocumentFile subDocument: document.listFiles()) {
|
||||
// Directory exists
|
||||
if (subDocument.isFile() && subDocument.getName().equals(filename)) {
|
||||
// Delete the file
|
||||
subDocument.delete();
|
||||
break;
|
||||
// We want to export the ID3 tags
|
||||
if (mID3Enable) {
|
||||
// Adds the meta data
|
||||
if (!trackWriteID3(musicTrack, fileTmp, dest)) {
|
||||
Logger.getInstance().logWarning("ExportMusicTrack", "ID3 writer failed! Continue without ID3 tags.");
|
||||
|
||||
// Failed, moving without meta data
|
||||
if (!FileTools.fileMove(fileTmp, dest)) {
|
||||
Logger.getInstance().logError("ExportMusicTrack", "Moving the raw file failed!");
|
||||
|
||||
// Could not copy the file
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create the mp3 file
|
||||
document = document.createFile("music/mp3", filename);
|
||||
|
||||
// Create the directories
|
||||
copyUri = document.getUri();
|
||||
}
|
||||
|
||||
|
||||
// We want to export the ID3 tags
|
||||
if (mID3Enable) {
|
||||
// Adds the meta data
|
||||
if (!trackWriteID3(musicTrack, fileTmp, dest)) {
|
||||
Logger.getInstance().logWarning("ExportMusicTrack", "ID3 writer failed! Continue without ID3 tags.");
|
||||
|
||||
// Failed, moving without meta data
|
||||
} else {
|
||||
// Moving the file
|
||||
if (!FileTools.fileMove(fileTmp, dest)) {
|
||||
Logger.getInstance().logError("ExportMusicTrack", "Moving the raw file failed!");
|
||||
|
||||
|
@ -591,59 +609,73 @@ public class PlayMusicManager {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Moving the file
|
||||
if (!FileTools.fileMove(fileTmp, dest)) {
|
||||
Logger.getInstance().logError("ExportMusicTrack", "Moving the raw file failed!");
|
||||
|
||||
// Could not copy the file
|
||||
// We need to copy the file to a uri
|
||||
if (copyUri != null) {
|
||||
// Lollipop only
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
try {
|
||||
// Gets the file descriptor
|
||||
ParcelFileDescriptor parcelFileDescriptor = mContext.getContentResolver().openFileDescriptor(copyUri, "w");
|
||||
|
||||
// Gets the output stream
|
||||
FileOutputStream fileOutputStream = new FileOutputStream(parcelFileDescriptor.getFileDescriptor());
|
||||
|
||||
// Gets the input stream
|
||||
FileInputStream fileInputStream = new FileInputStream(dest);
|
||||
|
||||
// Copy the stream
|
||||
FileTools.fileCopy(fileInputStream, fileOutputStream);
|
||||
|
||||
// Close all streams
|
||||
fileOutputStream.close();
|
||||
fileInputStream.close();
|
||||
parcelFileDescriptor.close();
|
||||
|
||||
} catch (FileNotFoundException e) {
|
||||
Logger.getInstance().logError("ExportMusicTrack", "File not found!");
|
||||
|
||||
// Could not copy the file
|
||||
return false;
|
||||
} catch (IOException e) {
|
||||
Logger.getInstance().logError("ExportMusicTrack", "Failed to write the document: " + e.toString());
|
||||
|
||||
// Could not copy the file
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Delete temp files
|
||||
cleanUp();
|
||||
|
||||
// Adds the file to the media system
|
||||
//new MediaScanner(mContext, dest);
|
||||
|
||||
} else {
|
||||
Logger.getInstance().logInfo("exportMusicTrack", path + " already exists, skipping." );
|
||||
}
|
||||
|
||||
// Done
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the destination file already exists
|
||||
* @param pUri the source file
|
||||
* @param pPath The destination
|
||||
* return true if the file already exists
|
||||
*/
|
||||
private boolean isAlreadyThere(Uri pUri, String pPath) {
|
||||
DocumentFile lDocumentFile = DocumentFile.fromTreeUri(mContext, pUri);
|
||||
for (String lDisplayName: pPath.split("/")) {
|
||||
if (lDocumentFile.findFile(lDisplayName) != null) {
|
||||
lDocumentFile = lDocumentFile.findFile(lDisplayName);
|
||||
} else {
|
||||
Logger.getInstance().logInfo("isAlreadyThere", pPath + " does not exist yet." );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// We need to copy the file to a uri
|
||||
if (copyUri != null) {
|
||||
// Lollipop only
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
try {
|
||||
// Gets the file descriptor
|
||||
ParcelFileDescriptor parcelFileDescriptor = mContext.getContentResolver().openFileDescriptor(copyUri, "w");
|
||||
|
||||
// Gets the output stream
|
||||
FileOutputStream fileOutputStream = new FileOutputStream(parcelFileDescriptor.getFileDescriptor());
|
||||
|
||||
// Gets the input stream
|
||||
FileInputStream fileInputStream = new FileInputStream(dest);
|
||||
|
||||
// Copy the stream
|
||||
FileTools.fileCopy(fileInputStream, fileOutputStream);
|
||||
|
||||
// Close all streams
|
||||
fileOutputStream.close();
|
||||
fileInputStream.close();
|
||||
parcelFileDescriptor.close();
|
||||
|
||||
} catch (FileNotFoundException e) {
|
||||
Logger.getInstance().logError("ExportMusicTrack", "File not found!");
|
||||
|
||||
// Could not copy the file
|
||||
return false;
|
||||
} catch (IOException e) {
|
||||
Logger.getInstance().logError("ExportMusicTrack", "Failed to write the document: " + e.toString());
|
||||
|
||||
// Could not copy the file
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Delete temp files
|
||||
cleanUp();
|
||||
|
||||
// Adds the file to the media system
|
||||
//new MediaScanner(mContext, dest);
|
||||
|
||||
// Done
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue