Loading sound once for all the activity - android

Iam trying to use soundpool to play sound in my android app. I have 3 activities where i have to play sound. So can i load sounds globally once only when application starts?? Can i make a global class and load all the sound once and use them in other activities.

You can try this example
//start service
Intent svc=new Intent(this, BackgroundSoundService.class);
startService(svc);
//Add in manifest file
<service
android:enabled="true"
android:name="com.package.name.BackgroundSoundService" />
public class BackgroundSoundService extends Service {
private static final String TAG = null;
MediaPlayer player;
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
player = MediaPlayer.create(this, R.raw.idil);
player.setLooping(true); // Set looping
player.setVolume(100,100);
}
public int onStartCommand(Intent intent, int flags, int startId) {
player.start();
return 1;
}
public void onStart(Intent intent, int startId) {
// TO DO
}
public IBinder onUnBind(Intent arg0) {
// TO DO Auto-generated method
return null;
}
public void onStop() {
}
public void onPause() {
}
#Override
public void onDestroy() {
player.stop();
player.release();
}
#Override
public void onLowMemory() {
}
}

Yes you can load your audio in a global class. Thankfully android is providing us such class called Application.java.
public class TestApp extends Application {
private static final String TAG = "TestApp";
private static TestApp sTestApp;
private MediaPlayer mMediaPlayer;
#Override
public void onCreate() {
super.onCreate();
sTestApp = this;
mMediaPlayer = MediaPlayer.create(this, R.raw.music);
mMediaPlayer.setVolume(1, 1); //Volume should have to be between 0.0 to 1.0
}
public static TestApp getInstance() {
return sTestApp;
}
public void play() {
mMediaPlayer.start();
}
}
Then declare this as application class in your manifest
<application
android:name=".TestApp"
android:label="#string/app_name"
android:theme="#style/AppTheme">
.........
</application>
Now this class will be started automatically when your application starts and will be destroyed after your application completely destroys.
Now you can play the audio by calling
TestApp.getInstance().play();
from wherever you want.

Related

Audio will still play even if I am using other app or the screen is locked

I am creating an app similar to other audio streaming apps. Is there a way to let a third party player stream music even though the screen of the mobile phone is locked or I am using other application?
You require to create the unbound service to play the media in background while other app may be opened or screen might be lock.
You can refer this for understanding in detail regarding use of services: https://developer.android.com/guide/components/services.html
Like this:
Create Intent first
Intent svc=new Intent(this, BackgroundSoundService.class);
startService(svc);
Create class for the service to run in the background:
public class BackgroundSoundService extends Service {
private static final String TAG = null;
MediaPlayer player;
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
player = MediaPlayer.create(this, R.raw.idil);
player.setLooping(true); // Set looping
player.setVolume(100,100);
}
public int onStartCommand(Intent intent, int flags, int startId) {
player.start();
return 1;
}
public void onStart(Intent intent, int startId) {
// TO DO
}
public IBinder onUnBind(Intent arg0) {
// TO DO Auto-generated method
return null;
}
public void onStop() {
}
public void onPause() {
}
#Override
public void onDestroy() {
player.stop();
player.release();
}
#Override
public void onLowMemory() {
}
}
Do not forget to call service in manifest file
<service android:enabled="true" android:name=".BackgroundSoundService " />
Hope this helps you.

creating android service for simple radio

