Streaming Audio Using Service - android

Please take a look at my simple three-methods Service class that streams audio and play it directly.
public class StreamService extends Service {
private static final String TAG = "MyService";
String url;
MediaPlayer mp;
#Override
public void onCreate() {
Toast.makeText(this, "My Service Created", Toast.LENGTH_LONG).show();
Log.d(TAG, "onCreate");
mp = new MediaPlayer();
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
}
#Override
public void onDestroy() {
Toast.makeText(this, "My Service Stopped", Toast.LENGTH_LONG).show();
Log.d(TAG, "onDestroy");
mp.stop();
}
#Override
public int onStartCommand(Intent intent, int flags, int startid) {
Toast.makeText(this, "My Service Started", Toast.LENGTH_LONG).show();
Log.d(TAG, "onStart");
url = intent.getExtras().getString("url");
try {
mp.setDataSource(url);
mp.prepare();
mp.start();
} catch(Exception e){}
return START_STICKY;
}
}
In my activity, I have two buttons to play/stop the media file:
The playButton execute this:
Intent i = new Intent(this, StreamService.class);
i.putExtra("my_mp3_url_string");
startService(i);
The stopButton execute this:
stopService(new Intent(this, StreamService.class));
Now, I have some questions:
how I can implement the pauseButton? I want to pause the media running in the Service
Does my way of playing/stopping the media/Service correct ? Is there any better way?
How I can (periodically) update my Activity's UI from my Service? do I need to add something?

I would recommend not using the lifetime of the Service as a way to start and stop playback. Using that approach will mean that every time you want to start a new stream, the code will be slowed down even more by having to bring up a new Service. You can save some time by just having the same Service play everything. Though that doesn't mean it should remain running all the time.
To accomplish that (and to be able to pause), you'll need to bind to the Service after it is started. With the bound Service, you'll be able to make calls to it - such as pause, play, stop, etc.
Here are some links that should help you with what you're looking for:
Using a Service with MediaPlayer
Binding to a Service

Related

why android service is stopped by Android OS?

OK, here is my code, I'm trying to create a running service even when the app is closed.
In main activity, I have created a new button and call startMyService() to start the service as following:
public void startMyService(View view) {
Intent intent = new Intent(MainActivity.this, MyService.class);
startService(intent);
}
the Service class is simple :
public class MyService extends Service {
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e("MyService", "service is running");
final Uri uri = Settings.System.DEFAULT_RINGTONE_URI;
final Context x =(Context) MyService.this;
new Thread(new Runnable() {
#Override
public void run() {
MediaPlayer player = MediaPlayer.create(x,uri);
player.setLooping(true);
player.start();
}
}).start();
Toast.makeText(getApplicationContext(), "Service is running", Toast.LENGTH_LONG).show();
return START_STICKY;
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show();
Log.e("MyService", "service done");
}
}
Of course, I have added the service to manifest
<service android:name=".MyService" android:exported="false" android:description="#string/service_description" />
Now after running, I pressed the button to start the service, and close the activity, I supposed the music will be playing in the background but it stopped just after closing the activity.
How to solve this issue? How to make the service still running, and how to make it running again after an android OS destroying it?
I know there are too many topics about android services and START_STICKY
However, as you see this is not working in code above, why?
Note: This is not about playing music in the background, I used playing music because it is the simplest way to know when service is stopped, this is about how to make service keeps running in the background as supposed to be, for example, to do some task like tracking data changes from the server.
It's normal behavior when your application target from android O, if you want to remain your Service you should use startForgroundService with Notification. Read here
While an app is in the foreground, it can create and run both foreground and background services freely. When an app goes into the background, it has a window of several minutes in which it is still allowed to create and use services. At the end of that window, the app is considered to be idle. At this time, the system stops the app's background services, just as if the app had called the services' Service.stopSelf() methods.

ANDROID - Create Notification w/ Media Controls on Service Start

