add download service with limited functionality

This commit is contained in:
dkanada 2021-05-04 21:03:09 +09:00
commit dd7722fd7f
7 changed files with 124 additions and 7 deletions

View file

@ -66,13 +66,9 @@
android:launchMode="singleInstance"
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
<service
android:name=".service.MusicService"
android:enabled="true" />
<service
android:name=".service.LoginService"
android:enabled="true" />
<service android:name=".service.DownloadService" />
<service android:name=".service.LoginService" />
<service android:name=".service.MusicService" />
<receiver android:name=".service.receivers.MediaButtonIntentReceiver">
<intent-filter>

View file

@ -3,6 +3,8 @@ package com.dkanada.gramophone.helper.menu;
import androidx.annotation.NonNull;
import androidx.fragment.app.FragmentActivity;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.view.MenuItem;
import android.view.View;
import android.widget.PopupMenu;
@ -15,6 +17,7 @@ import com.dkanada.gramophone.helper.MusicPlayerRemote;
import com.dkanada.gramophone.model.Album;
import com.dkanada.gramophone.model.Artist;
import com.dkanada.gramophone.model.Song;
import com.dkanada.gramophone.service.DownloadService;
import com.dkanada.gramophone.util.NavigationUtil;
public class SongMenuHelper {
@ -37,6 +40,9 @@ public class SongMenuHelper {
case R.id.action_details:
SongDetailDialog.create(song).show(activity.getSupportFragmentManager(), SongDetailDialog.TAG);
return true;
case R.id.action_download:
NavigationUtil.startDownload(activity, song);
return true;
case R.id.action_go_to_album:
NavigationUtil.startAlbum(activity, new Album(song));
return true;

View file

@ -0,0 +1,88 @@
package com.dkanada.gramophone.service;
import android.app.Service;
import android.content.Intent;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import com.dkanada.gramophone.App;
import com.dkanada.gramophone.BuildConfig;
import com.dkanada.gramophone.model.Song;
import com.dkanada.gramophone.util.MusicUtil;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
public class DownloadService extends Service {
public static final String PACKAGE_NAME = BuildConfig.APPLICATION_ID;
public static final String EXTRA_SONG = PACKAGE_NAME + ".extra.song";
private Executor executor;
private Handler handler;
@Override
public void onCreate() {
super.onCreate();
Looper looper = Looper.myLooper();
if (looper == null) {
looper = Looper.getMainLooper();
}
executor = Executors.newFixedThreadPool(4);
handler = new Handler(looper);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent == null) return super.onStartCommand(null, flags, startId);
Song song = intent.getParcelableExtra(EXTRA_SONG);
executor.execute(() -> {
try {
URL url = new URL(MusicUtil.getDownloadUri(song));
URLConnection connection = url.openConnection();
File root = new File(App.getInstance().getCacheDir(), "music");
String path = song.artistName + "/" + song.albumName + "/";
String name = song.discNumber + "." + song.trackNumber + " - " + song.title + "." + song.container;
File audio = new File(root, path + name);
audio.getParentFile().mkdirs();
audio.createNewFile();
InputStream input = connection.getInputStream();
OutputStream output = new FileOutputStream(audio);
connection.connect();
byte[] data = new byte[4096];
int count;
while ((count = input.read(data)) != -1) {
output.write(data, 0, count);
}
input.close();
output.close();
} catch (Exception e) {
e.printStackTrace();
}
});
return super.onStartCommand(intent, flags, startId);
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}

View file

@ -69,6 +69,19 @@ public class MusicUtil {
return builder.toString();
}
public static String getDownloadUri(Song song) {
StringBuilder builder = new StringBuilder(256);
builder.append(App.getApiClient().getApiUrl());
builder.append("/Items/");
builder.append(song.id);
builder.append("/Download");
builder.append("?ApiKey=").append(App.getApiClient().getAccessToken());
return builder.toString();
}
@NonNull
public static Intent createShareSongFileIntent(@NonNull final Song song, Context context) {
try {

View file

@ -22,6 +22,8 @@ import com.dkanada.gramophone.activities.details.AlbumDetailActivity;
import com.dkanada.gramophone.activities.details.ArtistDetailActivity;
import com.dkanada.gramophone.activities.details.GenreDetailActivity;
import com.dkanada.gramophone.activities.details.PlaylistDetailActivity;
import com.dkanada.gramophone.model.Song;
import com.dkanada.gramophone.service.DownloadService;
public class NavigationUtil {
public static void openUrl(@NonNull final Context context, String url) {
@ -99,4 +101,11 @@ public class NavigationUtil {
activity.startActivity(intent);
}
}
public static void startDownload(@NonNull Activity activity, Song song) {
Intent intent = new Intent(activity, DownloadService.class);
intent.putExtra(DownloadService.EXTRA_SONG, song);
activity.startService(intent);
}
}

View file

@ -29,4 +29,8 @@
android:id="@+id/action_details"
android:title="@string/action_details"
app:showAsAction="never" />
<item
android:id="@+id/action_download"
android:title="@string/action_download"
app:showAsAction="never" />
</menu>

View file

@ -18,6 +18,7 @@
<string name="action_add_to_favorites">Add to favorites</string>
<string name="action_remove_from_favorites">Remove from favorites</string>
<string name="action_search">Search</string>
<string name="action_download">Download</string>
<string name="action_play_next">Play next</string>
<string name="action_play">Play</string>
<string name="action_play_pause">Play/Pause</string>