I've been reading a while and all about services, I'm not all in dev, I'm new to this stuff and wanna learn, as a test I'm trying to make an online radio stream app. I already made it and it works perfect, my only problem is I can't seem to find the way to make the services work or how to do so, I know most of you all are great devs on android and all but just looking for a teacher or someone willing to show me how
this is my code:
public class MainActivity extends AppCompatActivity
{
Button b_play1;
MediaPlayer mediaPlayer;
boolean prepared;
String stream = "http://73.160.214.181:8000/stream";
private boolean started;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startService(new Intent(this, mServices.class));
b_play1 = (Button) findViewById(R.id.play1);
b_play1.setEnabled(false);
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
new PlayerTask().execute(stream);
b_play1.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view) {
if (started) {
started = false;
mediaPlayer.pause();
b_play1.setBackground(getDrawable(play));
} else {
started = true;
mediaPlayer.start();
b_play1.setBackground(getDrawable(pause));
}
}
});
}
#Override
protected void onPause()
{
super.onPause();
if(started){
mediaPlayer.pause();
}
}
#Override
protected void onResume()
{
super.onResume();
if(started){
mediaPlayer.start();
}
}
#Override
protected void onDestroy()
{
super.onDestroy();
if(prepared){
mediaPlayer.release();
}
}
class PlayerTask extends AsyncTask<String, Void, Boolean>
{
#Override
protected Boolean doInBackground(String... strings) {
try {
mediaPlayer.setDataSource(strings[0]);
mediaPlayer.prepare();
prepared = true;
} catch (IOException e) {
e.printStackTrace();
}
return prepared;
}
#Override
protected void onPostExecute(Boolean aBoolean) {
super.onPostExecute(aBoolean);
b_play1.setEnabled(true);
}
}}
I wrote an Android audio chapter in my book, and in it I present an app that plays music using a background service.
So here I am going to summarize it and slightly adapt it using your code to show how you should be able to stream from background service. Instead of using the Async task in your Activity, your are going to have a mainActivity that binds to a Service that does the streaming.
First, you need to define the service in your manifest: (obviously use your package name, not mine shown below)
<application
<service
android:name="com.wickham.android.musicservice.MusicService"
android:label="Music Service"
android:enabled="true">
</service>
Then, you need to bind your Activity to the service. The Activity can be used to control the service, such as starting and stopping the stream: (the following code block go in your Main Activity, that is where you have everything now)
// Bind the Service
bindService(new Intent(this,MusicService.class), Scon,Context.BIND_AUTO_CREATE);
// Connect to Service
public void onServiceConnected(ComponentName name, IBinder binder) {
mServ = ((MusicService.ServiceBinder)binder).getServiceInstance();}
// Start the service
Intent music = new Intent();
music.setClass(this,MusicService.class);
startService(music);
// Controlling the service
mServ.resumeMusic();
mServ.pauseMusic();
Then, in your service class that will be doing the actual streaming, you can implement it like this: (I did not include the two methods called resumeMusic() and pauseMusic(), but those go in the service and do basically what you had already in your activity.
public class MusicService extends Service implements MediaPlayer.OnErrorListener{
private final IBinder mBinder = new ServiceBinder();
MediaPlayer mPlayer;
private int length = 0;
public MusicService() { }
public class ServiceBinder extends Binder {
public MusicService getServiceInstance() {
return MusicService.this;
}
}
#Override
public IBinder onBind(Intent arg0){return mBinder;}
#Override
public void onCreate () {
super.onCreate();
mPlayer = new MediaPlayer();
mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mPlayer.setOnErrorListener(this);
mPlayer.setLooping(false);
mPlayer.setVolume(100,100);
mPlayer.setOnErrorListener(new OnErrorListener() {
public boolean onError(MediaPlayer mp, int what, int extra) {
onError(mPlayer, what, extra);
return true;
}
});
}
}
Hope this can help a little bit.
create a service class like
public class MyService extends Service {
MediaPlayer mPlayer;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
Toast.makeText(this, "Service Created", Toast.LENGTH_LONG).show();
mPlayer = MediaPlayer.create(this, R.raw.laila);
mPlayer.setLooping(false); // Set looping
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
mPlayer.start();
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, "Service Stopped", Toast.LENGTH_LONG).show();
mPlayer.stop();
}
}
Add below line in your Manifest.xml file
<service android:name=".service.MyService" android:enabled="true"/>
You can start service by calling
startService(new Intent(this, MyService.class));
and stop service
stopService(new Intent(this, MyService.class));
This is the basic flow how to start and stop a service. You can read more here Service

