diff --git a/README.md b/README.md
index 52420d24..ae7eb67d 100644
--- a/README.md
+++ b/README.md
@@ -23,17 +23,12 @@ This is a native music player for Android devices that connects to Jellyfin medi
* Playback history reporting
* Filter content by library
-# Requisites
-- A Jellfin server. See how to setup one [here](https://jellyfin.org/docs/general/quick-start/).
-- Android 4.4 or later
-
# Issues
Since this was a small project intended mainly for myself, there are some things I haven't resolved yet. I would appreciate pull requests to fix any of these issues!
* Artist sorting isn't available through the API
-* Playlists and favorites will not update automatically when changed ([#5](https://github.com/adrianvic/jamfish/issues/5))
-* App may crash on really low end devices due exceeding the maximum bitmap memory ([#4](https://github.com/adrianvic/jamfish/issues/4))
+* Playlists and favorites will not update automatically when changed
# Future Plans
diff --git a/app/build.gradle b/app/build.gradle
index 534ad6d3..30aa7bdf 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -10,12 +10,10 @@ android {
minSdk 19
targetSdk 33
- versionCode 2
- versionName '1.4.1'
+ versionCode 1
+ versionName '1.4.0'
- // for SDK < 19
multiDexEnabled true
-
vectorDrawables {
useSupportLibrary true
}
@@ -107,9 +105,8 @@ dependencies {
implementation 'com.android.support:multidex:1.0.3'
implementation 'com.mlegy.redscreenofdeath:red-screen-of-death:0.1.3'
- // old version of retrofit to work with api < 21
- implementation 'com.squareup.retrofit2:retrofit:2.6.4'
- implementation 'com.squareup.retrofit2:converter-gson:2.6.0'
+ implementation 'com.squareup.retrofit2:retrofit:2.9.0'
+ implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.4'
@@ -120,10 +117,4 @@ dependencies {
implementation 'com.github.bumptech.glide:annotations:4.12.0'
implementation 'com.github.bumptech.glide:glide:4.12.0'
implementation 'com.github.bumptech.glide:okhttp3-integration:4.12.0'
-
- // for supporting legacy android versions:
- implementation('com.squareup.okhttp3:okhttp:3.12.13')
-
- implementation "androidx.multidex:multidex:2.0.1"
- implementation 'org.conscrypt:conscrypt-android:2.5.2'
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index e5ab2f2f..2ad3febf 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -2,9 +2,7 @@
-
-
@@ -51,7 +49,6 @@
-
@@ -67,7 +64,7 @@
android:name="org.adrianvictor.geleia.views.shortcuts.AppShortcutLauncherActivity"
android:launchMode="singleInstance"
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
-
+
@@ -139,12 +136,6 @@
android:resource="@xml/provider_paths" />
-
-
diff --git a/app/src/main/java/org/adrianvictor/geleia/App.java b/app/src/main/java/org/adrianvictor/geleia/App.java
index 231cee4c..3145450b 100644
--- a/app/src/main/java/org/adrianvictor/geleia/App.java
+++ b/app/src/main/java/org/adrianvictor/geleia/App.java
@@ -6,9 +6,6 @@ import android.content.Context;
import android.os.Build;
import android.provider.Settings;
-import androidx.annotation.NonNull;
-import androidx.appcompat.app.AppCompatDelegate;
-import androidx.multidex.MultiDexApplication;
import androidx.room.Room;
import org.adrianvictor.geleia.database.JellyDatabase;
@@ -17,7 +14,6 @@ import org.adrianvictor.geleia.util.PreferenceUtil;
import org.adrianvictor.geleia.views.shortcuts.DynamicShortcutManager;
import com.melegy.redscreenofdeath.RedScreenOfDeath;
-import org.conscrypt.Conscrypt;
import org.jellyfin.apiclient.interaction.AndroidDevice;
import org.jellyfin.apiclient.interaction.ApiClient;
import org.jellyfin.apiclient.interaction.VolleyHttpClient;
@@ -26,16 +22,7 @@ import org.jellyfin.apiclient.interaction.http.IAsyncHttpClient;
import org.jellyfin.apiclient.logging.AndroidLogger;
import org.jellyfin.apiclient.logging.ILogger;
-import com.bumptech.glide.Glide;
-import com.bumptech.glide.Registry;
-import com.bumptech.glide.integration.okhttp3.OkHttpUrlLoader;
-import com.bumptech.glide.load.model.GlideUrl;
-import java.io.InputStream;
-import okhttp3.OkHttpClient;
-
-import java.security.Security;
-
-public class App extends MultiDexApplication {
+public class App extends Application {
private static App app;
private static JellyDatabase database;
@@ -43,14 +30,8 @@ public class App extends MultiDexApplication {
@Override
public void onCreate() {
- // Initializing stuff for older Android APIs compatibility
- Security.insertProviderAt(Conscrypt.newProvider(), 1); // To have SSL 1.2 on API < 19
- AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); // To load vectors on API < 19
-
super.onCreate();
- initializeGlide(this);
-
if (BuildConfig.DEBUG) {
RedScreenOfDeath.init(this);
}
@@ -59,7 +40,7 @@ public class App extends MultiDexApplication {
database = createDatabase(this);
apiClient = createApiClient(this);
- if (database.userDao().getUsers().isEmpty()) {
+ if (database.userDao().getUsers().size() == 0) {
PreferenceUtil.getInstance(this).setServer(null);
PreferenceUtil.getInstance(this).setUser(null);
}
@@ -95,7 +76,6 @@ public class App extends MultiDexApplication {
IDevice device = new AndroidDevice(deviceId, deviceName);
EventListener eventListener = new EventListener();
-
return new ApiClient(httpClient, logger, server, appName, appVersion, device, eventListener);
}
@@ -110,15 +90,4 @@ public class App extends MultiDexApplication {
public static App getInstance() {
return app;
}
-
- private void initializeGlide(@NonNull Context context) {
- // This OkHttpClient is now created with Conscrypt as the SSL provider.
- OkHttpClient client = new OkHttpClient.Builder().build();
-
- // Manually create and register Glide's OkHttp component.
- OkHttpUrlLoader.Factory factory = new OkHttpUrlLoader.Factory(client);
-
- // Ensure Glide is initialized and then register the component.
- Glide.get(context).getRegistry().replace(GlideUrl.class, InputStream.class, factory);
- }
}
diff --git a/app/src/main/java/org/adrianvictor/geleia/activities/AboutActivity.java b/app/src/main/java/org/adrianvictor/geleia/activities/AboutActivity.java
index 56ffa5cf..50601fac 100644
--- a/app/src/main/java/org/adrianvictor/geleia/activities/AboutActivity.java
+++ b/app/src/main/java/org/adrianvictor/geleia/activities/AboutActivity.java
@@ -7,7 +7,6 @@ import android.view.View;
import androidx.annotation.NonNull;
-import org.adrianvictor.geleia.service.notifications.ErrorNotification;
import org.adrianvictor.geleia.util.NavigationUtil;
import org.adrianvictor.geleia.util.PreferenceUtil;
import org.adrianvictor.geleia.databinding.ActivityAboutBinding;
@@ -103,7 +102,7 @@ public class AboutActivity extends AbsBaseActivity implements View.OnClickListen
try {
return context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionName;
} catch (PackageManager.NameNotFoundException e) {
- ErrorNotification.show(context, e.getMessage());
+ e.printStackTrace();
}
return "Unknown";
diff --git a/app/src/main/java/org/adrianvictor/geleia/activities/DirectoryPickerActivity.java b/app/src/main/java/org/adrianvictor/geleia/activities/DirectoryPickerActivity.java
deleted file mode 100644
index 4452596d..00000000
--- a/app/src/main/java/org/adrianvictor/geleia/activities/DirectoryPickerActivity.java
+++ /dev/null
@@ -1,127 +0,0 @@
-package org.adrianvictor.geleia.activities;
-
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.Environment;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ArrayAdapter;
-import android.widget.Button;
-import android.widget.LinearLayout;
-import android.widget.ListView;
-import android.widget.TextView;
-
-import androidx.appcompat.app.AppCompatActivity;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Arrays;
-
-public class DirectoryPickerActivity extends AppCompatActivity {
-
- public static final String EXTRA_RESULT_PATH = "result_path";
-
- private File rootDir;
- private File currentDir;
-
- private ArrayAdapter adapter;
- private TextView pathView;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- rootDir = Environment.getExternalStorageDirectory();
- currentDir = rootDir;
-
- LinearLayout layout = new LinearLayout(this);
- layout.setOrientation(LinearLayout.VERTICAL);
-
- pathView = new TextView(this);
- pathView.setPadding(24, 24, 24, 24);
-
- ListView listView = new ListView(this);
-
- Button selectButton = new Button(this);
- selectButton.setText("Select this folder");
-
- layout.addView(pathView);
- layout.addView(listView, new LinearLayout.LayoutParams(
- ViewGroup.LayoutParams.MATCH_PARENT, 0, 1f));
- layout.addView(selectButton);
-
- setContentView(layout);
-
- adapter = new ArrayAdapter(this,
- android.R.layout.simple_list_item_1, new ArrayList<>()) {
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- TextView tv = (TextView) super.getView(position, convertView, parent);
- File f = getItem(position);
-
- File parentFile = currentDir.getParentFile();
-
- if (parentFile != null && parentFile.equals(f)) {
- tv.setText("..");
- } else {
- tv.setText(f.getName());
- }
-
- return tv;
- }
- };
-
- listView.setAdapter(adapter);
-
- listView.setOnItemClickListener((p, v, pos, id) -> {
- File dir = adapter.getItem(pos);
- if (dir != null) openDir(dir);
- });
-
- selectButton.setOnClickListener(v -> {
- Intent result = new Intent();
- result.putExtra(EXTRA_RESULT_PATH, currentDir.getAbsolutePath());
- setResult(RESULT_OK, result);
- finish();
- });
-
- openDir(rootDir);
- }
-
- private void openDir(File dir) {
- if (!dir.exists() || !dir.canRead()) return;
-
- File[] dirs = dir.listFiles(f ->
- f.isDirectory() && f.canRead()
- );
-
- if (dirs == null) return;
-
- adapter.clear();
-
- File parent = dir.getParentFile();
- if (parent != null && parent.getAbsolutePath().startsWith(rootDir.getAbsolutePath())) {
- adapter.add(parent);
- }
-
- Arrays.sort(dirs);
-
- for (File f : dirs) {
- adapter.add(f);
- }
-
- currentDir = dir;
- pathView.setText(dir.getAbsolutePath());
- }
-
- @Override
- public void onBackPressed() {
- File parent = currentDir.getParentFile();
- if (parent != null &&
- parent.getAbsolutePath().startsWith(rootDir.getAbsolutePath())) {
- openDir(parent);
- } else {
- super.onBackPressed();
- }
- }
-}
diff --git a/app/src/main/java/org/adrianvictor/geleia/activities/MainActivity.java b/app/src/main/java/org/adrianvictor/geleia/activities/MainActivity.java
index 41a46462..0f1df8a7 100644
--- a/app/src/main/java/org/adrianvictor/geleia/activities/MainActivity.java
+++ b/app/src/main/java/org/adrianvictor/geleia/activities/MainActivity.java
@@ -13,14 +13,11 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.drawerlayout.widget.DrawerLayout;
-import androidx.lifecycle.Lifecycle;
import com.afollestad.materialcab.attached.AttachedCab;
import com.afollestad.materialcab.attached.AttachedCabKt;
import org.adrianvictor.geleia.activities.base.AbsMusicContentActivity;
-import org.adrianvictor.geleia.fragments.OfflineFragment;
import org.adrianvictor.geleia.interfaces.CabHolder;
-import org.adrianvictor.geleia.util.NavigationUtil;
import org.adrianvictor.geleia.util.PreferenceUtil;
import org.adrianvictor.geleia.util.ThemeUtil;
import org.adrianvictor.geleia.databinding.ActivityMainContentBinding;
@@ -45,7 +42,6 @@ public class MainActivity extends AbsMusicContentActivity implements CabHolder {
private ActivityMainContentBinding contentBinding;
private NavigationDrawerHeaderBinding navigationBinding;
private boolean onLogout;
- private boolean pendingShowOffline = false;
@Nullable
private AttachedCab cab;
@@ -101,15 +97,6 @@ public class MainActivity extends AbsMusicContentActivity implements CabHolder {
});
}
- @Override
- public void onStateOffline() {
- if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.RESUMED)) {
- NavigationUtil.startUnreachable(this);
- } else {
- pendingShowOffline = true;
- }
- }
-
@Override
public void onPause() {
super.onPause();
@@ -121,16 +108,6 @@ public class MainActivity extends AbsMusicContentActivity implements CabHolder {
}
}
- @Override
- protected void onResume() {
- super.onResume();
-
- if (pendingShowOffline) {
- setCurrentFragment(OfflineFragment.newInstance());
- pendingShowOffline = false;
- }
- }
-
private void setCurrentFragment(Fragment fragment) {
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, fragment, null).commit();
}
diff --git a/app/src/main/java/org/adrianvictor/geleia/activities/SearchActivity.java b/app/src/main/java/org/adrianvictor/geleia/activities/SearchActivity.java
index b483b51d..2958e587 100644
--- a/app/src/main/java/org/adrianvictor/geleia/activities/SearchActivity.java
+++ b/app/src/main/java/org/adrianvictor/geleia/activities/SearchActivity.java
@@ -93,9 +93,6 @@ public class SearchActivity extends AbsMusicContentActivity implements SearchVie
public void onStateOnline() {
}
- @Override
- public void onStateOffline() {}
-
private void setUpToolBar() {
binding.toolbar.setBackgroundColor(PreferenceUtil.getInstance(this).getPrimaryColor());
setSupportActionBar(binding.toolbar);
diff --git a/app/src/main/java/org/adrianvictor/geleia/activities/SettingsActivity.java b/app/src/main/java/org/adrianvictor/geleia/activities/SettingsActivity.java
index ab860b08..b1406474 100644
--- a/app/src/main/java/org/adrianvictor/geleia/activities/SettingsActivity.java
+++ b/app/src/main/java/org/adrianvictor/geleia/activities/SettingsActivity.java
@@ -51,7 +51,6 @@ public class SettingsActivity extends AbsBaseActivity {
public static class SettingsFragment extends PreferenceFragmentCompat implements SharedPreferences.OnSharedPreferenceChangeListener {
private ActivityResultLauncher dirPickerLauncher;
- private ActivityResultLauncher legacyDirPickerLauncher;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
@@ -72,25 +71,6 @@ public class SettingsActivity extends AbsBaseActivity {
}
}
});
-
- legacyDirPickerLauncher = registerForActivityResult(
- new ActivityResultContracts.StartActivityForResult(),
- result -> {
- if (result.getResultCode() == RESULT_OK && result.getData() != null) {
- String path = result.getData().getStringExtra(
- DirectoryPickerActivity.EXTRA_RESULT_PATH
- );
-
- if (path != null) {
- SharedPreferences.Editor editor =
- PreferenceManager.getDefaultSharedPreferences(requireContext()).edit();
- editor.putString(PreferenceUtil.LOCATION_DOWNLOAD, path);
- editor.apply();
- invalidateSettings();
- }
- }
- }
- );
}
@Override
@@ -181,13 +161,8 @@ public class SettingsActivity extends AbsBaseActivity {
}
private void openDirectoryPicker() {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
- Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
- dirPickerLauncher.launch(intent);
- } else {
- Intent intent = new Intent(requireContext(), DirectoryPickerActivity.class);
- legacyDirPickerLauncher.launch(intent);
- }
+ Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
+ dirPickerLauncher.launch(intent);
}
@Override
diff --git a/app/src/main/java/org/adrianvictor/geleia/activities/SplashActivity.java b/app/src/main/java/org/adrianvictor/geleia/activities/SplashActivity.java
index d3460d22..88a3b8af 100644
--- a/app/src/main/java/org/adrianvictor/geleia/activities/SplashActivity.java
+++ b/app/src/main/java/org/adrianvictor/geleia/activities/SplashActivity.java
@@ -1,13 +1,8 @@
package org.adrianvictor.geleia.activities;
-import android.content.BroadcastReceiver;
-import android.content.Context;
import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.Build;
import android.os.Bundle;
-
-import androidx.annotation.NonNull;
+import android.os.Handler;
import org.adrianvictor.geleia.App;
import org.adrianvictor.geleia.R;
@@ -20,41 +15,10 @@ import org.adrianvictor.geleia.util.PreferenceUtil;
import java.util.List;
public class SplashActivity extends AbsBaseActivity {
-
- private final BroadcastReceiver receiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, @NonNull Intent intent) {
- if (intent.getAction() == null) {
- return;
- }
-
- switch (intent.getAction()) {
- case LoginService.STATE_ONLINE:
- NavigationUtil.startMain(context);
- finish();
- break;
- case LoginService.STATE_OFFLINE:
- NavigationUtil.startUnreachable(context);
- finish();
- break;
- }
- }
- };
-
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- final IntentFilter filter = new IntentFilter();
- filter.addAction(LoginService.STATE_ONLINE);
- filter.addAction(LoginService.STATE_OFFLINE);
-
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- registerReceiver(receiver, filter, Context.RECEIVER_NOT_EXPORTED);
- } else {
- registerReceiver(receiver, filter);
- }
-
setContentView(R.layout.activity_splash);
}
@@ -71,20 +35,13 @@ public class SplashActivity extends AbsBaseActivity {
User user = App.getDatabase().userDao().getUser(PreferenceUtil.getInstance(this).getUser());
List available = App.getDatabase().userDao().getUsers();
- if (user == null && !available.isEmpty()) {
+ if (user == null && available.size() != 0) {
NavigationUtil.startSelect(this);
- finish();
} else if (user == null) {
NavigationUtil.startLogin(this);
- finish();
} else {
startService(new Intent(this, LoginService.class));
+ new Handler().postDelayed(() -> NavigationUtil.startMain(this), 1000);
}
}
-
- @Override
- protected void onDestroy() {
- unregisterReceiver(receiver);
- super.onDestroy();
- }
}
diff --git a/app/src/main/java/org/adrianvictor/geleia/activities/UnreachableActivity.java b/app/src/main/java/org/adrianvictor/geleia/activities/UnreachableActivity.java
deleted file mode 100644
index 94afba90..00000000
--- a/app/src/main/java/org/adrianvictor/geleia/activities/UnreachableActivity.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package org.adrianvictor.geleia.activities;
-
-import android.os.Bundle;
-import android.view.View;
-
-import org.adrianvictor.geleia.R;
-import org.adrianvictor.geleia.activities.base.AbsThemeActivity;
-import org.adrianvictor.geleia.util.NavigationUtil;
-
-public class UnreachableActivity extends AbsThemeActivity {
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- setContentView(R.layout.activity_unreachable);
- }
-
- public void onSelectClick(View view) {
- NavigationUtil.startSelect(this);
- }
-}
diff --git a/app/src/main/java/org/adrianvictor/geleia/activities/base/AbsBaseActivity.java b/app/src/main/java/org/adrianvictor/geleia/activities/base/AbsBaseActivity.java
index d64b6bc2..406f6237 100644
--- a/app/src/main/java/org/adrianvictor/geleia/activities/base/AbsBaseActivity.java
+++ b/app/src/main/java/org/adrianvictor/geleia/activities/base/AbsBaseActivity.java
@@ -59,7 +59,7 @@ public abstract class AbsBaseActivity extends AbsThemeActivity {
.setPositiveButton(R.string.disable, (dialog, id) -> requestBatteryOptimization());
new Handler().postDelayed(builder::show, 2000);
- } else if (!permissions.isEmpty() && ActivityCompat.shouldShowRequestPermissionRationale(this, permissions.get(0))) {
+ } else if (permissions.size() != 0 && ActivityCompat.shouldShowRequestPermissionRationale(this, permissions.get(0))) {
builder.setMessage(getPermissionMessage())
.setTitle(R.string.permissions_denied)
.setPositiveButton(R.string.action_grant, (dialog, id) -> requestPermissions());
@@ -127,11 +127,8 @@ public abstract class AbsBaseActivity extends AbsThemeActivity {
private boolean checkBatteryOptimization() {
String packageName = getPackageName();
PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- return pm.isIgnoringBatteryOptimizations(packageName);
- } else {
- return true;
- }
+
+ return pm.isIgnoringBatteryOptimizations(packageName);
}
@RequiresApi(api = Build.VERSION_CODES.M)
@@ -141,11 +138,9 @@ public abstract class AbsBaseActivity extends AbsThemeActivity {
@RequiresApi(api = Build.VERSION_CODES.M)
private boolean checkPermissions() {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- for (String permission : permissions) {
- if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
- return false;
- }
+ for (String permission : permissions) {
+ if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
+ return false;
}
}
diff --git a/app/src/main/java/org/adrianvictor/geleia/activities/base/AbsMusicContentActivity.java b/app/src/main/java/org/adrianvictor/geleia/activities/base/AbsMusicContentActivity.java
index 90843227..904b928f 100644
--- a/app/src/main/java/org/adrianvictor/geleia/activities/base/AbsMusicContentActivity.java
+++ b/app/src/main/java/org/adrianvictor/geleia/activities/base/AbsMusicContentActivity.java
@@ -1,19 +1,14 @@
package org.adrianvictor.geleia.activities.base;
-import static org.adrianvictor.geleia.adapter.CustomFragmentStatePagerAdapter.TAG;
-
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.os.Build;
import android.os.Bundle;
-import android.util.Log;
import androidx.annotation.NonNull;
import org.adrianvictor.geleia.App;
-import org.adrianvictor.geleia.fragments.OfflineFragment;
import org.adrianvictor.geleia.interfaces.StateListener;
import org.adrianvictor.geleia.service.LoginService;
import org.adrianvictor.geleia.util.NavigationUtil;
@@ -29,7 +24,7 @@ public abstract class AbsMusicContentActivity extends AbsMusicPanelActivity impl
onStateOnline();
break;
case LoginService.STATE_OFFLINE:
- onStateOffline();
+ NavigationUtil.startLogin(context);
break;
}
}
@@ -44,11 +39,7 @@ public abstract class AbsMusicContentActivity extends AbsMusicPanelActivity impl
filter.addAction(LoginService.STATE_ONLINE);
filter.addAction(LoginService.STATE_OFFLINE);
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- registerReceiver(receiver, filter, Context.RECEIVER_NOT_EXPORTED);
- } else {
- registerReceiver(receiver, filter);
- }
+ registerReceiver(receiver, filter);
if (App.getApiClient() == null) {
startService(new Intent(this, LoginService.class));
@@ -60,14 +51,24 @@ public abstract class AbsMusicContentActivity extends AbsMusicPanelActivity impl
@Override
protected void onResume() {
super.onResume();
+
+ if (App.getApiClient() == null) {
+ startService(new Intent(this, LoginService.class));
+ }
}
@Override
protected void onDestroy() {
unregisterReceiver(receiver);
+
super.onDestroy();
}
@Override
- public void onStatePolling() {}
+ public void onStatePolling() {
+ }
+
+ @Override
+ public void onStateOffline() {
+ }
}
diff --git a/app/src/main/java/org/adrianvictor/geleia/activities/details/AlbumDetailActivity.java b/app/src/main/java/org/adrianvictor/geleia/activities/details/AlbumDetailActivity.java
index ad920baa..9c7ca01b 100644
--- a/app/src/main/java/org/adrianvictor/geleia/activities/details/AlbumDetailActivity.java
+++ b/app/src/main/java/org/adrianvictor/geleia/activities/details/AlbumDetailActivity.java
@@ -74,11 +74,6 @@ public class AlbumDetailActivity extends AbsMusicContentActivity implements Pale
});
}
- @Override
- public void onStateOffline() {
-
- }
-
@Override
public void onOffsetChanged (AppBarLayout appBarLayout, int verticalOffset) {
float headerAlpha = Math.max(0, Math.min(1, 1 + (2 * (float) verticalOffset / headerViewHeight)));
@@ -236,6 +231,6 @@ public class AlbumDetailActivity extends AbsMusicContentActivity implements Pale
binding.durationText.setText(MusicUtil.getReadableDurationString(MusicUtil.getTotalDuration(this, album.songs)));
binding.albumYearText.setText(MusicUtil.getYearString(album.year));
- if (!album.songs.isEmpty()) adapter.swapDataSet(album.songs);
+ if (album.songs.size() != 0) adapter.swapDataSet(album.songs);
}
}
diff --git a/app/src/main/java/org/adrianvictor/geleia/activities/details/ArtistDetailActivity.java b/app/src/main/java/org/adrianvictor/geleia/activities/details/ArtistDetailActivity.java
index 2f98a935..d7cde428 100644
--- a/app/src/main/java/org/adrianvictor/geleia/activities/details/ArtistDetailActivity.java
+++ b/app/src/main/java/org/adrianvictor/geleia/activities/details/ArtistDetailActivity.java
@@ -87,11 +87,6 @@ public class ArtistDetailActivity extends AbsMusicContentActivity implements Pal
});
}
- @Override
- public void onStateOffline() {
-
- }
-
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
float headerAlpha = Math.max(0, Math.min(1, 1 + (2 * (float) verticalOffset / headerViewHeight)));
@@ -263,7 +258,7 @@ public class ArtistDetailActivity extends AbsMusicContentActivity implements Pal
binding.albumCountText.setText(MusicUtil.getAlbumCountString(this, artist.albums.size()));
binding.durationText.setText(MusicUtil.getReadableDurationString(MusicUtil.getTotalDuration(this, artist.songs)));
- if (!artist.songs.isEmpty()) songAdapter.swapDataSet(artist.songs);
- if (!artist.albums.isEmpty()) albumAdapter.swapDataSet(artist.albums);
+ if (artist.songs.size() != 0) songAdapter.swapDataSet(artist.songs);
+ if (artist.albums.size() != 0) albumAdapter.swapDataSet(artist.albums);
}
}
diff --git a/app/src/main/java/org/adrianvictor/geleia/activities/details/GenreDetailActivity.java b/app/src/main/java/org/adrianvictor/geleia/activities/details/GenreDetailActivity.java
index aacc7db8..9449daa5 100644
--- a/app/src/main/java/org/adrianvictor/geleia/activities/details/GenreDetailActivity.java
+++ b/app/src/main/java/org/adrianvictor/geleia/activities/details/GenreDetailActivity.java
@@ -59,11 +59,6 @@ public class GenreDetailActivity extends AbsMusicContentActivity implements CabH
});
}
- @Override
- public void onStateOffline() {
-
- }
-
@Override
protected View createContentView() {
binding = ActivityGenreDetailBinding.inflate(getLayoutInflater());
diff --git a/app/src/main/java/org/adrianvictor/geleia/activities/details/PlaylistDetailActivity.java b/app/src/main/java/org/adrianvictor/geleia/activities/details/PlaylistDetailActivity.java
index bb3d1d57..f111dc14 100644
--- a/app/src/main/java/org/adrianvictor/geleia/activities/details/PlaylistDetailActivity.java
+++ b/app/src/main/java/org/adrianvictor/geleia/activities/details/PlaylistDetailActivity.java
@@ -71,11 +71,6 @@ public class PlaylistDetailActivity extends AbsMusicContentActivity implements C
});
}
- @Override
- public void onStateOffline() {
-
- }
-
@Override
protected View createContentView() {
binding = ActivityPlaylistDetailBinding.inflate(getLayoutInflater());
diff --git a/app/src/main/java/org/adrianvictor/geleia/adapter/CustomFragmentStatePagerAdapter.java b/app/src/main/java/org/adrianvictor/geleia/adapter/CustomFragmentStatePagerAdapter.java
index f6c1c4f5..d19a6ffe 100644
--- a/app/src/main/java/org/adrianvictor/geleia/adapter/CustomFragmentStatePagerAdapter.java
+++ b/app/src/main/java/org/adrianvictor/geleia/adapter/CustomFragmentStatePagerAdapter.java
@@ -180,7 +180,7 @@ public abstract class CustomFragmentStatePagerAdapter extends PagerAdapter {
@Override
public Parcelable saveState() {
Bundle state = null;
- if (!mSavedState.isEmpty()) {
+ if (mSavedState.size() > 0) {
state = new Bundle();
Fragment.SavedState[] fss = new Fragment.SavedState[mSavedState.size()];
mSavedState.toArray(fss);
diff --git a/app/src/main/java/org/adrianvictor/geleia/adapter/DownloadsAdapter.java b/app/src/main/java/org/adrianvictor/geleia/adapter/DownloadsAdapter.java
deleted file mode 100644
index 25cf4c79..00000000
--- a/app/src/main/java/org/adrianvictor/geleia/adapter/DownloadsAdapter.java
+++ /dev/null
@@ -1,69 +0,0 @@
-package org.adrianvictor.geleia.adapter;
-
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import androidx.annotation.NonNull;
-import androidx.recyclerview.widget.RecyclerView;
-
-import org.adrianvictor.geleia.R;
-import org.adrianvictor.geleia.model.Song;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class DownloadsAdapter extends RecyclerView.Adapter {
- private final List mSongs;
- private final int mLayoutId;
-
- public DownloadsAdapter(int layoutId) {
- mLayoutId = layoutId;
- this.mSongs = new ArrayList<>();
- }
-
- public void swapDataSet(List newSongs) {
- mSongs.clear();
- if (newSongs != null) {
- mSongs.addAll(newSongs);
- }
- notifyDataSetChanged();
- }
-
- @NonNull
- @Override
- public DownloadsAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
- View view = LayoutInflater.from(parent.getContext()).inflate(mLayoutId, parent, false);
- return new ViewHolder(view);
- }
-
- @Override
- public void onBindViewHolder(@NonNull DownloadsAdapter.ViewHolder holder, int position) {
- final Song song = mSongs.get(position);
-
- holder.title.setText(song.title);
- holder.artist.setText(song.artistName);
-
- // TODO: Load album cover into holder.cover using Glide
- }
-
- @Override
- public int getItemCount() {
- return mSongs.size();
- }
-
- public static class ViewHolder extends RecyclerView.ViewHolder {
- public final TextView title;
- public final TextView artist;
- public final ImageView cover;
-
- public ViewHolder(View itemView) {
- super(itemView);
- title = itemView.findViewById(R.id.title);
- artist = itemView.findViewById(R.id.text);
- cover = itemView.findViewById(R.id.image);
- }
- }
-}
diff --git a/app/src/main/java/org/adrianvictor/geleia/adapter/MusicLibraryPagerAdapter.java b/app/src/main/java/org/adrianvictor/geleia/adapter/MusicLibraryPagerAdapter.java
index 23c1162d..2979ee5c 100644
--- a/app/src/main/java/org/adrianvictor/geleia/adapter/MusicLibraryPagerAdapter.java
+++ b/app/src/main/java/org/adrianvictor/geleia/adapter/MusicLibraryPagerAdapter.java
@@ -10,9 +10,6 @@ import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
-import org.adrianvictor.geleia.activities.UnreachableActivity;
-import org.adrianvictor.geleia.fragments.OfflineFragment;
-import org.adrianvictor.geleia.fragments.library.DownloadsFragment;
import org.adrianvictor.geleia.fragments.library.FavoritesFragment;
import org.adrianvictor.geleia.model.Category;
import org.adrianvictor.geleia.fragments.library.AlbumsFragment;
@@ -160,8 +157,7 @@ public class MusicLibraryPagerAdapter extends FragmentPagerAdapter {
ARTISTS(ArtistsFragment.class),
GENRES(GenresFragment.class),
PLAYLISTS(PlaylistsFragment.class),
- FAVORITES(FavoritesFragment.class),
- DOWNLOADS(DownloadsFragment.class);
+ FAVORITES(FavoritesFragment.class);
private final Class extends Fragment> mFragmentClass;
diff --git a/app/src/main/java/org/adrianvictor/geleia/database/CacheDao.java b/app/src/main/java/org/adrianvictor/geleia/database/CacheDao.java
index 54ff3733..8df0ded5 100644
--- a/app/src/main/java/org/adrianvictor/geleia/database/CacheDao.java
+++ b/app/src/main/java/org/adrianvictor/geleia/database/CacheDao.java
@@ -14,9 +14,6 @@ public interface CacheDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
void insertCache(Cache cache);
- @Query("SELECT * FROM cache")
- List getAll();
-
@Query("SELECT * FROM songs LEFT JOIN cache USING(id) WHERE songs.id IN (:ids)")
List getSongs(List ids);
diff --git a/app/src/main/java/org/adrianvictor/geleia/dialogs/SongShareDialog.java b/app/src/main/java/org/adrianvictor/geleia/dialogs/SongShareDialog.java
index d2becf6a..101c9377 100644
--- a/app/src/main/java/org/adrianvictor/geleia/dialogs/SongShareDialog.java
+++ b/app/src/main/java/org/adrianvictor/geleia/dialogs/SongShareDialog.java
@@ -31,7 +31,7 @@ public class SongShareDialog extends DialogFragment {
final String currentlyListening = getString(R.string.currently_listening_to_x_by_x, song.title, song.artistName);
return new MaterialDialog.Builder(requireActivity())
.title(R.string.what_do_you_want_to_share)
- .items(getString(R.string.the_audio_file), "“" + currentlyListening + "”")
+ .items(getString(R.string.the_audio_file), "\u201C" + currentlyListening + "\u201D")
.itemsCallback((materialDialog, view, i, charSequence) -> {
switch (i) {
case 0:
diff --git a/app/src/main/java/org/adrianvictor/geleia/fragments/OfflineFragment.java b/app/src/main/java/org/adrianvictor/geleia/fragments/OfflineFragment.java
deleted file mode 100644
index ed1d40a0..00000000
--- a/app/src/main/java/org/adrianvictor/geleia/fragments/OfflineFragment.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package org.adrianvictor.geleia.fragments;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.fragment.app.Fragment;
-
-import org.adrianvictor.geleia.R;
-
-public class OfflineFragment extends Fragment {
- public static OfflineFragment newInstance() {
- return new OfflineFragment();
- }
-
- @Nullable
- @Override
- public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
- return inflater.inflate(R.layout.fragment_offline, container, false);
- }
-}
diff --git a/app/src/main/java/org/adrianvictor/geleia/fragments/library/DownloadsFragment.java b/app/src/main/java/org/adrianvictor/geleia/fragments/library/DownloadsFragment.java
deleted file mode 100644
index f6f259f5..00000000
--- a/app/src/main/java/org/adrianvictor/geleia/fragments/library/DownloadsFragment.java
+++ /dev/null
@@ -1,125 +0,0 @@
-package org.adrianvictor.geleia.fragments.library;
-
-import androidx.annotation.NonNull;
-import androidx.recyclerview.widget.GridLayoutManager;
-
-import org.adrianvictor.geleia.App;
-import org.adrianvictor.geleia.adapter.DownloadsAdapter;
-
-import org.adrianvictor.geleia.database.Cache;
-import org.adrianvictor.geleia.model.Song;
-import org.adrianvictor.geleia.model.SortMethod;
-import org.adrianvictor.geleia.model.SortOrder;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class DownloadsFragment extends AbsLibraryPagerRecyclerViewCustomGridSizeFragment {
- @NonNull
- @Override
- protected DownloadsAdapter createAdapter() {
- return new DownloadsAdapter(getItemLayoutRes());
- }
-
- @NonNull
- @Override
- protected GridLayoutManager createLayoutManager() {
- return new GridLayoutManager(getActivity(), getGridSize());
- }
-
- @NonNull
- @Override
- protected Void createQuery() {
- return null;
- }
-
- @Override
- protected void loadItems(int index) {
- new Thread(() -> {
- List cachedEntries = App.getDatabase().cacheDao().getAll();
-
- List songIds = new ArrayList<>();
-
- for (Cache entry : cachedEntries) {
- songIds.add(entry.id);
- }
-
- final List downloadedSongs = App.getDatabase().cacheDao().getSongs(songIds);
-
- if (getActivity() != null) {
- getActivity().runOnUiThread(() -> {
- getAdapter().swapDataSet(downloadedSongs);
- });
- }
- }).start();
- }
- @Override
- protected int loadGridSize() {
- return 1;
- }
-
- @Override
- protected void saveGridSize(int gridColumns) {
-
- }
-
- @Override
- protected int loadGridSizeLand() {
- return 1;
- }
-
- @Override
- protected void saveGridSizeLand(int gridColumns) {
-
- }
-
- @Override
- protected void saveUsePalette(boolean usePalette) {
-
- }
-
- @Override
- protected boolean loadUsePalette() {
- return false;
- }
-
- @Override
- protected void setUsePalette(boolean usePalette) {
-
- }
-
- @Override
- protected void setGridSize(int gridSize) {
-
- }
-
- @Override
- protected SortMethod loadSortMethod() {
- return SortMethod.ADDED;
- }
-
- @Override
- protected void saveSortMethod(SortMethod sortMethod) {
-
- }
-
- @Override
- protected void setSortMethod(SortMethod sortMethod) {
-
- }
-
- @Override
- protected SortOrder loadSortOrder() {
- return SortOrder.ASCENDING;
- }
-
- @Override
- protected void saveSortOrder(SortOrder sortOrder) {
-
- }
-
- @Override
- protected void setSortOrder(SortOrder sortOrder) {
-
- }
-}
diff --git a/app/src/main/java/org/adrianvictor/geleia/helper/MusicPlayerRemote.java b/app/src/main/java/org/adrianvictor/geleia/helper/MusicPlayerRemote.java
index f409842c..4f658348 100644
--- a/app/src/main/java/org/adrianvictor/geleia/helper/MusicPlayerRemote.java
+++ b/app/src/main/java/org/adrianvictor/geleia/helper/MusicPlayerRemote.java
@@ -273,7 +273,7 @@ public class MusicPlayerRemote {
public static boolean playNext(Song song) {
if (musicService != null && musicService.queueManager != null) {
- if (!getPlayingQueue().isEmpty()) {
+ if (getPlayingQueue().size() > 0) {
musicService.queueManager.addSong(getPosition() + 1, song);
} else {
List queue = new ArrayList<>();
@@ -290,7 +290,7 @@ public class MusicPlayerRemote {
public static boolean playNext(@NonNull List songs) {
if (musicService != null && musicService.queueManager != null) {
- if (!getPlayingQueue().isEmpty()) {
+ if (getPlayingQueue().size() > 0) {
musicService.queueManager.addSongs(getPosition() + 1, songs);
} else {
openQueue(songs, 0, false);
@@ -306,7 +306,7 @@ public class MusicPlayerRemote {
public static boolean enqueue(Song song) {
if (musicService != null && musicService.queueManager != null) {
- if (!getPlayingQueue().isEmpty()) {
+ if (getPlayingQueue().size() > 0) {
musicService.queueManager.addSong(song);
} else {
List queue = new ArrayList<>();
@@ -323,7 +323,7 @@ public class MusicPlayerRemote {
public static boolean enqueue(@NonNull List songs) {
if (musicService != null && musicService.queueManager != null) {
- if (!getPlayingQueue().isEmpty()) {
+ if (getPlayingQueue().size() > 0) {
musicService.queueManager.addSongs(songs);
} else {
openQueue(songs, 0, false);
diff --git a/app/src/main/java/org/adrianvictor/geleia/model/Album.java b/app/src/main/java/org/adrianvictor/geleia/model/Album.java
index 81e4e481..36ff5554 100644
--- a/app/src/main/java/org/adrianvictor/geleia/model/Album.java
+++ b/app/src/main/java/org/adrianvictor/geleia/model/Album.java
@@ -29,10 +29,10 @@ public class Album implements Parcelable {
this.title = itemDto.getName();
this.year = itemDto.getProductionYear() != null ? itemDto.getProductionYear() : 0;
- if (!itemDto.getAlbumArtists().isEmpty()) {
+ if (itemDto.getAlbumArtists().size() != 0) {
this.artistId = itemDto.getAlbumArtists().get(0).getId();
this.artistName = itemDto.getAlbumArtists().get(0).getName();
- } else if (!itemDto.getArtistItems().isEmpty()) {
+ } else if (itemDto.getArtistItems().size() != 0) {
this.artistId = itemDto.getArtistItems().get(0).getId();
this.artistName = itemDto.getArtistItems().get(0).getName();
}
diff --git a/app/src/main/java/org/adrianvictor/geleia/model/Category.java b/app/src/main/java/org/adrianvictor/geleia/model/Category.java
index 3c897e81..91e54717 100644
--- a/app/src/main/java/org/adrianvictor/geleia/model/Category.java
+++ b/app/src/main/java/org/adrianvictor/geleia/model/Category.java
@@ -10,8 +10,7 @@ public enum Category {
ARTISTS(R.string.artists),
GENRES(R.string.genres),
PLAYLISTS(R.string.playlists),
- FAVORITES(R.string.favorites),
- DOWNLOADS(R.string.downloads);
+ FAVORITES(R.string.favorites);
@StringRes
public final int title;
diff --git a/app/src/main/java/org/adrianvictor/geleia/model/Song.java b/app/src/main/java/org/adrianvictor/geleia/model/Song.java
index b9218cb3..277a5942 100644
--- a/app/src/main/java/org/adrianvictor/geleia/model/Song.java
+++ b/app/src/main/java/org/adrianvictor/geleia/model/Song.java
@@ -67,10 +67,10 @@ public class Song implements Parcelable {
this.albumId = itemDto.getAlbumId();
this.albumName = itemDto.getAlbum();
- if (!itemDto.getArtistItems().isEmpty()) {
+ if (itemDto.getArtistItems().size() != 0) {
this.artistId = itemDto.getArtistItems().get(0).getId();
this.artistName = itemDto.getArtistItems().get(0).getName();
- } else if (!itemDto.getAlbumArtists().isEmpty()) {
+ } else if (itemDto.getAlbumArtists().size() != 0) {
this.artistId = itemDto.getAlbumArtists().get(0).getId();
this.artistName = itemDto.getAlbumArtists().get(0).getName();
}
@@ -93,7 +93,7 @@ public class Song implements Parcelable {
this.supportsTranscoding = source.getSupportsTranscoding();
- if (source.getMediaStreams() != null && !source.getMediaStreams().isEmpty()) {
+ if (source.getMediaStreams() != null && source.getMediaStreams().size() != 0) {
MediaStream stream = source.getMediaStreams().get(0);
this.codec = stream.getCodec();
diff --git a/app/src/main/java/org/adrianvictor/geleia/service/DownloadService.java b/app/src/main/java/org/adrianvictor/geleia/service/DownloadService.java
index 7cb72766..b3a61b5f 100644
--- a/app/src/main/java/org/adrianvictor/geleia/service/DownloadService.java
+++ b/app/src/main/java/org/adrianvictor/geleia/service/DownloadService.java
@@ -4,8 +4,6 @@ import android.app.Service;
import android.content.Intent;
import android.net.Uri;
import android.os.IBinder;
-import android.util.Log;
-
import androidx.documentfile.provider.DocumentFile;
import org.adrianvictor.geleia.App;
@@ -13,7 +11,6 @@ import org.adrianvictor.geleia.BuildConfig;
import org.adrianvictor.geleia.database.Cache;
import org.adrianvictor.geleia.model.Song;
import org.adrianvictor.geleia.service.notifications.DownloadNotification;
-import org.adrianvictor.geleia.service.notifications.ErrorNotification;
import org.adrianvictor.geleia.util.MusicUtil;
import org.adrianvictor.geleia.util.PreferenceUtil;
@@ -26,8 +23,8 @@ import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+@SuppressWarnings("ResultOfMethodCallIgnored")
public class DownloadService extends Service {
- public static final String TAG = DownloadService.class.getSimpleName();
public static final String PACKAGE_NAME = BuildConfig.APPLICATION_ID;
public static final String ACTION_START = PACKAGE_NAME + ".action.start";
public static final String ACTION_CANCEL = PACKAGE_NAME + ".action.cancel";
@@ -36,8 +33,6 @@ public class DownloadService extends Service {
private ExecutorService executor;
private DownloadNotification notification;
- private static final Object lock = new Object();
-
@Override
public void onCreate() {
super.onCreate();
@@ -60,7 +55,6 @@ public class DownloadService extends Service {
break;
case DownloadService.ACTION_START:
List songs = intent.getParcelableArrayListExtra(EXTRA_SONGS);
- assert songs != null;
for (Song song : songs) {
download(song);
notification.start(song);
@@ -84,24 +78,19 @@ public class DownloadService extends Service {
String location = PreferenceUtil.getInstance(App.getInstance()).getLocationDownload();
DocumentFile root;
- if (location.startsWith("content://")) {
- root = DocumentFile.fromTreeUri(this, Uri.parse(location));
- } else {
+ if (location.equals(getApplicationContext().getCacheDir().toString())) {
root = DocumentFile.fromFile(new File(location));
+ } else {
+ root = DocumentFile.fromTreeUri(this, Uri.parse(location));
}
- DocumentFile artist;
- DocumentFile album;
-
- synchronized (lock) {
- artist = root.findFile(MusicUtil.ascii(song.artistName));
- if (artist == null) {
- artist = root.createDirectory(MusicUtil.ascii(song.artistName));
- }
- album = artist.findFile(MusicUtil.ascii(song.albumName));
- if (album == null) {
- album = artist.createDirectory(MusicUtil.ascii(song.albumName));
- }
+ DocumentFile artist = root.findFile(MusicUtil.ascii(song.artistName));
+ if (artist == null) {
+ artist = root.createDirectory(MusicUtil.ascii(song.artistName));
+ }
+ DocumentFile album = artist.findFile(MusicUtil.ascii(song.albumName));
+ if (album == null) {
+ album = artist.createDirectory(MusicUtil.ascii(song.albumName));
}
String fileName = song.discNumber + "." + song.trackNumber + " - " + MusicUtil.ascii(song.title) + "." + song.container;
@@ -127,8 +116,7 @@ public class DownloadService extends Service {
App.getDatabase().cacheDao().insertCache(new Cache(song));
notification.stop(song);
} catch (Exception e) {
- Log.e(TAG, "Failed to download song: " + song.title, e);
- ErrorNotification.show(this, e.getMessage());
+ e.printStackTrace();
}
});
}
diff --git a/app/src/main/java/org/adrianvictor/geleia/service/LoginService.java b/app/src/main/java/org/adrianvictor/geleia/service/LoginService.java
index 55db8664..82f7a2a7 100644
--- a/app/src/main/java/org/adrianvictor/geleia/service/LoginService.java
+++ b/app/src/main/java/org/adrianvictor/geleia/service/LoginService.java
@@ -46,19 +46,9 @@ public class LoginService extends Service {
if (user == null) {
Toast.makeText(this, context.getResources().getString(R.string.error_unexpected), Toast.LENGTH_SHORT).show();
- sendBroadcast(new Intent(STATE_OFFLINE));
return;
}
- if (App.getApiClient() == null) {
- try {
- App.createApiClient(context);
- } catch (Exception e) {
- sendBroadcast(new Intent(STATE_OFFLINE));
- return;
- }
- }
-
App.getApiClient().ChangeServerLocation(user.server);
App.getApiClient().SetAuthenticationInfo(user.token, user.id);
App.getApiClient().GetSystemInfoAsync(new Response() {
diff --git a/app/src/main/java/org/adrianvictor/geleia/service/notifications/DownloadNotification.java b/app/src/main/java/org/adrianvictor/geleia/service/notifications/DownloadNotification.java
index 014eb570..fe6c0efa 100644
--- a/app/src/main/java/org/adrianvictor/geleia/service/notifications/DownloadNotification.java
+++ b/app/src/main/java/org/adrianvictor/geleia/service/notifications/DownloadNotification.java
@@ -1,134 +1,114 @@
package org.adrianvictor.geleia.service.notifications;
-import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
-import android.widget.RemoteViews;
+import androidx.annotation.RequiresApi;
import androidx.core.app.NotificationCompat;
import org.adrianvictor.geleia.R;
+import org.adrianvictor.geleia.activities.MainActivity;
import org.adrianvictor.geleia.model.Song;
import org.adrianvictor.geleia.service.DownloadService;
-import java.util.Collections;
-import java.util.LinkedList;
+import java.util.ArrayList;
import java.util.List;
+import java.util.stream.Collectors;
+
+import static android.content.Context.NOTIFICATION_SERVICE;
public class DownloadNotification {
- private static final String CHANNEL_ID = "download_channel";
- private final int ID = 2;
+ private static final String CHANNEL_ID = DownloadNotification.class.getSimpleName();
+ private static final int NOTIFICATION_ID = 2;
+
private final Context context;
private final NotificationManager notificationManager;
- private final List queue = Collections.synchronizedList(new LinkedList<>());
- private long totalSize;
- private long downloadedSize;
- private int lastPercentage = -1;
+ private final List songs;
+
+ private int current;
+ private int maximum;
public DownloadNotification(Context context) {
+ this.notificationManager = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
this.context = context;
- this.notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
- createNotificationChannel();
+
+ this.songs = new ArrayList<>();
}
- private void createNotificationChannel() {
+ public synchronized void start(Song song) {
+ this.songs.add(song);
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- NotificationChannel channel = new NotificationChannel(
- CHANNEL_ID,
- context.getString(R.string.download_channel_name),
- NotificationManager.IMPORTANCE_LOW
- );
- notificationManager.createNotificationChannel(channel);
+ createNotificationChannel();
}
}
- public void start(Song song) {
- queue.add(song);
- if (queue.size() == 1) { // This is the first song of a new batch
- totalSize = 0;
- downloadedSize = 0;
- lastPercentage = -1;
- notificationManager.notify(ID, getNotification());
- } else if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
- // For KitKat, update for every new song to show correct count.
- notificationManager.notify(ID, getNotification());
+ public synchronized void update(int current, int maximum) {
+ this.current += current;
+ this.maximum += maximum;
+
+ Intent action = new Intent(context, MainActivity.class).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ PendingIntent clickIntent = PendingIntent.getActivity(context, 0, action, PendingIntent.FLAG_IMMUTABLE);
+
+ Intent cancel = new Intent(context, DownloadService.class).setAction(DownloadService.ACTION_CANCEL);
+ PendingIntent pendingCancel = PendingIntent.getService(context, 0, cancel, PendingIntent.FLAG_IMMUTABLE);
+
+ NotificationCompat.InboxStyle style = new NotificationCompat.InboxStyle();
+ for (Song item : songs.stream().limit(5).collect(Collectors.toList())) {
+ style.addLine(item.title);
}
- }
-
- public void update(long downloaded, long total) {
- if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
- return; // No progress updates for KitKat
- }
-
- synchronized (this) {
- totalSize += total;
- downloadedSize += downloaded;
-
- int percentage = 0;
- if (totalSize > 0) {
- percentage = (int) ((downloadedSize * 100) / totalSize);
- }
-
- if (percentage > lastPercentage) {
- lastPercentage = percentage;
- notificationManager.notify(ID, getNotification());
- }
- }
- }
-
- public void stop(Song song) {
- queue.remove(song);
- if (queue.isEmpty()) {
- notificationManager.cancel(ID);
- } else {
- // Update notification to show new queue size.
- // On KitKat, this is the only update after a download finishes.
- notificationManager.notify(ID, getNotification());
- }
- }
-
- public void cancelAll() {
- queue.clear();
- notificationManager.cancel(ID);
- }
-
- private Notification getNotification() {
- Intent intent = new Intent(context, DownloadService.class);
- intent.setAction(DownloadService.ACTION_CANCEL);
-
- int flags = 0;
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- flags |= PendingIntent.FLAG_IMMUTABLE;
- }
- PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, flags);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_ID)
- .setSmallIcon(R.drawable.ic_notification)
- .setContentTitle(context.getString(R.string.downloading_songs))
- .setOngoing(true)
- .addAction(android.R.drawable.ic_menu_close_clear_cancel, context.getString(android.R.string.cancel), pendingIntent);
+ .setSmallIcon(R.drawable.ic_notification)
+ .setContentIntent(clickIntent)
+ .setContentTitle(String.format(context.getString(R.string.downloading_x_songs), songs.size()))
+ .setProgress(this.maximum, this.current, false)
+ .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
+ .addAction(R.drawable.ic_close_white_24dp, context.getString(R.string.action_cancel), pendingCancel)
+ .setStyle(style)
+ .setShowWhen(false);
- String contentText = context.getResources().getQuantityString(R.plurals.downloading_s_songs, queue.size(), queue.size());
+ notificationManager.notify(NOTIFICATION_ID, builder.build());
+ }
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
- RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.notification_download);
- remoteViews.setTextViewText(R.id.notification_download_title, contentText);
- int progress = lastPercentage > 0 ? lastPercentage : 0;
- remoteViews.setProgressBar(R.id.notification_download_progress, 100, progress, totalSize == 0 && downloadedSize == 0);
- builder.setCustomContentView(remoteViews);
- } else if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) {
- int progress = lastPercentage > 0 ? lastPercentage : 0;
- builder.setProgress(100, progress, totalSize == 0 && downloadedSize == 0);
- builder.setContentText(contentText);
- } else { // KitKat
- builder.setContentText(contentText);
+ public synchronized void stop(Song song) {
+ if (song != null) {
+ songs.remove(song);
+ } else {
+ songs.clear();
}
- return builder.build();
+ if (songs.size() != 0) {
+ return;
+ }
+
+ current = 0;
+ maximum = 0;
+
+ notificationManager.cancel(NOTIFICATION_ID);
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ notificationManager.deleteNotificationChannel(CHANNEL_ID);
+ }
+ }
+
+ @RequiresApi(Build.VERSION_CODES.O)
+ private void createNotificationChannel() {
+ NotificationChannel notificationChannel = notificationManager.getNotificationChannel(CHANNEL_ID);
+
+ if (notificationChannel == null) {
+ notificationChannel = new NotificationChannel(CHANNEL_ID, context.getString(R.string.action_download), NotificationManager.IMPORTANCE_LOW);
+
+ notificationChannel.setDescription(context.getString(R.string.playing_notification_description));
+ notificationChannel.enableLights(false);
+ notificationChannel.enableVibration(false);
+
+ notificationManager.createNotificationChannel(notificationChannel);
+ }
}
}
diff --git a/app/src/main/java/org/adrianvictor/geleia/service/notifications/ErrorNotification.java b/app/src/main/java/org/adrianvictor/geleia/service/notifications/ErrorNotification.java
deleted file mode 100644
index 793a9db7..00000000
--- a/app/src/main/java/org/adrianvictor/geleia/service/notifications/ErrorNotification.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package org.adrianvictor.geleia.service.notifications;
-
-import static android.content.Context.NOTIFICATION_SERVICE;
-
-import android.app.NotificationChannel;
-import android.app.NotificationManager;
-import android.content.Context;
-import android.os.Build;
-
-import androidx.core.app.NotificationCompat;
-
-import org.adrianvictor.geleia.R;
-
-public class ErrorNotification {
- private static final String CHANNEL_ID = ErrorNotification.class.getSimpleName();
- private static final int NOTIFICATION_ID = 3;
-
- private ErrorNotification() {}
-
- public static void show(Context context, String error) {
- NotificationManager notificationManager = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
- createNotificationChannel(notificationManager);
-
- NotificationCompat.BigTextStyle style = new NotificationCompat.BigTextStyle();
- style.setBigContentTitle("Error:").bigText(error);
-
- NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_ID)
- .setSmallIcon(R.drawable.ic_bug_report_white_24dp)
- .setContentTitle(context.getString(R.string.error_notification_title))
- .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
- .setStyle(style)
- .setContentText("Expand the notification for details.");
- }
-
- public static void createNotificationChannel(NotificationManager notificationManager) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- NotificationChannel channel = notificationManager.getNotificationChannel(CHANNEL_ID);
-
- if (channel == null) {
- channel = new NotificationChannel(CHANNEL_ID, "Errors", NotificationManager.IMPORTANCE_LOW);
- channel.setDescription("Displays all sorts of errors.");
- channel.enableLights(false);
- channel.enableVibration(true);
-
- notificationManager.createNotificationChannel(channel);
- }
- }
- }
-}
diff --git a/app/src/main/java/org/adrianvictor/geleia/service/playback/LocalPlayer.java b/app/src/main/java/org/adrianvictor/geleia/service/playback/LocalPlayer.java
index 2832d553..0a63184d 100644
--- a/app/src/main/java/org/adrianvictor/geleia/service/playback/LocalPlayer.java
+++ b/app/src/main/java/org/adrianvictor/geleia/service/playback/LocalPlayer.java
@@ -2,7 +2,6 @@ package org.adrianvictor.geleia.service.playback;
import android.content.Context;
import android.net.Uri;
-import android.os.Build;
import android.util.Log;
import android.widget.Toast;
@@ -142,17 +141,11 @@ public class LocalPlayer implements Playback {
private List createMediaItems(List queue) {
return queue.stream().map(song -> {
- String fileUri = MusicUtil.getFileUri(song);
- Uri uri;
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && fileUri.startsWith("content://")) {
- uri = Uri.parse(fileUri);
- } else {
- File audio = new File(fileUri);
- uri = Uri.fromFile(audio);
+ File audio = new File(MusicUtil.getFileUri(song));
+ Uri uri = Uri.fromFile(audio);
- if (!audio.exists()) {
- uri = Uri.parse(MusicUtil.getTranscodeUri(song));
- }
+ if (!audio.exists()) {
+ uri = Uri.parse(MusicUtil.getTranscodeUri(song));
}
List containers = PreferenceUtil.getInstance(context).getDirectPlayCodecs().stream()
diff --git a/app/src/main/java/org/adrianvictor/geleia/util/ImageUtil.java b/app/src/main/java/org/adrianvictor/geleia/util/ImageUtil.java
index de326d91..1388f345 100644
--- a/app/src/main/java/org/adrianvictor/geleia/util/ImageUtil.java
+++ b/app/src/main/java/org/adrianvictor/geleia/util/ImageUtil.java
@@ -14,7 +14,6 @@ import androidx.annotation.ColorInt;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import androidx.appcompat.content.res.AppCompatResources;
import androidx.core.graphics.drawable.DrawableCompat;
import androidx.core.content.res.ResourcesCompat;
@@ -92,22 +91,18 @@ public class ImageUtil {
}
public static Drawable getTintedVectorDrawable(@NonNull Context context, @DrawableRes int resId, @ColorInt int color) {
- final Drawable drawable = AppCompatResources.getDrawable(context, resId);
+ Drawable drawable = getVectorDrawable(context.getResources(), resId, context.getTheme());
- if (drawable != null) {
- Drawable wrappedDrawable = DrawableCompat.wrap(drawable).mutate();
+ DrawableCompat.setTintMode(drawable, PorterDuff.Mode.SRC_IN);
+ DrawableCompat.setTint(drawable, color);
- DrawableCompat.setTintMode(wrappedDrawable, PorterDuff.Mode.SRC_IN);
- DrawableCompat.setTint(wrappedDrawable, color);
- return wrappedDrawable;
- }
- return null;
+ return drawable;
}
-
public static Drawable getVectorDrawable(@NonNull Context context, @DrawableRes int resId) {
- return AppCompatResources.getDrawable(context, resId);
+ return getVectorDrawable(context.getResources(), resId, context.getTheme());
}
+
public static Drawable resolveDrawable(@NonNull Context context, @AttrRes int drawableAttr) {
TypedArray a = context.obtainStyledAttributes(new int[]{drawableAttr});
Drawable drawable = a.getDrawable(0);
diff --git a/app/src/main/java/org/adrianvictor/geleia/util/MusicUtil.java b/app/src/main/java/org/adrianvictor/geleia/util/MusicUtil.java
index 8d62cbbf..8831fe38 100644
--- a/app/src/main/java/org/adrianvictor/geleia/util/MusicUtil.java
+++ b/app/src/main/java/org/adrianvictor/geleia/util/MusicUtil.java
@@ -3,7 +3,6 @@ package org.adrianvictor.geleia.util;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
-import android.os.Build;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;
@@ -19,7 +18,6 @@ import org.adrianvictor.geleia.model.Codec;
import org.adrianvictor.geleia.model.Genre;
import org.adrianvictor.geleia.model.Song;
-import org.adrianvictor.geleia.service.notifications.ErrorNotification;
import org.jellyfin.apiclient.interaction.ApiClient;
import org.jellyfin.apiclient.interaction.Response;
import org.jellyfin.apiclient.model.dto.UserItemDataDto;
@@ -51,7 +49,7 @@ public class MusicUtil {
List codecs = preferenceUtil.getDirectPlayCodecs();
Stream values = codecs.stream().map(codec -> codec.value);
- if (!codecs.isEmpty()) {
+ if (codecs.size() != 0) {
builder.append("&Container=").append(values.collect(Collectors.joining(",")));
}
@@ -83,8 +81,7 @@ public class MusicUtil {
public static String getFileUri(Song song) {
String location = PreferenceUtil.getInstance(App.getInstance()).getLocationDownload();
File root = new File(location, "music");
-
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !location.equals(App.getInstance().getCacheDir().toString())) {
+ if (!location.equals(App.getInstance().getCacheDir().toString())) {
Uri uri = Uri.parse(location);
return new File(uri.getPath()).getAbsolutePath();
}
@@ -105,7 +102,7 @@ public class MusicUtil {
try {
return new Intent();
} catch (IllegalArgumentException e) {
- ErrorNotification.show(context, e.getMessage());
+ e.printStackTrace();
Toast.makeText(context, R.string.error_share_file, Toast.LENGTH_SHORT).show();
return new Intent();
}
@@ -113,7 +110,7 @@ public class MusicUtil {
@NonNull
public static String getArtistInfoString(@NonNull final Context context, @NonNull final Artist artist) {
- return !artist.genres.isEmpty() ? artist.genres.get(0).name : "";
+ return artist.genres.size() != 0 ? artist.genres.get(0).name : "";
}
@NonNull
diff --git a/app/src/main/java/org/adrianvictor/geleia/util/NavigationUtil.java b/app/src/main/java/org/adrianvictor/geleia/util/NavigationUtil.java
index 30460c35..924c47ba 100644
--- a/app/src/main/java/org/adrianvictor/geleia/util/NavigationUtil.java
+++ b/app/src/main/java/org/adrianvictor/geleia/util/NavigationUtil.java
@@ -12,7 +12,6 @@ import androidx.core.util.Pair;
import org.adrianvictor.geleia.activities.LoginActivity;
import org.adrianvictor.geleia.activities.MainActivity;
import org.adrianvictor.geleia.activities.SelectActivity;
-import org.adrianvictor.geleia.activities.UnreachableActivity;
import org.adrianvictor.geleia.model.Album;
import org.adrianvictor.geleia.model.Artist;
import org.adrianvictor.geleia.model.Genre;
@@ -62,13 +61,6 @@ public class NavigationUtil {
context.startActivity(intent);
}
- public static void startUnreachable(Context context) {
- final Intent intent = new Intent(context, UnreachableActivity.class);
-
- intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
- context.startActivity(intent);
- }
-
public static void startSelect(Context context) {
final Intent intent = new Intent(context, SelectActivity.class);
diff --git a/app/src/main/java/org/adrianvictor/geleia/util/PlaylistUtil.java b/app/src/main/java/org/adrianvictor/geleia/util/PlaylistUtil.java
index 731724ea..9144b16a 100644
--- a/app/src/main/java/org/adrianvictor/geleia/util/PlaylistUtil.java
+++ b/app/src/main/java/org/adrianvictor/geleia/util/PlaylistUtil.java
@@ -48,7 +48,7 @@ public class PlaylistUtil {
PlaylistCreationRequest request = new PlaylistCreationRequest();
request.setUserId(App.getApiClient().getCurrentUserId());
request.setName(name);
- if (!ids.isEmpty()) request.setItemIdList(ids);
+ if (ids.size() != 0) request.setItemIdList(ids);
App.getApiClient().CreatePlaylist(request, new Response<>());
}
diff --git a/app/src/main/java/org/adrianvictor/geleia/util/PreferenceUtil.java b/app/src/main/java/org/adrianvictor/geleia/util/PreferenceUtil.java
index 71ff53d5..1becdcb9 100644
--- a/app/src/main/java/org/adrianvictor/geleia/util/PreferenceUtil.java
+++ b/app/src/main/java/org/adrianvictor/geleia/util/PreferenceUtil.java
@@ -448,6 +448,7 @@ public final class PreferenceUtil {
}).collect(Collectors.toList());
}
+ @SuppressWarnings("SimplifyStreamApiCallChains")
public void setCategories(List categories) {
List values = categories.stream().map(category -> {
return category.select ? category.toString() : category.toString().toLowerCase();
diff --git a/app/src/main/java/org/adrianvictor/geleia/views/IconImageView.java b/app/src/main/java/org/adrianvictor/geleia/views/IconImageView.java
index 6af3adc6..557797cf 100644
--- a/app/src/main/java/org/adrianvictor/geleia/views/IconImageView.java
+++ b/app/src/main/java/org/adrianvictor/geleia/views/IconImageView.java
@@ -10,27 +10,23 @@ import org.adrianvictor.geleia.util.ThemeUtil;
import org.adrianvictor.geleia.R;
public class IconImageView extends AppCompatImageView {
-
public IconImageView(Context context) {
super(context);
+ init(context);
}
public IconImageView(Context context, AttributeSet attrs) {
super(context, attrs);
+ init(context);
}
public IconImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
+ init(context);
}
- @Override
- protected void onAttachedToWindow() {
- super.onAttachedToWindow();
- init();
- }
-
- private void init() {
- if (getContext() == null) return;
- setColorFilter(ThemeUtil.getColorResource(getContext(), R.attr.iconColor), PorterDuff.Mode.SRC_IN);
+ private void init(Context context) {
+ if (context == null) return;
+ setColorFilter(ThemeUtil.getColorResource(context, R.attr.iconColor), PorterDuff.Mode.SRC_IN);
}
}
diff --git a/app/src/main/java/org/adrianvictor/geleia/views/shortcuts/DynamicShortcutManager.java b/app/src/main/java/org/adrianvictor/geleia/views/shortcuts/DynamicShortcutManager.java
index c45ab175..ee889cd8 100644
--- a/app/src/main/java/org/adrianvictor/geleia/views/shortcuts/DynamicShortcutManager.java
+++ b/app/src/main/java/org/adrianvictor/geleia/views/shortcuts/DynamicShortcutManager.java
@@ -36,7 +36,7 @@ public class DynamicShortcutManager {
}
public void initDynamicShortcuts() {
- if (shortcutManager.getDynamicShortcuts().isEmpty()) {
+ if (shortcutManager.getDynamicShortcuts().size() == 0) {
shortcutManager.setDynamicShortcuts(getDefaultShortcuts());
}
}
diff --git a/app/src/main/res/drawable/ic_launcher_nodpi.xml b/app/src/main/res/drawable/ic_launcher_nodpi.xml
index a8b409b1..1361edfa 100644
--- a/app/src/main/res/drawable/ic_launcher_nodpi.xml
+++ b/app/src/main/res/drawable/ic_launcher_nodpi.xml
@@ -1,4 +1,14 @@
-
-
-
-
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml
index 61ff6cc1..a807a132 100644
--- a/app/src/main/res/layout/activity_login.xml
+++ b/app/src/main/res/layout/activity_login.xml
@@ -19,122 +19,134 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
-
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintBottom_toTopOf="@id/username_layout" />
-
+
+
+ android:inputType="textNoSuggestions"
+ android:hint="@string/username" />
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
-
-
-
-
-
+
diff --git a/app/src/main/res/layout/activity_unreachable.xml b/app/src/main/res/layout/activity_unreachable.xml
deleted file mode 100644
index ddc6f028..00000000
--- a/app/src/main/res/layout/activity_unreachable.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/card_about_app.xml b/app/src/main/res/layout/card_about_app.xml
index 59e36ce1..9bc04637 100644
--- a/app/src/main/res/layout/card_about_app.xml
+++ b/app/src/main/res/layout/card_about_app.xml
@@ -82,50 +82,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/app/src/main/res/layout/card_server.xml b/app/src/main/res/layout/card_server.xml
index bb7fcde2..09819218 100644
--- a/app/src/main/res/layout/card_server.xml
+++ b/app/src/main/res/layout/card_server.xml
@@ -5,6 +5,7 @@
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_margin="20dp"
+ android:background="@drawable/card_server"
android:elevation="4dp"
tools:ignore="UnusedAttribute">
diff --git a/app/src/main/res/layout/card_special_thanks.xml b/app/src/main/res/layout/card_special_thanks.xml
index 2d21f38a..d99e26e6 100644
--- a/app/src/main/res/layout/card_special_thanks.xml
+++ b/app/src/main/res/layout/card_special_thanks.xml
@@ -27,8 +27,7 @@
+ android:background="?attr/dividerColor" />
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_offline.xml b/app/src/main/res/layout/fragment_offline.xml
deleted file mode 100644
index 51d88627..00000000
--- a/app/src/main/res/layout/fragment_offline.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/notification_download.xml b/app/src/main/res/layout/notification_download.xml
deleted file mode 100644
index 3b2740bf..00000000
--- a/app/src/main/res/layout/notification_download.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-
-
-
-
-
-
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 00000000..036d09bc
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png
index 2db960bf..c455e356 100644
Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher.png and b/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png
index f995d681..1d5f0a3b 100644
Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher.png and b/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png
index 81b597fe..e8c79820 100644
Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher.png and b/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
index e258b0af..b00f5a28 100644
Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
index fc01141f..f9b1b953 100644
Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 235eb77f..6b3353bf 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -235,22 +235,5 @@
Please fill in your username.
Forking Phonograph and making Gelli
Adrian Victor
- An error occurred in Jamfish.
- You are offline.
- Change server
- Oops! I did it again...
- ;(
- Sorry, but we couldn\'t reach this server right now.
- License
- GNU General Public License v3.0
- GNU General Public License v3.0
-
- Downloads
- Downloading songs
- Downloads
-
- - Downloading %d song
- - Downloading %d songs
-
diff --git a/metadata/en-US/full_description.txt b/metadata/en-US/full_description.txt
index 2a3d80a1..62c58c1e 100644
--- a/metadata/en-US/full_description.txt
+++ b/metadata/en-US/full_description.txt
@@ -1,16 +1 @@
This is a native music player for Android devices that connects to Jellyfin media servers. The code is based on Gelli's archived repository, which is based on an old version of Phonograph. Jamfish is made for personal use, but contributions are welcome! Please open an issue to discuss larger changes before submitting a pull request.
-
-Features
-- Basic library navigation
-- Download songs to internal storage individually or through batch actions
-- Gapless playback
-- Sort albums and songs by different fields
-- Search media for partial matches
-- Media service integration with notification
-- Favorites and playlists
-- Playback history reporting
-- Filter content by library
-
-Requisites:
-- A Jellfin server
-- Android 4.4 or later
\ No newline at end of file
diff --git a/metadata/en-US/images/icon.png b/metadata/en-US/icon.png
similarity index 100%
rename from metadata/en-US/images/icon.png
rename to metadata/en-US/icon.png
diff --git a/metadata/en-US/images/phoneScreenshots/1.png b/metadata/en-US/phoneScreenshots/1.png
similarity index 100%
rename from metadata/en-US/images/phoneScreenshots/1.png
rename to metadata/en-US/phoneScreenshots/1.png
diff --git a/metadata/en-US/images/phoneScreenshots/2.png b/metadata/en-US/phoneScreenshots/2.png
similarity index 100%
rename from metadata/en-US/images/phoneScreenshots/2.png
rename to metadata/en-US/phoneScreenshots/2.png
diff --git a/metadata/en-US/images/phoneScreenshots/3.png b/metadata/en-US/phoneScreenshots/3.png
similarity index 100%
rename from metadata/en-US/images/phoneScreenshots/3.png
rename to metadata/en-US/phoneScreenshots/3.png
diff --git a/metadata/en-US/images/phoneScreenshots/4.png b/metadata/en-US/phoneScreenshots/4.png
similarity index 100%
rename from metadata/en-US/images/phoneScreenshots/4.png
rename to metadata/en-US/phoneScreenshots/4.png
diff --git a/metadata/en-US/images/phoneScreenshots/5.png b/metadata/en-US/phoneScreenshots/5.png
similarity index 100%
rename from metadata/en-US/images/phoneScreenshots/5.png
rename to metadata/en-US/phoneScreenshots/5.png