I have a MediaPlayerService, currently started when the Play/Pause Button on a ListView item is clicked. See code below (CustomListAdapter):
Intent intent = new Intent(v.getContext(),MediaPlayerService.class);
intent.putExtra("StreamLink",audio);
activity.startService(intent);
When this service is started by the code above I want to create a Notification with a Play/Stop button. The user should be able to get out of the app, be able to stop Media Playback e.g. player.stop() and start player.start(). Also when the Notification is clicked it should return the user to the MainActivity.
The code for my MediaPlayerService.java:
public class MediaPlayerService extends Service implements MediaPlayer.OnPreparedListener {
MediaPlayer mMediaPlayer = null;
public String audioStreamLink;
public int onStartCommand(Intent intent, int flags, int startId) {
// Get the Audio Streaming Link from the parsed JSON in the Main Activity
audioStreamLink = intent.getStringExtra("StreamLink");
// Instantiate MediaPlayer, set the Audio Type and acquire a wakelock, set the Media Player Data Source and Prepare.
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
mMediaPlayer.setDataSource(audioStreamLink);
} catch (IOException e) {
e.printStackTrace();
}
mMediaPlayer.setOnPreparedListener(this);
mMediaPlayer.prepareAsync();
return START_STICKY;
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
/** Called when MediaPlayer is ready */
#Override
public void onPrepared(MediaPlayer player) {
player.start();
}
#Override
public void onDestroy() {
mMediaPlayer.stop();
mMediaPlayer.reset();
if (mMediaPlayer != null) mMediaPlayer.release();
}
}
The process of getting a notification is completely documented down there in the documents, for example, see this.
To help you go through all this huge documentation these are the points :
You need to create the custom notification using a NotificationCompat.Builder
A typical music player service would start the notification using startForeground()
To add clickable buttons to the notification use addAction() when building the notifications.
Actions in Notifications are defined by PendingIntent, its a kind of normal Intent when it comes to responding to it.
When a button on the notification is clicked, the onStartCommand() is triggered with the intent you specified for that button (if you configure the intent correctly).
Each button's intent should have a different action so that you can identify the intent when it is received.
Inside the onStartCommand() you can play/pause and do other operations based on this intent's action.
Some reference I would suggest you to read :
https://developer.android.com/guide/topics/ui/notifiers/notifications.html
https://developer.android.com/guide/topics/ui/notifiers/notifications.html#Updating
https://developer.android.com/reference/android/app/Service.html#startForeground(int,android.app.Notification)
Things would have been a bit different if you were using a MediaSession to play the media.

Continuous Audio Playback despite Orientation Change

