diff --git a/.screenshots/zz1.jpg b/.screenshots/zz1.jpg new file mode 100644 index 0000000..650a9b2 Binary files /dev/null and b/.screenshots/zz1.jpg differ diff --git a/.screenshots/zz2.jpg b/.screenshots/zz2.jpg new file mode 100644 index 0000000..0be724a Binary files /dev/null and b/.screenshots/zz2.jpg differ diff --git a/.screenshots/zz3.jpg b/.screenshots/zz3.jpg new file mode 100644 index 0000000..dee61dd Binary files /dev/null and b/.screenshots/zz3.jpg differ diff --git a/README.md b/README.md index 150e8d6..2f20124 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,33 @@ -# ZryteZene Java Mobile -> Currently under development by 1 person, so it may take longer to finish, its hard to implement the run-in-background system where since Android 14 or newer restricted the background services the most. Estimated time to finish: 6 weeks - 7 months, hehe. +# ZryteZene Mobile - Java +> [!NOTE] +> **ZryteZene** is a multi-platform app to allow users to stream musics across various devices seamlessly, such as Android, desktop and web platform. Its completely free and ad-free too. -# Overview -**ZryteZene** is a multi-platform app to allow users to stream musics across various devices seamlessly, such as Android, desktop and web platform. Its completely free and ad-free too. +**ZryteZene Mobile** is an ad-free, background-enabled music streaming app designed to provide a seamless and uninterrupted music experience for Android users. Unlike traditional streaming services, Zryte prioritizes user freedom and simplicity while delivering essential features for music enthusiasts. Whether you're at home, on the go, or working out, Zryte ensures your favorite tracks are always just a tap away. + +# Development +

+ + + +