Service background music does not turn off

In my app there is a background music, for what I have a service. It works fine, but it "keeps playing" when either I close the app or turn off the screen.
Should I change something in onPause or onStop?
My code:
public class MyService extends Service {
private final String TAG = null;
MediaPlayer player;
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
player = MediaPlayer.create(this, R.raw.id);
player.setLooping(true); // Set looping
player.setVolume(100, 100);
}
public int onStartCommand(Intent intent, int flags, int startId) {
player.start();
return 1;
}
public void onStart(Intent intent, int startId) {
// TO DO
}
public IBinder onUnBind(Intent arg0) {
// TO DO Auto-generated method
return null;
}
protected void onStop() {
player.pause();
}
public void onPause() {
player.pause();
}
#Override
public void onDestroy() {
player.stop();
player.release();
}
#Override
public void onLowMemory() {
}
}
As screen turns off your activity becomes invisible which triggers onPause followed by onStop
Screen on, on the other hand, triggers onStart followed by onResume.
when ever you want to stop service use
stopService(new Intent(ActivityName.this, ServiceClassName.class));
Probably copies of the player are created somehow. Try to make MediaPlayer variable static and then try to deallocate it after pausing onPause(). Anyway it is weird, that you are creating MediaPlayer instance in service.

Background music doesn't turn off or on when it is supposed to

I've got a service which plays background music in all of my activities, but doesn't turn off while onPause or onStop. I want my music to turn off while apps close or screen turn off, doesnt matter in which activity usesr currently is.
The problem is this:
I have a service. In every activity I coded what to do onPause and onStop. It works fine, but service also stops when I switch to another activity.
Code:
public class MyService extends Service {
private final String TAG = null;
MediaPlayer player;
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
player = MediaPlayer.create(this, R.raw.id);
player.setLooping(true); // Set looping
player.setVolume(100, 100);
}
public int onStartCommand(Intent intent, int flags, int startId) {
player.start();
return 1;
}
public void onStart(Intent intent, int startId) {
// TO DO
}
public IBinder onUnBind(Intent arg0) {
// TO DO Auto-generated method
return null;
}
protected void onStop() {
player.pause();
}
public void onPause() {
player.pause();
}
#Override
public void onDestroy() {
player.stop();
player.release();
}
#Override
public void onLowMemory() {
}
}
You will have to stop the service in the onDestroy method of your main activity. Check this answer

Android can't bind to service

