Which is the best way to use media player? - java

Just to be clear, because my question can be not so clear.
I develop Music Player app. The thing is I have MainActivity and 4 Fragments in this activity(it's not all).
In each fragment I have list of songs retrieved from device using CustomCursorAdapter(for example: first fragment - all songs, second fragment albums e.t.c.)
I already tried to use MediaPlayerSingleton
public class singletonMediaPlayer{
MediaPlayer mediaPlayer;
private static singletonMediaPlayer in = null;
private singletonMediaPlayer() { }
public static singletonMediaPlayergetInstance() {
if (in == null) {
synchronized (singletonMediaPlayer.class) {
if (in == null) {
in = new singletonMediaPlayer();
}
}
}
return instance;
}
}
But here the problem was that all playback controls I have in MainActivity(not in fragments) and have no idea how to handle previouse, next buttons. It is not a problem if media player is in fragment or activity together with ListView of songs but like this... have no idea. Plus when I tried to select item(song) from another activity it just didn't play until I press play button. Playbacks I can see it through all fragments so it's looks like this(just in case):
Plus I have 2 seperate Activities to show songs from albums and from playlists. Sooooooooooo... Finaly the question is:
How do you think it is better to build Media Player for such app (just in case, I don't need code from you). Is it better to use Music Service(which I already started to build) or maybe Singletone is better(in that case I just don't know how to perform the task with singletone for now) or maybe there is another way??? Will be great if somebody response with hint, link or just show me the way in which better to go.
Thank you in advance!
P.S.
Yep, by the way there are 3 ListViews with songs(for now) - 2 of them reusable.

Related

Android studio - mediaPlayer

I'm doing a project on Android Studio and I've got a problem:
I have changed the volume of the media in one activity and I've tried to move the media to the second activity.
I've succeded to move the audio to the second activity but it was without any volume change...
How can I fix it?
update:
Hi, because I can't save the changes that I have made in my mediaPlayer I decided to record the song before I moving between the activitys.
I got a problem with the mediaRecorder - I can't start recording and I have no idea what is wrong in my code...
my code:
rec.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(secondRemix.this, "You are starting the recording, you need to wait a little bit until it will be ready.",
Toast.LENGTH_SHORT).show();
FILE = Environment.getExternalStorageState()+"/tempRecord.3gpp";
record.setAudioSource(MediaRecorder.AudioSource.MIC);
record.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
record.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
record.setOutputFile(FILE);
record.start();//check it!!!
song.start();
startActivity(new Intent(secondRemix.this,waitScreen.class));
record.stop();
record.release();
can anybody help me with that? –
Thank you!
Is not a properly answer but might help. Short: you can't.
Why?
The native Media Player uses canvas to render the frames and it is automatic cleaned when is not on the screen.
Workaround 1: When you start the video on the new Activity automatically start from the position that the user stopped.
Workaround 2 (Like Youtube): Use fragments to manage your view.

How many activities should I use with a bottom navigation bar?

I'm fairly new to android studio, any help would be appreciated.
I have set up a bottom navigation bar programatically in my MainActivity - what's the best way to set this up with other fragments. I have three fragments, one for each tab in the navigation bar and other fragments which can be opened when buttons are pressed from the navigation bar fragments.
Where do I set up these other fragments? in the same activity that connects the fragments that are connected to the navigation bar or in a different activity.
How do I save the current state of the displayed fragment so that when I move to a different tab and then move back it will be in the same state as when I left it?
My question is, where do i set up these other fragments? in the same activity that connects the fragments that are connected to the navigation bar or in a different activity.
It's really up to you and how you want to display the fragments. You can display them in the same activity or open another activity. However bear in mind that if you open another activity, you will lose the navigation bar of the previous activity (an activity always uses the whole screen)
What does FragmentManager and FragmentTransaction exactly do?
How do I save the current state of the displayed fragment so that when
I move to a different tab and then move back it will be in the same
state as when i left it?
Read about the fragment lifecycle at https://developer.android.com/guide/components/fragments.html#Lifecycle
Specifically, you want to save your state in onSaveInstanceState, and the stuff you save will be sent back to you when the fragment is recreated in onCreate
I'd like to expand on what #rupps said, because I feel like the part about what do FragmentManager/Transaction do is not approached from where you are expecting.
I assume you're using a BottomNavigationView.
Regardless of the (important) lifecycle of Fragments, you have to understand that a Fragment is always attached to an activity (note: this is not true, but let's not talk about headless fragments for now).
The approach you can take is that the Activity layout looks like this: (in pseudo code)
<RelativeLayout width=match_parent height=match_parent>
<FrameLayout
id="#+id/your_fragment_container"
width=match_parent
height=match_parent
layout_above="#+id/navbar" />
<BottomNavigationView
id="#id/navbar"
width=match_parent
height=wrap_content
align_parent_bottom=true />
</RelativeLayout>
This way the BottomNavBar will always be present at the bottom of your layouts.
Now you have to deal with putting the fragments there… Let's say that you need to attach a Listener to that bar, and when you receive a callback that a new menu item has been selected… you can proceed to change the fragment (you will always get one event upon startup or you can force it during onCreate I suppose).
You will literally add a switch/if statement to the onNavigationItemSelected(MenuItem item) method.
and call addFragment(TAG); depending which case it is.
Pseudo-Code for you to get the idea:
private void addFragment(final String tag) {
final Fragment existing = getSupportFragmentManager().findFragmentByTag(tag);
if (existing == null) {
final Fragment newInstance = getNewFragmentInstanceWithTag(tag);
getSupportFragmentManager()
.beginTransaction()
.replace(getFragmentContainerLayout(), newInstance, tag)
.commit();
}
}
You'll also need to provide:
private int getFragmentContainerLayout() {
return R.id.your_fragment_container;
}
and…
public static final String TAB1_TAG = "TAB1_TAG";
public static final String TAB2_TAG = "TAB2_TAG";
public static final String TAB3_TAG = "TAB3_TAG";
protected Fragment getNewFragmentInstanceWithTag(String tag) {
switch (tag) {
case TAB1_TAG:
return Tab1Fragment.newInstance();
case TAB2_TAG:
return Tab2Fragment.newInstance();
case TAB3_TAG:
return Tab3Fragment.newInstance();
default:
return null;
}
}
So what the frog is the FragmentManager/Transaction?
Think of the Manager as a singleton object (one per app) that keeps a reference to your Fragments and can retrieve them for you (if they existed before). It handles Transactions (add/remove/hide/show, etc.) so you can later roll back them (say you add a fragment in a transaction, if you also addToBackStack() then you can simply tell the Manager: pop the last transaction, effectively rolling it back.
It's a monster. It had bugs for over 9000 years and it's not very intuitive; but once you get used to it, you just "use it".

Calling two different activities on different devices (tablet and phone)

Here, I'm trying to start an activity on different devices (Android Tablet and Android Phone). Is there a way to use if statement to check which activity should to load based on the devices?
Here's my code:
Button buttonGo = (Button) findViewById(R.id.button_goToActivity);
buttonGo.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (tablet device) {
startActivity(new Intent(MainActivity.this, TabletActivity.class));
} else {
startActivity(new Intent(MainActivity.this, AndroidPhoneActivity.class));
}
});
Thanks for your effort...
In order to achieve that you must use Fragment not an Activity. the Design Philosophy of Fragments is exactly what you want. you can take a look at Example to see how it is implemented. This is a master-detail app with two Fragments, when device in a portrait mode or it is not a tablet it just shows master, otherwise it also shows detail beside the master and when you select an item from the list you will see the details without going to other Activity.
Firstly as Android Best Practice it is adviced to use Fragments rather than Activity to achieve your requirement.
But if you are keen on using Activity, then below is the solution to find device type and load different activities.
1) Have 2 values folders: values -> strings.xml and values-sw600dp -> strings.xml
2) Create string value in both the xml
<string name="device_type">PHONE</string> in values -> strings.xml
<string name="device_type">TABLET</string> in values-sw600dp -> strings.xml
3) create a method to check if current device is Phone or not
public boolean isPhone() {
String deviceType = getResource().getString(R.string.device_type);
if (deviceType.equalsIgnoreCase("PHONE") {
return true;
} else {
return false;
}
}
4) Depending on the device load your activity as you have already done in your above code snippet
Let me know if this helps...
Most likely, you should not have two separate activities here. Instead, you should have two different layouts for the same activity. The layout for phones should be in the regular res/layout folder and the layout for tablets should be in the res/layout-large folder. Read Supporting Different Screens for more details.
If you are using same fuctionality for Tablet Activity and Phone activity then you do not need two activities for this purpose. You need to make two different Layout xml for Tablet as well as Phone.
Make a Layout folder named : layout-large and layout-xlarge.
Now copy the xml file from normal layout folder and paste in both new layout folders.
No need to change the name of xml file.
Now Adjust xml file of layout-large and layot-xlarge as you want to make design for tablet.
Now on running application Tablet and phone bot will pick xml according to there size and screen density.
Note : the functionality should be same.
And if: you want to show different screen with different functionality for phone and tablet then. use this code for check.
if ((getResources().getConfiguration().screenLayout &
Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_LARGE) {
}
Hope this wll help you.

Bring Live Wallpaper to Front

I had originally asked another question, but I think I found a work-around, which presents a new question hah!
I think my question is fairly basic, and I have searched for anything relevant.
When you are setting a live wallpaper in android, before you set the wallpaper, you have a chance to view the wallpaper without being in the background with all of your icons above it. A sort of "preview" of the wallpaper.
Is there a simple java code to force this activity, on a double tap for instance? I want the user to be able to bring the wallpaper to the front on demand basically.
Maybe this isn't possible, but I assume it is as you can do it before you actually set the wallpaper.
Any help would be greatly appreciated.
Thanks,
Jack
Edit-
I should note I think I found a similar question but the English is so bad I can't tell:
How to make directly show live wallpaper in main activity?
public void StartActivity() {
WallpaperInfo localWallpaperInfo = ((WallpaperManager) getSystemService("wallpaper")).getWallpaperInfo();
if (localWallpaperInfo != null) {
String str1 = localWallpaperInfo.getSettingsActivity();
if (str1 != null) {
String str2 = localWallpaperInfo.getPackageName();
Intent localIntent1 = new Intent();
ComponentName localComponentName = new ComponentName(str2, str1);
localIntent1.setComponent(localComponentName);
localIntent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(localIntent1);
}
}
You can use
wallpaper.bringToFront(); With a double tap listener.
Or you can use the answer on the question you have in your edit.

Call Activity from a view

I have a class called TouchImageView extends ImageView and I detect where the user clicks on it. If it is a interest point, I want to call a method on the Detailed_Image_Activity that will update a WebView. How can I achieve this?
I found some ideas about using observer and observables but I don't know how to do that. I found this solution Equivalent of iOS NSNotificationCenter in Android? but I can't make it work it
This is my code in the TouchImageView class...
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if(isPointOfInterest) {
//The code below is used to update the WebView
//The task called below exists in the Detailed_Image_Activity
DownloadHighlightBackground HighlightDownloaderTask = new DownloadHighlightBackground();
HighlightDownloaderTask.execute(new String[] { arg1.toString() });
}
}
Try this,
You can get the activity from within the view, in this way..
((MyActivity)getContext()).method_name();
To start up an activity you need access to the application's context and then you can call startActivity.

Categories