Here I tried simple service program. Start service works fine and generates Toast but stop service does not. The code of this simple service is as below:
public class MailService extends Service {
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
public void onCreate(){
super.onCreate();
Toast.makeText(this, "Service Started", Toast.LENGTH_SHORT).show();
}
public void onDestroyed(){
Toast.makeText(this, "Service Destroyed", Toast.LENGTH_SHORT).show();
super.onDestroy();
}
}
The code of the Activity from where this Service is called is as below:
public class ServiceTest extends Activity{
private Button start,stop;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.service_test);
start=(Button)findViewById(R.id.btnStart);
stop=(Button)findViewById(R.id.btnStop);
start.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
startService(new Intent(ServiceTest.this,MailService.class));
}
});
stop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
stopService(new Intent(ServiceTest.this,MailService.class));
}
});
}
}
Help me to stop service with that stop button which generates toast in the onDestroy() method. I have already seen many posts regarding stop service problem here, but not satisfactory so posting new question. Hope for satisfactory answer.
onDestroyed()
is wrong name for
onDestroy()
Did you make a mistake only in this question or in your code too?
This code works for me: check this link
This is my code when i stop and start service in activity
case R.id.buttonStart:
Log.d(TAG, "onClick: starting srvice");
startService(new Intent(this, MyService.class));
break;
case R.id.buttonStop:
Log.d(TAG, "onClick: stopping srvice");
stopService(new Intent(this, MyService.class));
break;
}
}
}
And in service class:
#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();
}
HAPPY CODING!
To stop the service we must use the method stopService():
Intent myService = new Intent(MainActivity.this, BackgroundSoundService.class);
//startService(myService);
stopService(myService);
then the method onDestroy() in the service is called:
#Override
public void onDestroy() {
Log.i(TAG, "onCreate() , service stopped...");
}
Here is a complete example including how to stop the service.
Related
I built app to play audio from internet, I use service to play audio in background, the question is how to show loding dialog while media player is in preparing posision in service(background) hire my Code.
Activity
package com.uqifm.onlineradio;
.......
public class MainActivity extends AppCompatActivity {
Button b_play;
Boolean started = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
b_play = (Button) findViewById(R.id.b_play);
b_play.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(started){
started = false;
stopService(new Intent(MainActivity.this,MyService.class));
b_play.setText("PLAY");
}else{
started = true;
startService(new Intent(MainActivity.this,MyService.class));
b_play.setText("STOP");
}
}
});
}
#Override
protected void onDestroy() {
super.onDestroy();
stopService(new Intent(MainActivity.this,MyService.class));
}
}
Service
package com.uqifm.onlineradio;
....................
public class MyService extends Service {
MediaPlayer mediaPlayer;
String stream = "http://xxxxx:36365";
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
mediaPlayer.setDataSource(stream);
mediaPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
mediaPlayer.start();
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy() {
mediaPlayer.release();
}
}
Register broadcasts, Start a ProgressDialog before you start the service. Then wait for the broadcast. After the broadcast, hide the dialog. see example in this thread. Send data from Service back to my activity
Put a ProgressDialog in xml and set the visibility according to your requirement. Use interface for communicating with service.
You can use Broadcast or try EventBus which is much more easier. You can post an event from the service using EventBus and receive the the broadcast in MainActivity and update the progress dialogue.
Please follow the link.
Maybe something like this:
fun playAudio(audioUrl: String){
showProgressBar()
var mediaPlayer: MediaPlayer? = MediaPlayer().apply {
setAudioStreamType(AudioManager.STREAM_MUSIC)
setDataSource(audioUrl)
prepareAsync() // might take long! (for buffering, etc)
}
mediaPlayer?.setOnPreparedListener {
hideProgressBar()
it.start()
}
mediaPlayer?.setOnCompletionListener {
mediaPlayer.release()
}
}
So I have created a webservice call class that calls my webservice which extends on AsyncTask:
public class WebServiceLoginCall extends AsyncTask{
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
}
protected void onPostExecute(Void result) {
try {
if(loginStatus){
System.out.println("onpost has been executed");
//Navigate to Home Screen
loginIntent = new Intent(getBaseContext(), HomeActivity.class);
startActivity(loginIntent);
//prevents user to go back to the login screen
finish();
}else{
//Set Error message
Toast.makeText(getApplicationContext(), "Login Failed. Check your details.", Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
Toast.makeText(getApplicationContext(), "An error occured. Check your mobile connection.", Toast.LENGTH_SHORT).show();
}
}
#Override
protected Boolean doInBackground(Object... arg0) {
System.out.println("doinbackground triggered");
try {
loginStatus = Webservice.invokeLoginWS(loginUser.get_userEmail(), loginUser.get_userPassword());
} catch (Exception e) {
System.out.println("an error occured with the webservice");
}
return loginStatus;
}
}
When the user presses the login button, I use the following code:
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnLogin:
email = (EditText) findViewById(R.id.txtEmail);
loginUser = new User();
loginUser.set_userEmail(email.getText().toString());
loginUser.set_userPassword(password.getText().toString());
//starts loging webservice
WebServiceLoginCall task = new WebServiceLoginCall();
//executes the login task
task.execute();
break;
When I check, the doInBackground is triggered in my console, but the onPostExecute is not. Is there anything that I am doing wrong? The doInBackground does not throw any exceptions.
Make following two changes
1.Use public class WebServiceLoginCall extends AsyncTask<Void, Void, Boolean >
instead of public class WebServiceLoginCall extends AsyncTask
2.Use
#Override
protected void onPostExecute(Void result) {
// your code
}
instead of just
protected void onPostExecute(Void result) {
// your code
}
Refer Android- Async task
Explanation:
In your case if you put #Override on onPostExecute() without extending the generic Asynctask, you will get a compile time error. Hence you will have to make above two changes.
hope it helps you.
because you are calling a different method your post execute wont execute ever execute if you defined it like your code
use
#Override
protected void onPostExecute(boolean result) {
}
Because your not Override the onPostExecute() method
add : #Override
like this
#Override
protected void onPostExecute(Void result) {
try {
if(loginStatus){
System.out.println("onpost has been executed");
//Navigate to Home Screen
loginIntent = new Intent(getBaseContext(), HomeActivity.class);
startActivity(loginIntent);
//prevents user to go back to the login screen
finish();
}else{
//Set Error message
Toast.makeText(getApplicationContext(), "Login Failed. Check your details.", Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
Toast.makeText(getApplicationContext(), "An error occured. Check your mobile connection.", Toast.LENGTH_SHORT).show();
}
}
1) Add the #Override to your postexecute
2) If your asynctask takes parameter then execute your asynctask like this:
task.execute(Object);
because your AsyncTask takes Object
#Override
protected Boolean doInBackground(Object... arg0)
3) Your doInBackground returns a Boolean loginStatus value but your onPostExecute(Void result) takes in void.
Hope it helps
I am creating application which contains service that suppose to listen to calls,
and pop up an alert dialog after call has ended, the issue is, that as long as the activity running or in the background, the service works and the dialog pop up, but when I close the activity, the dialog wont pop up, as like the listener will not listen anymore to calls.
need help please!
this is how I call the service from my activity:
public void onClick(View v) {
switch (v.getId()) {
case R.id.start:
startService(new Intent(getBaseContext(), PhoneService.class));
break;
case R.id.stop:
stopService(new Intent(getBaseContext(), PhoneService.class));
break;
}
}
the service class:
public class PhoneService extends Service {
private static String TAG = "SERVICE";
int currentState;
Context context;
String incomingNumber;
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
// starts the service
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "FirstService started");
context = this;
TelephonyManager telephony = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE); // TelephonyManager
// object
CallListener listener = new CallListener();
telephony.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);
// keeps the service going until explicitly stops
return START_STICKY;
}
#Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Log.i(TAG, "FirstService destroyed");
}
the listener class:
public class CallListener extends PhoneStateListener {
#Override
public void onCallStateChanged(int state, String incomingNumber) {
if (TelephonyManager.CALL_STATE_RINGING == state) {
// Incoming call handling
Log.i(TAG, " ring ring ring" + incomingNumber);
currentState = state;
}
if (TelephonyManager.CALL_STATE_OFFHOOK == state) {
// Outgoing call handling and answer
Log.i(TAG, " ofhook" + incomingNumber);
currentState = state;
}
if (TelephonyManager.CALL_STATE_IDLE == state) {
// Device back to normal state (not in a call)
Log.i(TAG, " idle" + incomingNumber);
if (currentState == TelephonyManager.CALL_STATE_OFFHOOK) {
Toast.makeText(context,"phone number dialed is "+ PhoneService.this.incomingNumber,Toast.LENGTH_SHORT).show();
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setMessage("Who is this person?").setCancelable(false).setPositiveButton("1",new DialogInterface.OnClickListener() {
public void onClick(
DialogInterface dialog, int id) {
}
})
.setNegativeButton("0",
new DialogInterface.OnClickListener() {
public void onClick(
DialogInterface dialog, int id) {
}
});
AlertDialog alert = builder.create();
alert.getWindow().setType(
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
alert.show();
}
currentState = state;
}
}
}
Change your service to derive from IntentService and remove the overrides for onBind and onStartCommand (let the system handle those).
Put your code in the onHandleIntent override.
The different service types are handled differently - a bound service only operates while the activity is running, but an intent service can be started at any time. You can read more about service types here.
I'm having trouble STOPPING the StimulationService , I'm not sure if i'm calling the stopservice method correctly from my activity.
Any help will be much appreciated.
Activity to start and stop Service
public class Stimulation extends Activity implements OnClickListener {
private static final String TAG = "StimulationActivity";
Button buttonStart, buttonStop;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(com.someapp.Activities.R.layout.stimulation);
buttonStart = (Button) findViewById(com.someapp.Activities.R.id.ButtonStart);
buttonStop = (Button) findViewById(com.someapp.Activities.R.id.ButtonStop);
buttonStart.setOnClickListener(this);
buttonStop.setOnClickListener(this);
}
public void onClick(View src) {
switch (src.getId()) {
case com.someapp.Activities.R.id.ButtonStart:
Log.d(TAG, "onClick: starting service");
startService(new Intent(this, StimulationService.class));
break;
case com.someapp.Activities.R.id.ButtonStop:
Log.d(TAG, "onClick: stopping service");
stopService(new Intent(this, StimulationService.class));
break;
}
}
}
}
Service
public class StimulationService extends Service {
private static final String TAG = "StimulationService";
private IOIO ioio_;
private DigitalOutput led
private volatile IOIOThread ioio_thread_;
public IBinder onBind(Intent intent) {
return null;
}
public void onCreate() {
Toast.makeText(this, "My Service Created", Toast.LENGTH_LONG).show();
Log.d(TAG, "onCreate");
}
public void onDestroy() {
Toast.makeText(this, "My Service Stopped", Toast.LENGTH_LONG).show();
Log.d(TAG, "onDestroy");
ioio_thread_.stop();
}
public void onStart(Intent intent, int startid) {
Toast.makeText(this, "My Service Started", Toast.LENGTH_LONG).show();
Log.d(TAG, "onStart");
ioio_thread_ = new IOIOThread();
ioio_thread_.start();
}
public void onStop(Intent intent, int stopid) {
Log.d(TAG, "stop()");
ioio_thread_ = null;
}
class IOIOThread extends Thread {
private IOIO ioio_;
private DigitalOutput led;
/** Thread body. */
public void run() {
Thread thisThread = Thread.currentThread();
super.run();
while (ioio_thread_ == thisThread) {
ioio_ = IOIOFactory.create();
try{
Log.d(TAG, "Wait for IOIO Connection");
ioio_.waitForConnect();
Log.d(TAG, "IOIOConnected");
while (true) {
intializePins();
Log.d(TAG, "Pins Intialized");
while(true){
led.write(false);
sleep(2000);
led.write(true);
sleep(2000);
}
}
}
catch (ConnectionLostException e) {
} catch (Exception e) {
Log.e("Hello", "Unexpected exception caught", e);
ioio_.disconnect();
break;
} finally {
try {
ioio_.waitForDisconnect();
} catch (InterruptedException e) {
}
}
}
}
}
First, as #Waqas notes, there is no onStop() method. There is an onDestroy() method, which will be called after stopService() is called.
Second, you are not stopping the background thread ever. Simply setting the ioio_thread_ data member to null does not stop the thread. That thread will keep running forever. Please do not do this. If nothing else, use an AtomicBoolean instead of a hardwired true in your while() loop, and flip that AtomicBoolean to false in onDestroy().
Your activity is OK. The problem is that the service is not killing the IOIOThread.
Thread.stop() is deprecated and will not do what you want anyway.
What you want is to call ioio_.disconnect() from the service's onStop() (through a method on your thread class), and then join() the thread.
See AbstracIOIOActivity as an example. With minor modifications it can be turned into AbstractIOIOService, and will enable you to leave you application-specific logic in a subclass.
I create a security application just like Mcafee wave secure.
My application is listening for SMS command and doing some action when the command is match, so I create a form with another service for listening the SMS.
Here's the main form:
public static final String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
ArrayList<String> messageList;
ArrayAdapter< String> adapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//untuk mendisable notification area
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.main);
MainButtonAbout=(Button) findViewById(R.id.MainbuttonAbout);
MainButtonHelp=(Button) findViewById(R.id.MainbuttonHelp);
MainButtonWizard=(Button) findViewById(R.id.MainbuttonWizard);
MainButtonOption=(Button) findViewById(R.id.MainbuttonOption);
MainCheckBoxActive=(CheckBox)findViewById(R.id.MaincheckBoxActive);
MainButtonAbout.setOnClickListener(this);
MainButtonHelp.setOnClickListener(this);
MainButtonWizard.setOnClickListener(this);
MainButtonOption.setOnClickListener(this);
startService(new Intent(MainForm.this, ListenSMSservice.class));
MainCheckBoxActive.setOnCheckedChangeListener(new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// TODO Auto-generated method stub
if (buttonView.isChecked())
{
Toast.makeText(MainForm.this, "Your Device is Protected Now!!", 1).show();
startService(new Intent(MainForm.this, ListenSMSservice.class));
}
else
{
Toast.makeText(MainForm.this, "Your Device is not Protected Now!!", 1).show();
stopService(new Intent(MainForm.this, ListenSMSservice.class));
}
}
});
}
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.MainbuttonAbout:
Intent GoToAbout= new Intent(this,AboutForm.class);
startActivity(GoToAbout);
break;
case R.id.MainbuttonHelp:
Intent GoToHelp= new Intent(this,HelpForm.class);
startActivity(GoToHelp);
break;
case R.id.MainbuttonWizard:
Intent GoToWizard1= new Intent(this,WizardForm1.class);
startActivity(GoToWizard1);
break;
case R.id.MainbuttonOption:
Intent GoToOption= new Intent(this,OptionForm.class);
startActivity(GoToOption);
break;
default:
break;
}
}
and this is the Service form:
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
Toast.makeText(this, "My Service Created", Toast.LENGTH_LONG).show();
}
/*#Override
public void onStart(Intent intent, int startid) {
Toast.makeText(this, "My Service Started", Toast.LENGTH_LONG).show();
ListenSMS();
}*/
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
ListenSMS();
// We want this service to continue running until it is explicitly
// stopped, so return sticky.
return START_STICKY;
}
private void ListenSMS() {
// TODO Auto-generated method stub
messageList = new ArrayList<String>();
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, messageList);
//Toast.makeText(this, "Masuk bagian sini sudah", 1).show();
IntentFilter filter = new IntentFilter(SMS_RECEIVED);
registerReceiver(receiver_SMS, filter);
}
BroadcastReceiver receiver_SMS = new BroadcastReceiver()
{
public void onReceive(Context context, Intent intent)
{
if (intent.getAction().equals(SMS_RECEIVED))
{
Bundle bundle = intent.getExtras();
if (bundle != null)
{
Object[] pdus = (Object[]) bundle.get("pdus");
SmsMessage[] messages = new SmsMessage[pdus.length];
for (int i = 0; i < pdus.length; i++)
messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
for (SmsMessage message : messages)
{
Toast.makeText(ListenSMSservice.this, "isi pesan >> "+message.getDisplayMessageBody(), Toast.LENGTH_LONG).show();
receivedMessage(message.getDisplayOriginatingAddress());
if (message.getDisplayMessageBody().toString().equalsIgnoreCase("aaaa"))
{
Toast.makeText(ListenSMSservice.this, "messegenya aaaa", 1).show();
}
}
}
}
}
};
private void receivedMessage(String message)
{
messageList.add(message);
adapter.notifyDataSetChanged();
}
#Override
public void onDestroy() {
Toast.makeText(this, "My Service Stopped", Toast.LENGTH_LONG).show();
}
Unfortunately, my service can be stopped by Advanced task killer, so I can't listen for the SMS command.
I'm using start_sticky option, but it does not work for me.
Does anyone have an idea how to handle that problem, so I can listen to the SMS (auto started service) even when task killer was used to kill my application?
anyone have idea how to handle that problem, so i can listen to the SMS (auto started service) while task killer have killed my application
If the user force-stops your application via Settings or a task killer, the user is saying that your app is not supposed to run. Please honor and respect that decision.
As of Android 3.1, your application will not run again after being force-stopped, until the user launches it again from an activity.
Register a <reciver> in the manifest and it will start your app when you receive a SMS
<receiver android:name=".YourBroadCastReciver" android:enabled="true">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>