New to android, trying to figure out Services. I'm trying to bind a service to an activity, I'm following the examples in the documentation, but I keep getting a NullPointerException on the line marked below(appService.playSong(title)). Checking it in the debugger reveals that appService is indeed null.
public class Song extends Activity implements OnClickListener,Runnable {
protected static int currentPosition;
private ProgressBar progress;
private TextView songTitle;
private MPService appService;
private ServiceConnection onService = new ServiceConnection() {
public void onServiceConnected(ComponentName className,
IBinder rawBinder) {
appService = ((MPService.LocalBinder)rawBinder).getService();
}
public void onServiceDisconnected(ComponentName classname) {
appService = null;
}
};
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.song);
Intent bindIntent = new Intent(Song.this,MPService.class);
bindService(bindIntent,onService,
Context.BIND_AUTO_CREATE);
Bundle b = getIntent().getBundleExtra("songdata");
String title = b.getString("song title");
// ...
appService.playSong(title); // nullpointerexception
// ...
}
Here's the relevant part of the service:
package org.example.music;
// imports
public class MPService extends Service {
private MediaPlayer mp;
public static int currentPosition = 0;
public List<String> songs = new ArrayList<String>();
public static String songTitle;
private static final String MEDIA_PATH = new String("/mnt/sdcard/");
#Override
public void onCreate() {
super.onCreate();
mp = new MediaPlayer();
songs = Music.songs;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return Service.START_STICKY;
}
public class LocalBinder extends Binder {
MPService getService() {
return MPService.this;
}
}
private final IBinder binder = new LocalBinder();
#Override
public IBinder onBind(Intent intent) {
return binder;
}
public void playSong(String songPath) {
try {
mp.reset();
mp.setDataSource(songPath);
mp.prepare();
mp.start();
mp.setOnCompletionListener(new OnCompletionListener() {
public void onCompletion(MediaPlayer arg0) {
nextSong();
}
});
songTitle = songPath.substring(12,songPath.length()-4);
} catch (IOException e) {
Log.v(getString(R.string.app_name),e.getMessage());
}
}
public void nextSong() {
if (++currentPosition >= songs.size()) {
currentPosition = 0;
}
String song = MEDIA_PATH+songs.get(currentPosition);
playSong(song);
}
public void prevSong() {
if (--currentPosition<0) {
currentPosition=songs.size()-1;
}
String song = Music.MEDIA_PATH+songs.get(currentPosition);
playSong(song);
}
public int getSongPosition() {
return mp.getCurrentPosition();
}
public MediaPlayer getMP() {
return mp;
}
}
I have registered the service in AndroidManifest.xml and set android:enabled="true". Do you see any obvious mistakes here?
There are two kinds of binds you can make local and remote. Local is only for use by your application and remote if for use by any application that implements certain interface.
You should start with local binding.
Local binding tutorial.
Remote binding tutorial.
My solution without bind:
public class MyActivity extends Activity{
#Override
public void onCreate(Bundle savedInstanceState){
...
Intent it = new Intent(MyService.ACTIVITY_START_APP);
it.setClass(getApplicationContext(), MyService.class);
startService(it);
}
...
#Override
protected void onResume() {
super.onResume();
registerBroadcastReceiver();
}
#Override
protected void onPause() {
super.onPause();
this.unregisterReceiver(this.receiver);
}
...
private BroadcastReceiver receiver = new BroadcastReceiver(){
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(MyService.BROADCAST_INIT)) {
//do your stuff here after init
}
}
};
private void registerBroadcastReceiver(){
IntentFilter filter = new IntentFilter();
filter.addAction(HMyService.BROADCAST_INIT);
this.registerReceiver(receiver, filter);
}
}
Your service:
public class MyService extends Service{
public static final String BROADCAST_INITIAL_DATA = "org.myapp.BROADCAST_INIT";
public static final String ACTIVITY_START_APP = "org.myapp.ACTIVITY_START_APP";
#Override
public int onStartCommand (Intent intent, int flags, int startId){
super.onStartCommand(intent, flags, startId);
if(intent.getAction().equals(ACTIVITY_START_APP)){
//do your initialization
//inform the client/GUI
Intent i = new Intent();
i.setAction(BROADCAST_INIT);
sendBroadcast(i);
}else{
//some other stuff like handle buttons
}
}
}
good luck.
You are assuming that the bindService() will connect to the service synchronously, but the connection will be available only after onCreate() finshed.
The framework runs onCreate() on the UI thread and bindService() just makes a note to connect to the service later. Connecting to a service will always be done on the UI thread, so this can only happen after onCreate was executed. You can't even count on the connection being set up right after onCreate(). It will happen sometime after that :). Also, the framework might disconnect the service on it's will, though it should only happen in low memory conditions.
So, move the code which works with appService from onCreate() to onServiceConnected() and it's gonna work.
From a quick glance it looks like you are trying to access your service before the binding has completed. You have to make sure onServiceConnected has fired before trying to call any methods on your service.
Example:
Intent bindIntent = new Intent(Song.this,MPService.class);
bindService(bindIntent,onService, Context.BIND_AUTO_CREATE);
//Wait until service has bound
while(appService == null){
Thread.sleep(100);
}
appService.playSong(title);
This example isn't the best but it demonstrates that you have to wait until the binding has completed before trying to access the service.

Categories

Resources