I want perform some check continuously. I have defined AsyncTask as
follows,
new AsyncTask<String, Void, String>() {
#Override
protected void onPreExecute() {
Log.d(TAG, "onPreExecute()");
}
#Override
protected String doInBackground(String... params) {
sendData(array);
return null;
}
#Override
protected void onPostExecute(String res) { }
}.execute(userResponse);
But when I terminate the application then thread stops execution.
Service class demo :-
package com.example.My Application;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.widget.Toast;
public class MyService extends Service {
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Let it continue running until it is stopped.
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
}
}
Activity :-
package com.example.My Application;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.content.Intent;
import android.view.View;
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
// Method to start the service
public void startService(View view) {
startService(new Intent(getBaseContext(), MyService.class));
}
// Method to stop the service
public void stopService(View view) {
stopService(new Intent(getBaseContext(), MyService.class));
}
}
Manifest :-
Add <service android:name=".MyService" />
Related
I have a simple application with Service and AsyncTask class. When I start the service the BackgroundTask class which extends AsyncTask runs some simulate task and show some progress.
Here in the same BackgroundTask class, I can not understand why is Service service in the class constructor, and why in MyService class in the onStartCommand method BackgroundTask constructor accepts this as an argument.
MainActivity class:
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
private Button btnStartService;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnStartService = findViewById(R.id.btnStartService);
btnStartService.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(getApplicationContext(), MyService.class);
startService(intent);
}
});
}
}
MyService class:
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.widget.Toast;
public class MyService extends Service {
private static final int TASK_COUNT = 3;
private boolean serviceOn = false;
public MyService() {
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (!serviceOn){
Toast.makeText(this, "Service starting...", Toast.LENGTH_SHORT).show();
BackgroundTask backgroundTask = new BackgroundTask(this);
backgroundTask.execute(TASK_COUNT);
serviceOn = true;
}else{
Toast.makeText(this, "Service has already started...", Toast.LENGTH_SHORT).show();
}
return START_STICKY;
}
#Override
public void onDestroy() {
Toast.makeText(this, "Service stoped", Toast.LENGTH_SHORT).show();
super.onDestroy();
}
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
}
BackgroundTask class:
import android.app.Service;
import android.os.AsyncTask;
import android.widget.Toast;
public class BackgroundTask extends AsyncTask<Integer, Integer, String> {
private Service service;
public BackgroundTask(Service service) {
this.service = service;
}
#Override
protected String doInBackground(Integer... integers) {
int taskCount = integers[0];
for (int i = 0; i < taskCount;i++){
performLongTask();
publishProgress((int) ((i+1) / (float) taskCount * 100));
}
String result = taskCount + " "+service.getString(R.string.finished);
return result;
}
private void performLongTask() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
#Override
protected void onProgressUpdate(Integer... values) {
String text = values[0] + "% " + service.getResources().getString(R.string.finished);
Toast.makeText(service, text, Toast.LENGTH_SHORT).show();
}
#Override
protected void onPostExecute(String s) {
Toast.makeText(service, s+" mark", Toast.LENGTH_SHORT).show();
service.stopSelf();
}
}
QUESTIONS:
What is a meaning of "Service service" in BackgroundTask class constructor, and why this class accepts "this" as an argument in onStartCommand method from MyService class?
Can I instead of "Service service" in BackgroundTask class use "Context context" or some combination with "Service service" because of service needs for stopSelf method?
How can I manage to reference a string resource with service in BackgroundTask class
with this code: "service.getString(R.string.finished);"?
In you use case I don't think you need "MyService" to start with. Simply use AsyncTask will do. Especially "MyService" still runs on UI thread so I don't see a point of wrapping AsyncTask with a Service.
Plus don't pass Context/Service/Activity to AsyncTask as this forms an explicit reference and may cause memory leak.
That's my MainActivity.
package com.example.simeon.cookingbook.activities;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.KeyEvent;
import com.example.simeon.cookingbook.R;
import com.example.simeon.cookingbook.services.BackgroundMusic;
public class MainActivity extends AppCompatActivity {
Intent srv;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.srv = new Intent(this, BackgroundMusic.class);
startService(srv);
}
#Override
protected void onDestroy() {
super.onDestroy();
stopService(srv);
}
#Override
protected void onPause() {
super.onPause();
stopService(srv);
}
#Override
protected void onStop() {
super.onStop();
stopService(srv);
}
#Override
protected void onRestart() {
super.onRestart();
startService(srv);
}
#Override
protected void onResume() {
super.onResume();
startService(srv);
}
}
That's BackgroundMusic Service.
package com.example.simeon.cookingbook.services;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.IBinder;
import com.example.simeon.cookingbook.R;
public class BackgroundMusic extends Service {
private static final String TAG = null;
public MediaPlayer player;
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
player = MediaPlayer.create(this, R.raw.background);
player.setLooping(true); // Set looping
player.setVolume(100,100);
}
public int onStartCommand(Intent intent, int flags, int startId) {
player.start();
return START_STICKY;
}
}
I have other activities and I want the music to be heard when my application is opened, but when it goes to background, I don't want music to continue playing. I tried with BaseActivityClass and have read a lot, but still no solution. Please help, thank you in advance.
When you are done using MediaPlayer you need to release it with the release() method. I guess the onDestroy() method of you Service is a good place for that:
public class BackgroundMusic extends Service {
private static final String TAG = null;
public MediaPlayer player;
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
player = MediaPlayer.create(this, R.raw.background);
player.setLooping(true); // Set looping
player.setVolume(100,100);
}
public int onStartCommand(Intent intent, int flags, int startId) {
player.start();
return START_STICKY;
}
public int onDestroy() {
player.release();
}
}
I like to exit my application immediately after starting a service.
The code below causes the activity to finish before the service is started.
How do I set a listener to prompt me when the service is started?
btn = (ImageButton) findViewById(R.id.button );
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startService(new Intent(MainActivity.this, MyService.class));
//I want to exit the activity here.
finish(); // this exits the activity before the service is started
}
});
The following are the codes I used, based on the proposal by #Er.Arjunsaini
on the ACTIVITY file, I register to listen for an "Exit App" broadcast.
private final BroadcastReceiver exitAppReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//activity exits when "exit app" broadcast received.
finish();
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//REGISTER TO LISTEN FOR THE BROADCAST
LocalBroadcastManager.getInstance(this).
registerReceiver(exitAppReceiver, new IntentFilter(getString(R.string.exit_app)));
btn = (ImageButton) findViewById(R.id.my_button);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startService( new Intent(this, MyService.class));
}
});
}
#Override
public void onDestroy() {
//UNREGISTER THE RECEIVER
LocalBroadcastManager.getInstance(this).
unregisterReceiver(exitFloatingWindowReceiver);
super.onDestroy();
}
on the SERVICE file, I send an "Exit APP" broadcast.
#Override
public void onCreate() {
super.onCreate();
//... do the rest of the Service initializing
//CLOSE ACTIVITY
LocalBroadcastManager.getInstance(this).
sendBroadcast(new Intent(getString(R.string.exit_app)));
}
check out ServiceConnection, onServiceConnected may be method you are looking for to call finish()
HERE you have example
If you use bindService() instead of startService(), you can use the Message based communication system between Activity and Service.
This is explained in this reference.
At the end of the section there's a link to sample classes:
-MessengerService.java
-MessengerServiceActivities.java
Here an example of an Activity with 2 button, one for starting the Service and one for sending a message to the Service that will resend a message to the Activity to close it.
MainActivity.java
package com.pasquapp.brodcasttest01;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.view.View;
import android.widget.Button;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
public final static int WHAT_CLOSE_ACTIVITY=1;
private Button startServiceButton;
private Button closeButton;
private Messenger activityMessenger;
private Messenger serviceMessenger;
private MyServiceConnection serviceConnection;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
activityMessenger =new Messenger(new ActivityHandler());
initView();
}
#Override
protected void onDestroy() {
super.onDestroy();
if(serviceConnection!=null)
unbindService(serviceConnection);
}
private void initView(){
startServiceButton=findViewById(R.id.button_start_service);
startServiceButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startService();
}
});
closeButton=findViewById(R.id.button_close);
closeButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(serviceMessenger!=null){
Message msg=Message.obtain();
msg.replyTo=activityMessenger;
msg.what=MyService.WHAT_CLOSE_ACTIVITY;
try {
serviceMessenger.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
});
}
private class MyServiceConnection implements ServiceConnection{
#Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
serviceMessenger=new Messenger(iBinder);
}
#Override
public void onServiceDisconnected(ComponentName componentName) {
serviceMessenger=null;
}
}
private void startService(){
serviceConnection=new MyServiceConnection();
bindService(new Intent(this,MyService.class),serviceConnection,BIND_AUTO_CREATE);
}
private class ActivityHandler extends Handler{
#Override
public void handleMessage(#NonNull Message msg) {
int what=msg.what;
switch (what){
case WHAT_CLOSE_ACTIVITY:
MainActivity.this.finish();
break;
default:
super.handleMessage(msg);
}
}
}}
MyService.java
package com.pasquapp.brodcasttest01;
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import androidx.annotation.NonNull;
public class MyService extends Service {
public static final int WHAT_CLOSE_ACTIVITY=1;
private Messenger mMessenger;
public MyService() {
}
#Override
public void onCreate() {
super.onCreate();
mMessenger=new Messenger(new ServiceHandler());
}
#Override
public IBinder onBind(Intent intent) {
return mMessenger.getBinder();
}
private class ServiceHandler extends Handler{
#Override
public void handleMessage(#NonNull Message msg) {
int what=msg.what;
switch (what){
case WHAT_CLOSE_ACTIVITY:
Messenger messenger=msg.replyTo;
Message closeMsg=Message.obtain();
closeMsg.what=MainActivity.WHAT_CLOSE_ACTIVITY;
try {
messenger.send(closeMsg);
} catch (RemoteException e) {
e.printStackTrace();
}
break;
default:
super.handleMessage(msg);
}
}
}
}
I'm supposed to add a timer to my service class that prints a message to LogCat every 10 seconds. Nothing in the service class is printing once I call the startService method and I have no idea why.. Any ideas?
package com.murach.reminder;
import android.content.Intent;
import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
public class ReminderActivity extends Activity implements OnClickListener {
private Button startServiceButton;
private Button stopServiceButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_reminder);
startServiceButton = (Button) findViewById(R.id.startServiceButton);
stopServiceButton = (Button) findViewById(R.id.stopServiceButton);
startServiceButton.setOnClickListener(this);
stopServiceButton.setOnClickListener(this);
}
#Override
public void onClick(View v) {
Intent serviceIntent = new Intent(this, ReminderService.class);
switch (v.getId()) {
case R.id.startServiceButton:
// put code to start service and display toast here
startService(serviceIntent);
Toast.makeText(this, "Service started", Toast.LENGTH_SHORT).show();
break;
case R.id.stopServiceButton:
// put code to stop service and display toast here
stopService(serviceIntent);
Toast.makeText(this, "Service stopped", Toast.LENGTH_SHORT).show();
break;
}
}
}
package com.murach.reminder;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
import java.util.Timer;
import java.util.TimerTask;
public class ReminderService extends Service
{
private Timer timer;
public void onCreate()
{
Log.d("Reminder", "Service created");
startTimer();
}
#Override
public IBinder onBind(Intent intent)
{
Log.d("Reminder", "No binding for this activity");
return null;
}
public void onDestroy()
{
Log.d("Reminder", "Service destroyed");
stopTimer();
}
private void startTimer() {
TimerTask task = new TimerTask() {
public void run() {
Log.d("Reminder", "Timer task executed");
}
};
timer = new Timer(true);
int delay = 1000 * 10;
int interval = 1000 * 10;
timer.schedule(task, delay, interval);
}
private void stopTimer()
{
if (timer != null)
{
timer.cancel();
}
}
}
And here is how I register the service in the Manifest (in a service element, it wouldn't let me type it out completely)
android:name="com.murach.reminder.ReminderService"
The package names do not match. There is a spelling mistake in the word murach in your Manifest declaration.
I am having a problem with setting the onStart method in my app. It always has a strikethrough, saying "This method was deprecated in API level 5. I need onStart, not onStartCommand.
How can I resolve this?
MyNotificationService.java
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.widget.Toast;
public class MyNotificationService extends Service {
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
Toast.makeText(this, "OnCreate()", Toast.LENGTH_SHORT).show();
}
#Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Toast.makeText(this, "OnDestroy()", Toast.LENGTH_SHORT).show();
}
#Override
#Deprecated
public void onStart(Intent intent, int startId) {
// TODO Auto-generated method stub
super.onStart(intent, startId);
}
}
Reminder_2.java
import android.media.MediaPlayer;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.view.Window;
import android.widget.DatePicker;
import android.widget.ImageButton;
public class Reminder_2 extends Activity {
String message;
DatePicker datepicker;
#Override
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_reminder_2);
datepicker=(DatePicker)findViewById(R.id.datePicker1);
Home();
Next();
Save();
}
private void Next() {
final MediaPlayer button_tone = MediaPlayer.create(this, R.raw.button_sound);
ImageButton Button = (ImageButton) findViewById(R.id.imageButton1);
View.OnClickListener myListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
button_tone.start();
finish();
}
};
Button.setOnClickListener(myListener);
}
private void Save() {
final MediaPlayer button_tone = MediaPlayer.create(this, R.raw.button_sound);
ImageButton Button = (ImageButton) findViewById(R.id.imageButton3);
View.OnClickListener myListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
button_tone.start();
Intent intent = new Intent();
intent.setClass(getApplicationContext(), MyNotificationService.class);
startService(intent);
}
};
Button.setOnClickListener(myListener);
}
private void Home() {
final MediaPlayer button_tone = MediaPlayer.create(this, R.raw.button_sound);
ImageButton Button = (ImageButton) findViewById(R.id.imageButton2);
View.OnClickListener myListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
button_tone.start();
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
}
};
Button.setOnClickListener(myListener);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.reminder, menu);
return true;
}
}
Use onStartCommand().
It you want to know more about how they change it, refer to google documentation like below.
// This is the old onStart method that will be called on the pre-2.0
// platform. On 2.0 or later we override onStartCommand() so this
// method will not be called.
#Override
public void onStart(Intent intent, int startId) {
handleStart(intent, startId);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
handleStart(intent, startId);
return START_NOT_STICKY;
}
You can use like this with onStartCommand().
package htin.linnzaw.service;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.IBinder;
import android.widget.Toast;
public class MyService extends Service
{
private MediaPlayer mediaplayer;
public MyService()
{
}
#Override
public IBinder onBind(Intent intent)
{
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public void onCreate()
{
Toast.makeText(this, "Service created", Toast.LENGTH_SHORT).show();
mediaplayer = MediaPlayer.create(this, R.raw.eventually);
mediaplayer.setLooping(false);
}
#Override
public int onStartCommand(Intent intent, int flags, int startid)
{
Toast.makeText(this, "Service Started", Toast.LENGTH_SHORT).show();
mediaplayer.start();
return startid;
}
#Override
public void onDestroy()
{
Toast.makeText(this, "Service stopped", Toast.LENGTH_SHORT).show();
mediaplayer.stop();
}
}