+ +> Currently under development by limited persons, so it may take longer to finish, its hard to implement the run-in-background system where since Android 14 or newer restricted the background services the most. Estimated time to finish: 6 weeks - 7 months, hehe. # Requirements -- Minimum SDK : 27 (Oreo) -- Compile SDK : 34 (Upside Down Cake) -- Language : Java - Native \ No newline at end of file +- Minimum SDK : Android 8 / API 27 (Oreo) +- Compile SDK : Android 14 / API 34 (Upside Down Cake) +- Language : Java - Native + +## Features +- **Ad-Free Experience**: Enjoy your music without interruptions from ads. +- **Background Playback**: Continue listening even when the app is minimized or your screen is off. +- **MediaStyle Notifications**: Control your music directly from the notification panel with an intuitive interface. +- **Seamless Playback**: Play, pause, skip, and resume music effortlessly. +- **Offline Support (Coming Soon)**: Download tracks for offline listening. +- **Simple and Intuitive UI**: Navigate easily with a clean and user-friendly interface. + +## Future Plans +- **Offline Playback**: Allow users to download songs and play them without an internet connection. +- **Listen Pairing**: Create a play room and listen to the songs together with them. +- **Equalizer Integration**: Customize your listening experience. +- **Dynamic Themes**: Support for light and dark themes. diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 3606cc3..cd267f0 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -81,6 +81,9 @@ + + diff --git a/app/src/main/java/tw/music/streamer/MainActivity.java b/app/src/main/java/tw/music/streamer/MainActivity.java index fc5b7d1..54f3ca4 100644 --- a/app/src/main/java/tw/music/streamer/MainActivity.java +++ b/app/src/main/java/tw/music/streamer/MainActivity.java @@ -994,7 +994,7 @@ private void _chkChglog() { if ((double) packageInfo.versionCode > Double.parseDouble(data.getString("lastVersion", ""))) { _dispChglog(); } else { - activityChanger.setClass(getApplicationContext(), StreamerActivity.class); + activityChanger.setClass(getApplicationContext(), StreamingActivity.class); startActivity(activityChanger); finish(); } @@ -1010,7 +1010,7 @@ private void _dispChglog() { @Override public void onClick(DialogInterface _dialog, int _which) { data.edit().putString("lastVersion", String.valueOf((long) ((double) packageInfo.versionCode))).commit(); - activityChanger.setClass(getApplicationContext(), StreamerActivity.class); + activityChanger.setClass(getApplicationContext(), StreamingActivity.class); startActivity(activityChanger); finish(); } diff --git a/app/src/main/java/tw/music/streamer/MainActivity2.java b/app/src/main/java/tw/music/streamer/MainActivity2.java deleted file mode 100644 index 6d5c341..0000000 --- a/app/src/main/java/tw/music/streamer/MainActivity2.java +++ /dev/null @@ -1,18 +0,0 @@ -package tw.music.streamer; - -import androidx.appcompat.app.AppCompatActivity; -import android.app.Activity; -import android.os.Bundle; - -public class MainActivity2 extends AppCompatActivity { - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - } - - @Override - protected void onDestroy() { - super.onDestroy(); - } -} \ No newline at end of file diff --git a/app/src/main/java/tw/music/streamer/StreamingActivity.java b/app/src/main/java/tw/music/streamer/StreamingActivity.java new file mode 100644 index 0000000..c989d74 --- /dev/null +++ b/app/src/main/java/tw/music/streamer/StreamingActivity.java @@ -0,0 +1,374 @@ +package tw.music.streamer; + +import android.os.Bundle; +import android.view.View; +import android.widget.ImageView; +import android.widget.TextView; +import android.widget.ProgressBar; +import android.widget.LinearLayout; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.BroadcastReceiver; +import android.content.res.ColorStateList; +import android.graphics.Color; +import android.graphics.PorterDuff; +import android.graphics.drawable.Drawable; +import android.graphics.drawable.GradientDrawable; + +import androidx.appcompat.app.AppCompatActivity; +import androidx.recyclerview.widget.RecyclerView; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.GridLayoutManager; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.load.resource.bitmap.RoundedCorners; + +import com.google.firebase.auth.FirebaseAuth; +import com.google.firebase.database.DataSnapshot; +import com.google.firebase.database.DatabaseReference; +import com.google.firebase.database.FirebaseDatabase; +import com.google.firebase.storage.FirebaseStorage; +import com.google.firebase.storage.StorageReference; + +import java.util.ArrayList; + +import tw.music.streamer.adaptor.ZZSong; +import tw.music.streamer.adaptor.ZryteZeneAdaptor; +import tw.music.streamer.adapter.ZZSongAdapter; +import tw.music.streamer.adapter.ZZOnClickListener; +import tw.music.streamer.adapter.ZZRandomSongAdapter; +import tw.music.streamer.service.ZryteZenePlay; + +public class StreamingActivity extends AppCompatActivity { + + private FirebaseAuth auth; + private DatabaseReference db_song, db_drsong; + private StorageReference fs_music; + private BroadcastReceiver zzreceiver; + + private RecyclerView rv_random_songs, rv_songs; + private LinearLayoutManager lm1; + private GridLayoutManager lm2; + private TextView user_welcome, taptext1, taptext2, taptext3, taptext4, mp_title, mp_artist; + private ImageView user_icon, tapicon1, tapicon2, tapicon3, mp_play, mp_icon, bg_drop; + private LinearLayout menu_bar, tapbar1, tapbar2, tapbar3, tapbar4, mp_base; + private ProgressBar mp_bar; + + private ArrayList zz_songs, zz_songs2; + + private ZryteZeneAdaptor zz; + private ZZRandomSongAdapter ra_songs; + private ZZSongAdapter ar_songs; + private ZZOnClickListener zz_click1; + + private int openMenu = 0; + + @Override + protected void onCreate(Bundle a) { + super.onCreate(a); + setContentView(R.layout.stream_base); + initVariables(getApplicationContext()); + initFirebase(); + initLayout(); + initOnClick(getApplicationContext()); + initLogic(getApplicationContext()); + initFirebaseListener(getApplicationContext()); + initBackgroundServices(getApplicationContext()); + } + + private void initVariables(Context a) { + zz_songs = new ArrayList<>(); + zz_songs2 = new ArrayList<>(); + zz_click1 = new ZZOnClickListener() { + public void onItemClicked(int a) { + playFromZZSongs(a); + } + }; + ra_songs = new ZZRandomSongAdapter(zz_songs2); + ar_songs = new ZZSongAdapter(zz_songs, zz_click1); + lm1 = new LinearLayoutManager(a, LinearLayoutManager.HORIZONTAL, false); + lm2 = new GridLayoutManager(a, 2); + } + + private void initFirebase() { + auth = FirebaseAuth.getInstance(); + db_song = FirebaseDatabase.getInstance().getReference("zrytezene/songs"); + db_drsong = FirebaseDatabase.getInstance().getReference("zrytezene/daily-random-songs"); + } + + private void initFirebaseListener(final Context z) { + db_song.limitToFirst(20).get().addOnCompleteListener(a -> { + if (a.isSuccessful()) { + DataSnapshot b = a.getResult(); + if (b.exists()) { + for (DataSnapshot c : b.getChildren()) { + zz_songs.add(new ZZSong(c)); + } + ar_songs.notifyDataSetChanged(); + } else { + // songs empty + } + } else { + // error: task.getException().getMessage() + } + }); + + db_drsong.get().addOnCompleteListener(a -> { + if (a.isSuccessful()) { + DataSnapshot b = a.getResult(); + if (b.exists()) { + for (DataSnapshot c : b.getChildren()) { + zz_songs2.add(new ZZSong(c)); + } + ra_songs.notifyDataSetChanged(); + } + } + }); + + FirebaseDatabase.getInstance().getReference("profile/image/" + auth.getCurrentUser().getUid()).get().addOnCompleteListener(a -> { + if (a.isSuccessful()) { + DataSnapshot b = a.getResult(); + if (b.exists() && b.hasChild("url")) { + Glide.with(z).load(b.child("url").getValue(String.class)).apply(RequestOptions.circleCropTransform()).into(user_icon); + } + } + }); + + FirebaseDatabase.getInstance().getReference("profile/text/" + auth.getCurrentUser().getUid()).get().addOnCompleteListener(a -> { + if (a.isSuccessful()) { + DataSnapshot b = a.getResult(); + if (b.exists() && b.hasChild("username")) { + user_welcome.setText("Hello, " + b.child("username").getValue(String.class) + "!"); + } + } + }); + } + + private void initLayout() { + user_welcome = findViewById(R.id.profile_name); + user_icon = findViewById(R.id.profile_icon); + rv_random_songs = findViewById(R.id.random_music_container); + rv_songs = findViewById(R.id.uploaded_music_container); + bg_drop = findViewById(R.id.sbbg); + menu_bar = findViewById(R.id.sb_bottom_menu_bar); + mp_bar = findViewById(R.id.zzmp1_progress); + mp_base = findViewById(R.id.zzmp1_base); + mp_play = findViewById(R.id.zzmp1_play); + mp_icon = findViewById(R.id.zzmp1_icon); + mp_title = findViewById(R.id.zzmp1_title); + mp_artist = findViewById(R.id.zzmp1_artist); + tapbar1 = findViewById(R.id.sbmb1); + tapbar2 = findViewById(R.id.sbmb2); + tapbar3 = findViewById(R.id.sbmb3); + tapbar4 = findViewById(R.id.sbmb4); + tapicon1 = findViewById(R.id.sbmi1); + tapicon2 = findViewById(R.id.sbmi2); + tapicon3 = findViewById(R.id.sbmi3); + taptext1 = findViewById(R.id.sbmt1); + taptext2 = findViewById(R.id.sbmt2); + taptext3 = findViewById(R.id.sbmt3); + taptext4 = findViewById(R.id.sbmt4); + mp_base.setVisibility(View.GONE); + } + + private void initOnClick(final Context a) { + tapbar1.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View b) { + openMenuBar(1,true); + } + }); + tapbar2.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View b) { + openMenuBar(2,true); + } + }); + tapbar3.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View b) { + openMenuBar(3,true); + } + }); + tapbar4.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View b) { + openMenuBar(4,true); + } + }); + } + + private void initLogic(final Context a) { + scaleLower(tapicon1); + scaleLower(tapicon2); + scaleLower(tapicon3); + scaleLower(user_icon); + openMenuBar(1,false); + getWindow().setStatusBarColor(0xFF000000); + menu_bar.setBackground(new GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, new int[]{Color.argb(90,0,0,0),Color.argb(150,0,0,0)})); + rv_random_songs.setLayoutManager(lm1); + rv_random_songs.setAdapter(ra_songs); + rv_songs.setLayoutManager(lm2); + rv_songs.setAdapter(ar_songs); + } + + private void initBackgroundServices(final Context a) { + zz = new ZryteZeneAdaptor(a); + zzreceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (intent != null && intent.getAction() != null) { + if (intent.getAction().equals(ZryteZenePlay.ACTION_UPDATE)) { + String m = intent.getStringExtra("update"); + if (m.equals("on-prepared")) { + zz.setPlaying(true); + zz.setCurrentDuration(0); + zz.setDuration(intent.getIntExtra("data",0)/1000); + mp_bar.setProgress(0); + mp_bar.setMax(zz.getDuration()); + } else if (m.equals("on-reqmedia")) { + int b = intent.getIntExtra("status",0); + if (b > 0) { + if (b==1) mp_play.setImageResource(R.drawable.ic_pause_white); + zz.setPlaying(b == 1); + zz.setCurrentDuration(intent.getIntExtra("currentDuration",0)/1000); + zz.setDuration(intent.getIntExtra("duration",0)/1000); + mp_bar.setMax(zz.getDuration()); + mp_bar.setProgress(zz.getCurrentDuration()); + loadSongFromKey(intent.getStringExtra("key")); + } + } else if (m.equals("on-tick")) { + zz.setCurrentDuration(intent.getIntExtra("data",0)); + mp_bar.setProgress(zz.getCurrentDuration()/1000); + } else if (m.equals("on-completion")) { + zz.setPlaying(false); + } else if (m.equals("on-error")) { + zz.addError(intent.getStringExtra("data")); + } else if (m.equals("on-seekerror")) { + } else if (m.equals("on-initialized")) { + } else if (m.equals("on-bufferupdate")) { + zz.setBufferingUpdate(intent.getIntExtra("data",0)); + } else if (m.equals("request-play")) { + } else if (m.equals("request-pause")) { + zz.setPlaying(false); + } else if (m.equals("request-resume")) { + zz.setPlaying(true); + } else if (m.equals("request-stop")) { + zz.setPlaying(false); + } else if (m.equals("request-seek")) { + zz.setCurrentDuration(intent.getIntExtra("data",0)/1000); + } else if (m.equals("request-restart")) { + zz.setCurrentDuration(0); + } else if (m.equals("request-reset")) { + } + } + } + } + }; + IntentFilter filr = new IntentFilter(ZryteZenePlay.ACTION_UPDATE); + registerReceiver(zzreceiver, filr); + zz.requestAction("request-media"); + } + + private void playFromZZSongs(int a) { + mp_artist.setText(zz_songs.get(a).song_artist); + mp_title.setText(zz_songs.get(a).song_name); + mp_play.setImageResource(R.drawable.ic_pause_white); + Glide.with(getApplicationContext()).load(zz_songs.get(a).url_icon).transform(new RoundedCorners(dip(5))).into(mp_icon); + mp_base.setVisibility(View.VISIBLE); + Glide.with(getApplicationContext()).load(zz_songs.get(a).url_cover).into(bg_drop); + mp_bar.setProgressTintList(ColorStateList.valueOf(Color.parseColor(zz_songs.get(a).color1))); + zz.play(zz_songs.get(a)); + } + + private void loadSongFromKey(String a) { + FirebaseDatabase.getInstance().getReference("zrytezene/songs/" + a).get().addOnCompleteListener(b -> { + if (b.isSuccessful()) { + DataSnapshot c = b.getResult(); + if (c.exists()) { + mp_artist.setText(c.child("artist").getValue(String.class)); + mp_title.setText(c.child("title").getValue(String.class)); + Glide.with(getApplicationContext()).load(c.child("icon").getValue(String.class)).transform(new RoundedCorners(dip(5))).into(mp_icon); + mp_base.setVisibility(View.VISIBLE); + Glide.with(getApplicationContext()).load(c.child("cover").getValue(String.class)).into(bg_drop); + mp_bar.setProgressTintList(ColorStateList.valueOf(Color.parseColor(c.child("color-bline").getValue(String.class)))); + } + } + }); + } + + private void openMenuBar(int a, boolean b) { + if (a==openMenu) return; + tapicon1.setColorFilter(0xFF757575, PorterDuff.Mode.MULTIPLY); + tapicon2.setColorFilter(0xFF757575, PorterDuff.Mode.MULTIPLY); + tapicon3.setColorFilter(0xFF757575, PorterDuff.Mode.MULTIPLY); + taptext1.setTextColor(0xFF757575); + taptext2.setTextColor(0xFF757575); + taptext3.setTextColor(0xFF757575); + taptext4.setTextColor(0xFF757575); + if (b) { + if (openMenu==1) animateScaleDown(tapicon1); + if (openMenu==2) animateScaleDown(tapicon2); + if (openMenu==3) animateScaleDown(tapicon3); + if (openMenu==4) animateScaleDown(user_icon); + }; + if (a == 1) { + tapicon1.clearColorFilter(); + taptext1.setTextColor(0xFFFFFFFF); + if (b) { + animateScaleUp(tapicon1); + } else { + scaleBigger(tapicon1); + } + } else if (a == 2) { + tapicon2.clearColorFilter(); + taptext2.setTextColor(0xFFFFFFFF); + if (b) { + animateScaleUp(tapicon2); + } else { + scaleBigger(tapicon2); + } + } else if (a == 3) { + tapicon3.clearColorFilter(); + taptext3.setTextColor(0xFFFFFFFF); + if (b) { + animateScaleUp(tapicon3); + } else { + scaleBigger(tapicon3); + } + } else if (a == 4) { + taptext4.setTextColor(0xFFFFFFFF); + if (b) { + animateScaleUp(user_icon); + } else { + scaleBigger(user_icon); + } + }; + openMenu = a; + } + + private void scaleLower(View a) { + a.setScaleX(0.8f); + a.setScaleY(0.8f); + } + + private void scaleBigger(View a) { + a.setScaleX(1f); + a.setScaleY(1f); + } + + private void animateScaleUp(View a) { + a.animate().setDuration(300).scaleX(1f).scaleY(1f); + } + + private void animateScaleDown(View a) { + a.animate().setDuration(300).scaleX(0.8f).scaleY(0.8f); + } + + private int dip(int a) { + return (int) (a * getApplicationContext().getResources().getDisplayMetrics().density); + } + +} \ No newline at end of file diff --git a/app/src/main/java/tw/music/streamer/adapter/ZZOnClickListener.java b/app/src/main/java/tw/music/streamer/adapter/ZZOnClickListener.java new file mode 100644 index 0000000..6dd10f6 --- /dev/null +++ b/app/src/main/java/tw/music/streamer/adapter/ZZOnClickListener.java @@ -0,0 +1,5 @@ +package tw.music.streamer.adapter; + +public interface ZZOnClickListener { + void onItemClicked(int a); +} \ No newline at end of file diff --git a/app/src/main/java/tw/music/streamer/adapter/ZZRandomSongAdapter.java b/app/src/main/java/tw/music/streamer/adapter/ZZRandomSongAdapter.java new file mode 100644 index 0000000..6ed906a --- /dev/null +++ b/app/src/main/java/tw/music/streamer/adapter/ZZRandomSongAdapter.java @@ -0,0 +1,59 @@ +package tw.music.streamer.adapter; + +import android.graphics.Color; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; +import android.widget.RelativeLayout; +import android.widget.ImageView; +import android.widget.LinearLayout; +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; +import java.util.ArrayList; + +import tw.music.streamer.R; +import tw.music.streamer.adaptor.ZZSong; + +import com.bumptech.glide.Glide; + +public class ZZRandomSongAdapter extends RecyclerView.Adapter { + + private ArrayList data; + + public ZZRandomSongAdapter(ArrayList a) { + data = a; + } + + @NonNull + @Override + public ZZViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.song_list_item_2, parent, false); + return new ZZViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ZZViewHolder h, int p) { + h.title.setText(data.get(p).song_name); + h.line.setBackgroundColor(Color.parseColor(data.get(p).color1)); + Glide.with(h.title.getContext()).load(data.get(p).url_cover).into(h.cover); + } + + @Override + public int getItemCount() { + return data.size(); + } + + public static class ZZViewHolder extends RecyclerView.ViewHolder { + TextView title; + ImageView cover; + LinearLayout line; + + public ZZViewHolder(@NonNull View i) { + super(i); + title = i.findViewById(R.id.sli2_title); + cover = i.findViewById(R.id.sli2_cover); + line = i.findViewById(R.id.sli2_bottom_line); + } + } +} diff --git a/app/src/main/java/tw/music/streamer/adapter/ZZSongAdapter.java b/app/src/main/java/tw/music/streamer/adapter/ZZSongAdapter.java new file mode 100644 index 0000000..bb9e717 --- /dev/null +++ b/app/src/main/java/tw/music/streamer/adapter/ZZSongAdapter.java @@ -0,0 +1,72 @@ +package tw.music.streamer.adapter; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; +import android.widget.RelativeLayout; +import android.widget.ImageView; +import android.widget.LinearLayout; +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; +import java.util.ArrayList; + +import tw.music.streamer.R; +import tw.music.streamer.adaptor.ZZSong; + +import com.bumptech.glide.Glide; + +public class ZZSongAdapter extends RecyclerView.Adapter { + + private ArrayList data; + private ZZOnClickListener listener; + + public ZZSongAdapter(ArrayList a, ZZOnClickListener b) { + data = a; + listener = b; + } + + @NonNull + @Override + public ZZViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.song_list_item_1, parent, false); + return new ZZViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ZZViewHolder h, final int p) { + h.title.setText(data.get(p).song_name); + h.artist.setText(data.get(p).song_artist); + Glide.with(h.title.getContext()).load(data.get(p).url_cover).into(h.cover); + h.cover.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View a) { + callListener(p); + } + }); + } + + @Override + public int getItemCount() { + return data.size(); + } + + public static class ZZViewHolder extends RecyclerView.ViewHolder { + TextView title; + TextView artist; + ImageView cover; + + public ZZViewHolder(@NonNull View i) { + super(i); + title = i.findViewById(R.id.sli1_title); + artist = i.findViewById(R.id.sli1_artist); + cover = i.findViewById(R.id.sli1_cover); + } + } + + public void callListener(int a) { + if (listener!=null) { + listener.onItemClicked(a); + } + } +} diff --git a/app/src/main/java/tw/music/streamer/adaptor/ZZSong.java b/app/src/main/java/tw/music/streamer/adaptor/ZZSong.java new file mode 100644 index 0000000..2930e5e --- /dev/null +++ b/app/src/main/java/tw/music/streamer/adaptor/ZZSong.java @@ -0,0 +1,24 @@ +package tw.music.streamer.adaptor; + +import com.google.firebase.database.DataSnapshot; + +public class ZZSong { + + public static final String PATH = "https://firebasestorage.googleapis.com/v0/b/teammusic-tw.appspot.com/o/zrytezene%2Fsongs%2F"; + + public String key, url_song, url_icon, url_cover, uploader_uid, uploader_name, song_name, song_artist, color1; + public boolean playing; + + public ZZSong(DataSnapshot a) { + playing = false; + key = a.getKey(); + url_song = PATH + a.child("song").getValue(String.class); + url_icon = PATH + a.child("icon").getValue(String.class); + url_cover = PATH + a.child("cover").getValue(String.class); + uploader_uid = a.child("uid").getValue(String.class); + uploader_name = a.child("uploader").getValue(String.class); + song_name = a.child("title").getValue(String.class); + song_artist = a.child("artist").getValue(String.class); + color1 = a.child("color-bline").getValue(String.class); + } +} \ No newline at end of file diff --git a/app/src/main/java/tw/music/streamer/adaptor/ZryteZeneAdaptor.java b/app/src/main/java/tw/music/streamer/adaptor/ZryteZeneAdaptor.java index 475cfe2..d607f04 100644 --- a/app/src/main/java/tw/music/streamer/adaptor/ZryteZeneAdaptor.java +++ b/app/src/main/java/tw/music/streamer/adaptor/ZryteZeneAdaptor.java @@ -104,12 +104,46 @@ public void requestAction(String a, String b) { } public void play(String a, String b, String c, String d) { - Intent jof = new Intent(ZryteZenePlay.ACTION_BROADCAST); - jof.putExtra("action", "play"); - jof.putExtra("path", a); - jof.putExtra("title", b); - jof.putExtra("artist", c); - jof.putExtra("cover", d); - ctx.sendBroadcast(jof); + if (isr) { + Intent jof = new Intent(ZryteZenePlay.ACTION_BROADCAST); + jof.putExtra("action", "play"); + jof.putExtra("path", a); + jof.putExtra("title", b); + jof.putExtra("artist", c); + jof.putExtra("cover", d); + ctx.sendBroadcast(jof); + } else { + Intent siop = new Intent(ctx, ZryteZenePlay.class); + siop.putExtra("action", "play"); + siop.putExtra("path", a); + siop.putExtra("title", b); + siop.putExtra("artist", c); + siop.putExtra("cover", d); + ctx.startForegroundService(siop); + isr = true; + } + } + + public void play(ZZSong a) { + if (isr) { + Intent jof = new Intent(ZryteZenePlay.ACTION_BROADCAST); + jof.putExtra("action", "play"); + jof.putExtra("path", a.url_song); + jof.putExtra("title", a.song_name); + jof.putExtra("artist", a.song_artist); + jof.putExtra("cover", a.url_cover); + jof.putExtra("key", a.key); + ctx.sendBroadcast(jof); + } else { + Intent siop = new Intent(ctx, ZryteZenePlay.class); + siop.putExtra("action", "play"); + siop.putExtra("path", a.url_song); + siop.putExtra("title", a.song_name); + siop.putExtra("artist", a.song_artist); + siop.putExtra("cover", a.url_cover); + siop.putExtra("key", a.key); + ctx.startForegroundService(siop); + isr = true; + } } } \ No newline at end of file diff --git a/app/src/main/java/tw/music/streamer/notification/ZryteZeneNotification.java b/app/src/main/java/tw/music/streamer/notification/ZryteZeneNotification.java index dc4059e..2e35715 100644 --- a/app/src/main/java/tw/music/streamer/notification/ZryteZeneNotification.java +++ b/app/src/main/java/tw/music/streamer/notification/ZryteZeneNotification.java @@ -30,19 +30,17 @@ public class ZryteZeneNotification { public static Notification setup(Context a) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - NotificationChannel ch = new NotificationChannel( - ZryteZenePlay.CHANNEL_ID, - "ZryteZene Player", - NotificationManager.IMPORTANCE_LOW - ); - ch.setSound(null, null); - ch.enableLights(false); - ch.enableVibration(false); - NotificationManager mr = a.getSystemService(NotificationManager.class); - if (mr != null) { - mr.createNotificationChannel(ch); - } + NotificationChannel ch = new NotificationChannel( + ZryteZenePlay.CHANNEL_ID, + "ZryteZene Player", + NotificationManager.IMPORTANCE_LOW + ); + ch.setSound(null, null); + ch.enableLights(false); + ch.enableVibration(false); + NotificationManager mr = a.getSystemService(NotificationManager.class); + if (mr != null) { + mr.createNotificationChannel(ch); } Intent openAppIntent = new Intent(a, StreamerActivity.class); @@ -78,17 +76,15 @@ public void onLoadCleared(@Nullable Drawable i) { } public static void updateWithMedia(Context a, boolean b, MediaSessionCompat c, String d, String e, Bitmap f) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - NotificationChannel channel = new NotificationChannel(ZryteZenePlay.CHANNEL_ID, "ZryteZene Player", NotificationManager.IMPORTANCE_LOW); - NotificationManager manager = a.getSystemService(NotificationManager.class); - if (manager != null) { - manager.createNotificationChannel(channel); - } - } + NotificationChannel channel = new NotificationChannel(ZryteZenePlay.CHANNEL_ID, "ZryteZene Player", NotificationManager.IMPORTANCE_LOW); + NotificationManager manager = a.getSystemService(NotificationManager.class); + if (manager != null) { + manager.createNotificationChannel(channel); + } - Intent playPauseIntent = new Intent(a, ZryteZenePlay.class).setAction(ZryteZenePlay.ACTION_BROADCAST).putExtra("action", b ? "pause" : "resume"); - Intent previousIntent = new Intent(a, ZryteZenePlay.class).setAction(ZryteZenePlay.ACTION_BROADCAST).putExtra("action", "previous"); - Intent nextIntent = new Intent(a, ZryteZenePlay.class).setAction(ZryteZenePlay.ACTION_BROADCAST).putExtra("action", "forward"); + Intent playPauseIntent = new Intent(a, ZryteZenePlay.class).putExtra("action", b ? "pause" : "resume"); //setAction(ZryteZenePlay.ACTION_BROADCAST). + Intent previousIntent = new Intent(a, ZryteZenePlay.class).putExtra("action", "previous"); + Intent nextIntent = new Intent(a, ZryteZenePlay.class).putExtra("action", "forward"); PendingIntent playPausePendingIntent = PendingIntent.getService(a, 0, playPauseIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); PendingIntent previousPendingIntent = PendingIntent.getService(a, 0, previousIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); PendingIntent nextPendingIntent = PendingIntent.getService(a, 0, nextIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); diff --git a/app/src/main/java/tw/music/streamer/service/ZryteZenePlay.java b/app/src/main/java/tw/music/streamer/service/ZryteZenePlay.java index d4a88b1..8b2d8c8 100644 --- a/app/src/main/java/tw/music/streamer/service/ZryteZenePlay.java +++ b/app/src/main/java/tw/music/streamer/service/ZryteZenePlay.java @@ -34,7 +34,7 @@ public class ZryteZenePlay extends Service implements MediaPlayer.OnPreparedList private MediaPlayer mp; private IntentFilter ief; private SharedPreferences sp; - private String lm, act, csp, sn, sa, sc; + private String lm, act, csp, sn, sa, sc, sk; private Intent ita; private Handler ha = new Handler(); private boolean pd = false; @@ -134,8 +134,6 @@ private void onReceived(Intent a) { } private void onReceived(Context a, Intent b) { - if (b.getAction() == null) return; - if (!b.getAction().equals(ACTION_BROADCAST)) return; if (!b.hasExtra("action")) return; act = b.getStringExtra("action"); if (act.equals("seek")) { @@ -171,6 +169,7 @@ private void playSong(Intent a) { sn = a.getStringExtra("title"); sa = a.getStringExtra("artist"); sc = a.getStringExtra("cover"); + sk = a.getStringExtra("key"); if (mp != null) { mp.reset(); } else { @@ -278,6 +277,7 @@ private void requestMedia() { if (mp != null && isPrepared()) { ita.putExtra("duration", mp.getDuration()); ita.putExtra("currentDuration", mp.getCurrentPosition()); + ita.putExtra("key", sk); } sendBroadcast(ita); } diff --git a/app/src/main/res/layout/song_list_item_1.xml b/app/src/main/res/layout/song_list_item_1.xml new file mode 100644 index 0000000..3157aab --- /dev/null +++ b/app/src/main/res/layout/song_list_item_1.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/song_list_item_2.xml b/app/src/main/res/layout/song_list_item_2.xml new file mode 100644 index 0000000..4f728ab --- /dev/null +++ b/app/src/main/res/layout/song_list_item_2.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/stream_base.xml b/app/src/main/res/layout/stream_base.xml index a6275af..3231682 100644 --- a/app/src/main/res/layout/stream_base.xml +++ b/app/src/main/res/layout/stream_base.xml @@ -1,48 +1,67 @@ - + + + android:background="#ED000000"> - + + - - - - + android:layout_height="wrap_content" + android:layout_marginBottom="8dp"/> + + - + + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" + android:gravity="bottom"> + + \ No newline at end of file diff --git a/app/src/main/res/layout/zzbottomappbar1.xml b/app/src/main/res/layout/zzbottomappbar1.xml new file mode 100644 index 0000000..4997d27 --- /dev/null +++ b/app/src/main/res/layout/zzbottomappbar1.xml @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/zzminiplayer1.xml b/app/src/main/res/layout/zzminiplayer1.xml new file mode 100644 index 0000000..be67ac6 --- /dev/null +++ b/app/src/main/res/layout/zzminiplayer1.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + \ No newline at end of file