Apologize if this question has been repeated 1000 times before, but I'm stuck really and need the help :/.
[PROBLEM]
QUESTION 1: Where in the coding I need to add or change to make my background music play automatically when app starts? As it is now I can only make it play by using a START button and it also plays across my other activities which is also what I want it to do.
QUESTION 2: If I want more than one music file to be played, what should be implemented? (I know I need to create a new question for this, but just thought if it possible to combine these two into one Q, that would be easier).
.
MusicService.java
public class MyService extends Service {
MediaPlayer mediaPlayer;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
mediaPlayer = MediaPlayer.create(this, R.raw.mrkrabs);
mediaPlayer.setLooping(true);
mediaPlayer.start();
return super.onStartCommand(intent, flags, startId);
}//onStartCommand ends here
#Override
public boolean stopService(Intent name) {
return super.stopService(name);
}//stopService ends here
#Override
public void onDestroy() {
super.onDestroy();
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer = null;
}//onDestroy ends here
}//MyService ends here
.
MainActivity.java
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
Button stopMusic;
Button startMusic;
Button nextActivity;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
stopMusic = (Button) findViewById(R.id.stopMusic);
stopMusic.setOnClickListener(this);
startMusic = (Button) findViewById(R.id.startMusic);
startMusic.setOnClickListener(this);
nextActivity = (Button) findViewById(R.id.nextActivity);
nextActivity.setOnClickListener(this);
}//onCreate ends here
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.stopMusic:
stopService(new Intent(this, MyService.class));
stopMusic.setVisibility(View.GONE);
startMusic.setVisibility(View.VISIBLE);
break;
case R.id.startMusic:
startService(new Intent(this, MyService.class));
startMusic.setVisibility(View.GONE);
stopMusic.setVisibility(View.VISIBLE);
break;
case R.id.nextActivity:
startActivity(new Intent(this, NextActivity.class));
break;
}//switch ends here
}//onClick ends here
}//MainActivity ends here
.
Manifest.XML
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.musicapplication">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".MyService" />
<activity android:name=".NextActivity"></activity>
</application>
</manifest>
Mak sure you properly creating the media player, setting source, prepare/loop calls in service.
Refer this
You can use ServiceConnection in your activity and pass sources and change sources from your activity. That's what the typical music application does.
Here is the universal music player code you can refer
Related
I am running a service from my Android test app, which needs to show toast from counter value which is continuously increasing in a service.
Its starting well, and showing the toast. But, once I press back/home button to keep the app in background, the toast stops showing. When I again bring the app to foreground, again the toast started visible.
This problem happens sin Kitkat. But in JellyBeans and below, its working fine.
Here is my manifest file.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.rtrgroup.mysms"
android:installLocation="internalOnly">
<uses-sdk android:minSdkVersion="9"
android:targetSdkVersion="19"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true">
<activity
android:name="com.rtrgroup.mysms.MainActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name="com.rtrgroup.mysms.MyService"
android:enabled="true"
android:exported="true">
</service>
</application>
</manifest>
Here is my MainActivity.java file.
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public void onStart() {
Intent serviceIntent = new Intent(this, MyService.class);
startService(serviceIntent);
}
}
Here is my service code, MyService.java:
package com.rtrgroup.mysms;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.*;
import android.widget.Toast;
public class MyService extends Service {
Handler handler;
int count = 0;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
handler = new Handler();
handler.postDelayed(test, 1000);
return START_NOT_STICKY;
}
Runnable test = new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), "TOAST count = " + String.valueOf(count), Toast.LENGTH_SHORT).show();
count++;
handler.postDelayed(test, 5000);
}
};
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
So, how to make toast visible always, even the app is in background and the service is running? Please explain.
if you want to detect when the user put your app in background , override this method
#Override
public void onTrimMemory(int level) {
super.onTrimMemory(level);
switch (level) {
case ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN:
// do your magic here
break;
}
}
check the documentation http://developer.android.com/reference/android/content/ComponentCallbacks2.html#TRIM_MEMORY_UI_HIDDEN
also you can start your service in "foreground" mode for this check
Show notification from background started service
or you can show a notification instead a toast.
I have an application that I would like to have automatically start following boot completion. The following code seems overly complicated and I get erratic application starts when swiping to a neighbouring workspace.
What am I missing here? I have an activity class, a service class, as well as a broadcast receiver. Below is my code (in that order) followed by the manifest.
public class BlueDoor extends Activity implements OnClickListener{
Button btnExit;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
setContentView(R.layout.main);
btnExit = (Button) this.findViewById(R.id.ExitButton);
btnExit.setOnClickListener(this);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.ExitButton:
System.exit(0);
break;
}
}
}
service.class
public class BlueDoorStartService extends Service {
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
callIntent.setClass(this, BlueDoor.class);
startActivity(callIntent);
// do something when the service is created
}
}
broadcast receiver
public class StartBlueDoorAtBootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
Intent serviceIntent = new Intent(context, BlueDoorStartService.class);
context.startService(serviceIntent);
}
}
}
Manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.bluedoor"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="21" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<receiver
android:name=".StartBlueDoorAtBootReceiver"
android:enabled="true"
android:exported="false" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<service android:name=".BlueDoorStartService" >
</service>
<activity
android:name=".BlueDoor"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
UPDATE Solution(s), 10/22/2015:
Changing the service to:
public class BlueDoorStartService extends Service {
#Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
}
and the receiver to:
public class StartBlueDoorAtBootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// Start Service On Boot Start Up
Intent serviceIntent = new Intent(context, BlueDoorStartService.class);
context.startService(serviceIntent);
//Start App On Boot Start Up
Intent App = new Intent(context, BlueDoor.class);
App.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(App);
}
}
resulted in a working configuration using a service w/no misbehaving. However deleting the service all together and modifying the receiver thus:
public class StartBlueDoorAtBootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent App = new Intent(context, BlueDoor.class);
App.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(App);
}
}
also resulted in a functional as well as a more concise configuration that starts the application following boot completion.
Your BroadcastReceiver calls
context.startService(serviceIntent)
so the service will be created if it doesn't exist yet (which will be the case shortly after booting) and thus start the activity from its onCreate() method. So the app works, to a certain extent.
BUT when you call startService(), the system always calls the service's onStartCommand() method. You did not override that method, so the system uses the standard implementation from class android.app.Service.
As you can read on grepcode.com, the method will return a value like START_STICKY by default. This tells the system to keep the service alive until it is explicitly stopped.
In your case, I suppose the system reacted to the swiping by temporarily killing and then reanimating (= creating) the service, which in turn started your activity.
Some information on the service lifecycle can be found here.
What you can do:
Override onStartCommand() to start the activity from there instead of from onCreate(). Then use stopSelf(int) like described here
One last thing: when exiting from the activity, don't use System.exit(0) but call finish() instead, see this SO answer for "why".
I'm trying to make a simple app to test out the Services class. I want to have a button that when pressed starts a service and shows a Toast that the service has started, however, whenever I press the button the app crashes and I do not know what the problem is.
Testing Class:
public class ControllerTestingScreen extends Activity{
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_controller_test_screen);
//Set button colors to red, green, blue, and red, respectively
Button button = (Button) findViewById(R.id.testbutton);
button.getBackground().setColorFilter(0xFFFF0000, PorterDuff.Mode.MULTIPLY);
OnClickListener buttonListener = new View.OnClickListener(){
public void onClick(View arg0) {
startService(new Intent(getBaseContext(),Controller.class));
//sendSMS("PutPhoneNumberHereForTesting","WhereYouApp Text Message Test");
}
};
button.setOnClickListener(buttonListener);
}
Manifest File
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.whereyouapp"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="19" />
<activity
android:name="com.example.whereyouapp.ControllerTestingScreen"
android:label="YOLO">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name="com.example.whereyouapp.Controller"/>
</application>
</manifest>
Controller Class:
public class Controller extends Service{
private static final int POLL_INTERVAL = 1000 * 30;
public Controller(String name) {
super();
// TODO Auto-generated constructor stub
}
public int onStartCommand(Intent intent,int flags, int startId){
Toast.makeText(this, "yololo- the service class works", Toast.LENGTH_LONG).show();
return START_STICKY;
}
public void onDestroy(){
super.onDestroy();
Toast.makeText(this, "yolo- the service has stopped working", Toast.LENGTH_LONG).show();
}
}
Error that I'm getting:
logcat error: 02-23 14:10:40.187: E/AndroidRuntime(1173): java.lang.RuntimeException: Unable to instantiate service com.example.whereyouapp.Controller: java.lang.InstantiationException: can't instantiate class com.example.whereyouapp.Controller; no empty constructor
Your service does need parameterless constructor, if you define:
public Controller(String name)
then java will not automatically add parameter less one, and android needs it to instantiate your Service using startService
I can't see <application> opening tag in your manifest O_o
I don't have much experience in Android dev. Right now, i am unable to register a receiver from the onStartCommand method of a service.
In english it would be : I have two buttons (Start/Stop service) on an Activity. When I click on the Start button, I wan't to run the service which will register the BroadcastReceiver (SMS_RECEIVED). When a SMS is received, I wan't to see a log trace. But I don't see it !
It seems that I can't register my Broadcast receiver but I know that my Service is running (thanks to the logs).
In addition, I'd like to make my service, and consequently my BroadcastReceiver, persistent (if I quit the application, I want it to run in background, and even if I restart the phone).
Can anyone tell me what's wrong in my code ? ... and maybe give me help with my second question .... :)
Thanks !
Here is my code :
--- Activity : Main ---
package com.tuto.servicerunbroadcastreceiver;
import XYZ
public class Main extends Activity implements OnClickListener
{
Button bt_start;
Button bt_stop;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bt_start = (Button)findViewById(R.id.button1);
bt_start.setOnClickListener(this);
bt_stop = (Button)findViewById(R.id.button2);
bt_stop.setOnClickListener(this);
}
#Override
public void onClick(View v)
{
switch (v.getId())
{
case R.id.button1 :
{
Log.d("Button : ", "Button start");
startService(new Intent(this, svcMessage.class));
break ;
}
case R.id.button2 :
{
Log.d("Button : ", "Button stop");
stopService(new Intent(this, svcMessage.class));
break ;
}
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
--- Service : svcMessage ---
package com.tuto.servicerunbroadcastreceiver;
import XYZ;
public class svcMessage extends Service
{
private static final String ACTION_RECEIVE_SMS = "android.provider.Telephony.SMS_RECEIVED";
private BroadcastReceiver br_receiver;
#Override
public IBinder onBind(Intent arg0)
{
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
final IntentFilter filter = new IntentFilter();
filter.addAction("ACTION_RECEIVE_SMS");
Log.d("Service : ", "start");
this.br_receiver = new BroadcastReceiver()
{
#Override
public void onReceive(Context context, Intent intent)
{
Log.d("LOG : ", "onReceive");
}
};
this.registerReceiver(this.br_receiver, filter);
return (START_STICKY);
}
#Override
public void onDestroy()
{
super.onDestroy();
Log.d("Service : ", "destroy");
this.unregisterReceiver(this.br_receiver);
}
}
--- Manifest.xml ---
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tuto.servicerunbroadcastreceiver"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.tuto.servicerunbroadcastreceiver.Main"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name="com.tuto.servicerunbroadcastreceiver.svcMessage">
</service>
</application>
</manifest>
It seems you have a simple bug here:
//without ""
filter.addAction(ACTION_RECEIVE_SMS);
and don't forget add the permission:
<uses-permission android:name="android.permission.RECEIVE_SMS" />
One more thing, if you unregister the receiver in the onDestory(). you should register in onCreate() on Service.
This is an example of splash screen but facing difficulty with it as I couldn't view my MainActivity class, couldn't be able to recognize the issue.Tried in manifest file by changing the action and the category name as well but could not be able to resolve to it.
Basically changed my Intent intent = new Intent(); as well but still the same goes on.
public class SplashActivity extends Activity
{
MediaPlayer player;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
player = MediaPlayer.create(SplashActivity.this, R.raw.splash);
player.start();
Thread timer = new Thread()
{
#Override
public void run()
{
try
{
sleep(4000);
}catch(InterruptedException e)
{
e.printStackTrace();
}
finish();
Intent intent = new Intent();
intent.setClass(SplashActivity.this, MainActivity.class);
startActivity(intent);
stop();
}
};
timer.start();
}
#Override
protected void onPause()
{
super.onPause();
player.release();
finish();
}
}
====>And here is my manifest file --
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mainsplashcreen"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="10" />
<application
android:icon="#drawable/android_splash"
android:label="#string/app_name" >
<activity
android:name=".MainActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity android:name=".SplashActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
I would guess, that your problem is, that you finish your activity before you start the new one. If you call finish() on your activity, it will be destroyed, and so the startActivity() won't be called anymore (or if it will be called, it won't get a valid context anymore). So try to move the finish() method, at the end of your run method, that should solve the problem.
Another Very Short,Simple and Effective way of Implementing Flash Screen is as below:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
Handler handler=new Handler();
Runnable gotoMain=new Runnable() {
public void run()
{
startActivity(new Intent(SplashActivity.this, MainActivity.class));
finish();
}
};
handler.postDelayed(gotoMain, 4000);
}
You just Replace you OnCreate Method with this one.
There are a few things which you should take care of:
1. The usage of stop() and the place it is being used are not encouraged. Besides being deprecated, it will also give you UnsupportedOperationExcecption.
2. Is your MediaPlayer being initialized correctly without any errors? Check the logs.
3. What is the reason you are using finish() in onPause() method? It is not recommended.
4. You are assigning MAIN action to both your activities. While it is allowed, it should be for a specific reason.
However, all these things should not avoid your application to go to the main activity. There may be the reasons with your main activity code.