This question has been asked a few times, but none of the answers have helped me solve my problem so I'm posting my version of it.
I'm creating an app that plays a list of songs through a service. The problem is that I got a null exception error from the mediaPlayer after I rotate the device. As you can see below, I first start and then bind to my service in the onResume method. Likewise, I unbind and stop the service in the onDestroy method.
protected void onResume() {
if (playIntent == null) {
playIntent = new Intent(MainActivity.this, MediaService.class);
// if (n < 0) {
startService(playIntent);
bindService(playIntent, mediaConnection, Context.BIND_AUTO_CREATE);
Log.d("Check", "Started Service");
// }
}
super.onResume();
}
In my service, I set up the mediaPlayer in the service's onCreate method as below. I have a few things in the onStartCommand method (like creating a notification to show in the action bar). I also return Start_sticky in onStartCommand method.
Unfortunately, like I said, when I rotate the device, I get a null exception from the mediaPlayer.
Please help; I've been trying to fix this for days.
static private MediaPlayer player;
private final IBinder musicBind = new MediaBinder();
Notification notification;
private int playbackDuration;
static Uri paths[][] = new Uri[MainActivity.NUMBER_OF_ARTISTS][MainActivity.NUMBER_OF_TRACKS];
public void onCreate() {
// create the service
super.onCreate();
player = new MediaPlayer();
player.reset();
player.setLooping(true);
initMediaPlayer();
Log.d("Check", "In Service's OnCreate method");

How to run an application in background

Hi i'm trying to make an app which can be run in background and does not go to PAUSE mode.
I have read about services and tried to do that,but dint actually get how to use Service to do so.
Please help me out with services or any other way to to run an application in background.
To create a application to run in the background of other current activities, one needs to create a Service. The Service can run indefinitely (unbounded) or can run at the lifespan of the calling activity(bounded).
Please note that a Service has a different lifecycle than activities therefore have different methods. But to begin a service in the application a call to startService() which envokes the service onCreate() method and onStart() beginning running the service.
https://thenewcircle.com/s/post/60/servicesdemo_using_android_services
Source
http://thenewcircle.com/static/tutorials/ServicesDemo.zip
Music File
http://thenewcircle.com/static/tutorials/braincandy.m4a
service class extends Service{
//service methods
#Override
public void onCreate() {
Toast.makeText(this, "My Service Created", Toast.LENGTH_LONG).show();
Log.d(TAG, "onCreate");
player = MediaPlayer.create(this, R.raw.braincandy);
player.setLooping(false); // Set looping
}
#Override
public void onDestroy() {
Toast.makeText(this, "My Service Stopped", Toast.LENGTH_LONG).show();
Log.d(TAG, "onDestroy");
player.stop();
}
#Override
public void onStart(Intent intent, int startid) {
Toast.makeText(this, "My Service Started", Toast.LENGTH_LONG).show();
Log.d(TAG, "onStart");
player.start();
}
}
It works perfect, i have tested this also.
http://developer.android.com/reference/android/app/Service.html
Android: How to periodically send location to a server
keep application running in background
Pls let me know if still ur facing any problem :)
Try something like below.
The following code start new activity.
Intent intent = new Intent(MainActivity.this, AppService.class);
startService(intent);
// This function is used to hide your app
hideApp(getApplicationContext().getPackageName());
System.out.println("Inside of main");
}
private void hideApp(String appPackage) {
ComponentName componentName = new ComponentName(appPackage, appPackage
+ ".MainActivity");
getPackageManager().setComponentEnabledSetting(componentName,
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
}
So basically do your task whatever you want to do in AppService class
and in manifest file declare service class as a service not as an activity so it should be like this
<service android:name=".AppService" >
</service>

Get argument in service passed by activity.Media player.Android

please help me.I have an activity class and service class.Activity contain many buttons,so when user click it shows corresponding to button xml,and it must play corresponding sound.So i pass argument to service via putExtra,but i can't get it in service class.I get it in onStartCommand(),but it doesn't create or play it(so i don't know).How to solve this problem? Thank you.Here my code.
Activity.java
public void onClick(View arg0) {
if(arg0.getId()==R.id.Button01){
id=arg0.getId();
service = new Intent(this, MyService.class);
service.putExtra("ButtonA", id);
startService(service);
setContentView(R.layout.button_a);
}
....
Service.java
public void onCreate() {}
public int onStartCommand(Intent intent,int flags,int startId){
Toast.makeText(this, "My Service Started", Toast.LENGTH_LONG).show();
onHandleCommand(intent);
return START_STICKY;
}
private void onHandleCommand(Intent intent) {
if(button.equals(intent.getStringExtra("ButtonA"))){
player = MediaPlayer.create(this, R.raw.alma);
player.setLooping(false);
} else if(button.equals(intent.getStringExtra("ButtonAE"))){
player = MediaPlayer.create(this, R.raw.azhe);
player.setLooping(false);
}
}
Sorry I missed the point,onHandleCommand is your own method and you cannot override it.
Looks like your problem is here :
if(button.equals(intent.getStringExtra("ButtonA")))
What you passing as an extra to intent here?
What you are trying to compare?A Button and a String?

Categories

Resources