I am using this broadcast service with countdown timer. But when i kill the app, it is not ticking on same time(second), it is starts again.
Here is my code.
BroadcastService:
package com.example.emre.denemeprojesi;
import android.app.Service;
import android.content.Intent;
import android.os.CountDownTimer;
import android.os.IBinder;
import android.util.Log;
public class BroadcastService extends Service {
private final static String TAG = "BroadcastService";
public static final String COUNTDOWN_BR = "com.example.emre.denemeprojesi";
Intent bi = new Intent(COUNTDOWN_BR);
CountDownTimer cdt = null;
#Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "Starting timer...");
System.out.println("STARTING TIMER");
cdt = new CountDownTimer(60000, 1000) {
#Override
public void onTick(long millisUntilFinished) {
Log.i(TAG, "Countdown seconds remaining: " + millisUntilFinished / 1000);
bi.putExtra("countdown", millisUntilFinished);
sendBroadcast(bi);
}
#Override
public void onFinish() {
Log.i(TAG, "Timer finished");
System.out.println("TIMER CANCELLED");
}
};
cdt.start();
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
#Override
public IBinder onBind(Intent arg0) {
return null;
}
}
Main Activity:
package com.example.emre.denemeprojesi;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private String TAG ="Countdown Servisi";
private TextView lblResult ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lblResult = (TextView)findViewById(R.id.lbl_result);
startService(new Intent(this, BroadcastService.class));
Log.i(TAG, "Started service");
}
private BroadcastReceiver br = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
updateGUI(intent); // or whatever method used to update your GUI fields
}
};
#Override
public void onResume() {
super.onResume();
registerReceiver(br, new IntentFilter(BroadcastService.COUNTDOWN_BR));
Log.i(TAG, "Registered broacast receiver");
}
#Override
public void onPause() {
super.onPause();
unregisterReceiver(br);
Log.i(TAG, "Unregistered broacast receiver");
}
#Override
public void onStop() {
try {
unregisterReceiver(br);
} catch (Exception e) {
// Receiver was probably already stopped in onPause()
}
super.onStop();
}
#Override
public void onDestroy() {
super.onDestroy();
// stopService(new Intent(this, BroadcastService.class));
//Log.i(TAG, "Stopped service");
}
private void updateGUI(Intent intent) {
if (intent.getExtras() != null) {
long millisUntilFinished = intent.getLongExtra("countdown", 0);
System.out.println(millisUntilFinished); //<<<bu göstermiyor<<<<<<
Log.i(TAG, "Countdown seconds remaining: " + millisUntilFinished / 1000);
//
}
}
}
Related
I have a problem with an activity after minimalising. Everything is going ok when i start an activity and press start button. But when i minimalise activity and again maximalize it, it doesnt respond to my buttons and commands. Anybody know what to do? This is my first android app so i dont know what is going on..
here are my classes :
TrackerService
package sk.tuke.smart.makac.services;
import android.app.Service;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;
public class TrackerService extends Service implements LocationListener {
private Intent commandIntent;
private long duration;
private boolean paused,checkedAfterPause;
private int sportActivity;
private double distance,pace,calories;
private ArrayList<Location> finalPositionList = new ArrayList<Location>();
private LocationManager locationManager;
private static final String TAG = "TrackerService";
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Log.i(TAG,"onStart intent " +intent.getAction());
commandIntent=intent;
checkedAfterPause=true;
if(intent.getAction() == "sk.tuke.smart.makac.COMMAND_START"){
if(intent.getAction() == "sk.tuke.smart.makac.COMMAND_START") {
duration = 0;
}
new Timer().scheduleAtFixedRate(new TimerTask()
{
#Override
public void run() {
if(!paused){
duration++;
Intent intent1 = new Intent();
intent1.setAction("sk.tuke.smart.makac.TICK");
intent1.putExtra("duration", duration);
intent1.putExtra("distance",distance);
sendBroadcast(intent1);
Log.i(TAG,"" + duration);
}
}
}, 1000, 1000);
}else if (intent.getAction() == "sk.tuke.smart.makac.COMMAND_PAUSE"){
paused=true;
locationManager.removeUpdates(this);
}
if(intent.getAction() == "sk.tuke.smart.makac.COMMAND_CONTINUE"){
paused=false;
checkedAfterPause=false;
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,3000,10,this);
}
}
#Override
public void onCreate() {
super.onCreate();
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,3000,10,this);
}
#Override
public void onDestroy() {
locationManager.removeUpdates(this);
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onLocationChanged(Location location) {
finalPositionList.add(location);
Location lastLocation;
double minDistance;
if (finalPositionList.size() != 1 && checkedAfterPause) {
lastLocation = finalPositionList.get(finalPositionList.size() - 2);
minDistance=location.distanceTo(lastLocation);
if(minDistance>=2){
distance += location.distanceTo(lastLocation);
}else{
finalPositionList.remove(finalPositionList.size()-1);
}
}
if(commandIntent.getAction() == "sk.tuke.smart.makac.COMMAND_CONTINUE" && !checkedAfterPause){
Log.i(TAG,"checking distance after pause");
lastLocation = finalPositionList.get(finalPositionList.size() - 2);
minDistance=location.distanceTo(lastLocation);
if(minDistance<=100){
distance += location.distanceTo(lastLocation);
}
checkedAfterPause=true;
}
Log.i(TAG,"locations " + finalPositionList);
Log.i(TAG,"distance = " + distance);
}
#Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
#Override
public void onProviderEnabled(String s) {
}
#Override
public void onProviderDisabled(String s) {
}
public long getDuration(){
return duration;
}
public double getPace(){
return pace;
}
}
SportsActivity
package sk.tuke.smart.makac;
import android.Manifest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import sk.tuke.smart.makac.helpers.MainHelper;
import sk.tuke.smart.makac.services.TrackerService;
public class StopwatchActivity extends AppCompatActivity {
private static final int MY_PERMISSIONS_REQUEST_FINE_LOCATION = 111;
private static final String TAG = "StopwatchActivity";
private boolean started;
private boolean running;
private boolean paused=false;
private long duration;
private double distance;
private MainHelper helper;
private TextView durationView,distanceView;
private Button startButton,endButton;
private BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction()=="sk.tuke.smart.makac.TICK"){
duration = intent.getLongExtra("duration",duration);
distance = intent.getDoubleExtra("distance",distance);
durationView.setText(helper.formatDuration(duration));
distanceView.setText(helper.formatDistance(distance));
}
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_stopwatch);
IntentFilter intentFilter = new IntentFilter("sk.tuke.smart.makac.TICK");
registerReceiver(receiver,intentFilter);
started=false;
running=false;
helper = new MainHelper();
durationView = findViewById(R.id.textview_stopwatch_duration);
distanceView = findViewById(R.id.textview_stopwatch_distance);
startButton = findViewById(R.id.button_stopwatch_start);
endButton = findViewById(R.id.button_stopwatch_endworkout);
if(!canAccessLocation()){
ActivityCompat.requestPermissions(this,
new String[]{
Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_FINE_LOCATION);
}
}
public void toggle(View view){
Intent intent = new Intent(this,TrackerService.class);
started=true;
this.running = !this.running;
if(running && started){
startButton.setText("Stop");
endButton.setVisibility(view.GONE);
if(paused){
intent.setAction("sk.tuke.smart.makac.COMMAND_CONTINUE");
paused=false;
}else
intent.setAction("sk.tuke.smart.makac.COMMAND_START");
}
if(!running && started){
startButton.setText("Continue");
endButton.setVisibility(view.VISIBLE);
intent.setAction("sk.tuke.smart.makac.COMMAND_PAUSE");
paused=true;
}
startService(intent);
}
public void endWorkout(View view){
Intent intent = new Intent(this,TrackerService.class);
intent.setAction("sk.tuke.smart.makac.COMMAND_STOP");
startService(intent);
setContentView(R.layout.activity_workout_detail);
onStop();
}
public void openMaps(View view){
Intent intent = new Intent(StopwatchActivity.this, MapsActivity.class);
startActivity(intent);
}
#Override
protected void onStart() {
super.onStart();
}
#Override
protected void onStop() {
super.onStop();
Intent intent= new Intent(this,TrackerService.class);
stopService(intent);
}
private boolean hasPermission(String perm) {
return(PackageManager.PERMISSION_GRANTED==checkSelfPermission(perm));
}
private boolean canAccessLocation() {
return(hasPermission(Manifest.permission.ACCESS_FINE_LOCATION));
}
}
You aren't creating a connection to the service. You're only starting it, not binding it. So there's no connection to maintain.
It looks like you're trying to do quasi-binding via actions. Don't do that, properly bind the service and avoid a whole raft of problems like this.
First of all, I know there is so much questions are already asked about this voice recognition in background or service. I think I've checked all of them in 2 weeks :P. But I did not understand all these answers. I also used there code but it's not working.
What I want is when user clicks on a button to start voice recognition service then the service starts and even the android is locked the service listen instructions from the user.
Can somebody tell me how can I achieve this or any tutorials.
I'm working on this from 2 weeks. I have searched a lot on google and SO also.
==================Update==============================
I'm Calling a Service in MainActivity but the service is started and and also receive the message but the RecognitionListener class methods did not start. I'm using the code from this
Android Speech Recognition Continuous Service
Can somebody tell me what's going wrong in my code....
This is MainActivity
package com.android.jarvis.voicerecognitionservice;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Build;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import static com.android.jarvis.voicerecognitionservice.BuildConfig.DEBUG;
public class MainActivity extends AppCompatActivity {
static final String TAG = "Service";
private int mBindFlag;
private Messenger mServiceMessenger;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Intent service = new Intent(MainActivity, RecognitionService.class);
startService(new Intent(this, RecognitionService.class));
mBindFlag = Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH ? 0 : Context.BIND_ABOVE_CLIENT;
}
#Override
protected void onStart()
{
super.onStart();
bindService(new Intent(this, RecognitionService.class), mServiceConnection, mBindFlag);
}
#Override
protected void onStop()
{
super.onStop();
if (mServiceMessenger != null)
{
unbindService(mServiceConnection);
mServiceMessenger = null;
}
}
private final ServiceConnection mServiceConnection = new ServiceConnection()
{
#Override
public void onServiceConnected(ComponentName name, IBinder service)
{
if (DEBUG) {Log.d(TAG, "onServiceConnected");} //$NON-NLS-1$
mServiceMessenger = new Messenger(service);
Message msg = new Message();
msg.what = RecognitionService.MSG_RECOGNIZER_START_LISTENING;
try
{
mServiceMessenger.send(msg);
Log.d(TAG,"Message Sent");
}
catch (RemoteException e)
{
e.printStackTrace();
}
}
#Override
public void onServiceDisconnected(ComponentName name)
{
if (DEBUG) {
Log.d(TAG, "onServiceDisconnected");} //$NON-NLS-1$
mServiceMessenger = null;
}
}; //
}
This is Recognition Service
package com.android.jarvis.voicerecognitionservice;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.os.Build;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.speech.RecognitionListener;
import android.speech.RecognizerIntent;
import android.speech.SpeechRecognizer;
import android.util.Log;
import android.widget.Toast;
import java.lang.ref.WeakReference;
import static com.android.jarvis.voicerecognitionservice.MainActivity.TAG;
public class RecognitionService extends Service {
static AudioManager mAudioManager;
protected SpeechRecognizer mSpeechRecognizer;
protected Intent mSpeechRecognizerIntent;
protected final Messenger mServerMessenger = new Messenger(new IncomingHandler(this));
static boolean mIsListening;
static volatile boolean mIsCountDownOn;
static boolean mIsStreamSolo;
static final int MSG_RECOGNIZER_START_LISTENING = 1;
static final int MSG_RECOGNIZER_CANCEL = 2;
#Override
public void onCreate()
{
super.onCreate();
mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
mSpeechRecognizer = SpeechRecognizer.createSpeechRecognizer(this);
mSpeechRecognizer.setRecognitionListener(new SpeechRecognitionListener());
mSpeechRecognizerIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE,
this.getPackageName());
Toast.makeText(this, "Service Started", Toast.LENGTH_SHORT).show();
}
protected static class IncomingHandler extends Handler
{
private WeakReference<RecognitionService> mtarget;
IncomingHandler(RecognitionService target)
{
mtarget = new WeakReference<RecognitionService>(target);
}
#Override
public void handleMessage(Message msg)
{
final RecognitionService target = mtarget.get();
switch (msg.what)
{
case MSG_RECOGNIZER_START_LISTENING:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
{
// turn off beep sound
// if (!mIsStreamSolo)
// {
// mAudioManager.setStreamSolo(AudioManager.STREAM_VOICE_CALL, true);
// mIsStreamSolo = true;
// }
}
if (!target.mIsListening)
{
target.mSpeechRecognizer.startListening(target.mSpeechRecognizerIntent);
target.mIsListening = true;
Log.d(TAG, "message start listening"); //$NON-NLS-1$
}
break;
case MSG_RECOGNIZER_CANCEL:
if (mIsStreamSolo)
{
mAudioManager.setStreamSolo(AudioManager.STREAM_VOICE_CALL, false);
mIsStreamSolo = false;
}
target.mSpeechRecognizer.cancel();
target.mIsListening = false;
Log.d(TAG, "message canceled recognizer"); //$NON-NLS-1$
break;
}
}
}
// Count down timer for Jelly Bean work around
protected CountDownTimer mNoSpeechCountDown = new CountDownTimer(5000, 5000)
{
#Override
public void onTick(long millisUntilFinished)
{
// TODO Auto-generated method stub
}
#Override
public void onFinish()
{
mIsCountDownOn = false;
Message message = Message.obtain(null, MSG_RECOGNIZER_CANCEL);
try
{
mServerMessenger.send(message);
message = Message.obtain(null, MSG_RECOGNIZER_START_LISTENING);
mServerMessenger.send(message);
}
catch (RemoteException e)
{
}
}
};
#Override
public void onDestroy()
{
super.onDestroy();
if (mIsCountDownOn)
{
mNoSpeechCountDown.cancel();
}
if (mSpeechRecognizer != null)
{
mSpeechRecognizer.destroy();
}
}
#Override
public IBinder onBind(Intent intent)
{
Log.d(TAG, "onBind"); //$NON-NLS-1$
return mServerMessenger.getBinder();
}
protected class SpeechRecognitionListener implements RecognitionListener
{
#Override
public void onBeginningOfSpeech()
{
// speech input will be processed, so there is no need for count down anymore
if (mIsCountDownOn)
{
mIsCountDownOn = false;
mNoSpeechCountDown.cancel();
}
Log.d(TAG, "onBeginingOfSpeech"); //$NON-NLS-1$
}
#Override
public void onBufferReceived(byte[] buffer)
{
}
#Override
public void onEndOfSpeech()
{
Log.d(TAG, "onEndOfSpeech"); //$NON-NLS-1$
}
#Override
public void onError(int error)
{
if (mIsCountDownOn)
{
mIsCountDownOn = false;
mNoSpeechCountDown.cancel();
}
mIsListening = false;
Message message = Message.obtain(null, MSG_RECOGNIZER_START_LISTENING);
try
{
mServerMessenger.send(message);
}
catch (RemoteException e)
{
}
Log.d(TAG, "error = " + error); //$NON-NLS-1$
}
#Override
public void onEvent(int eventType, Bundle params)
{
}
#Override
public void onPartialResults(Bundle partialResults)
{
}
#Override
public void onReadyForSpeech(Bundle params)
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
{
mIsCountDownOn = true;
mNoSpeechCountDown.start();
}
Log.d(TAG, "onReadyForSpeech"); //$NON-NLS-1$
}
#Override
public void onResults(Bundle results)
{
Log.d(TAG, "onResults"); //$NON-NLS-1$
}
#Override
public void onRmsChanged(float rmsdB)
{
}
}
}
You should implement an RecognitionService.
https://developer.android.com/reference/android/speech/RecognitionService
There is an demo example from android:
https://android.googlesource.com/platform/development/+/master/samples/VoiceRecognitionService/
I am making simple app to display video and plaing audio playback if activity is in background.
My app works fine if i just turn screen off/on.
It crashes when I resume my app after brawsing another application.
Log cat show no error.
import android.app.Activity;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import com.squareup.otto.Subscribe;
public class MainActivity
extends Activity
implements android.view.SurfaceHolder.Callback {
private SurfaceView surfaceViewFrame;
private SurfaceHolder holder;
private Bundle extras;
private static final String TAG = "log_tag";
private boolean b = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
surfaceViewFrame = (SurfaceView) findViewById(R.id.surfaceView);
surfaceViewFrame.setClickable(false);
holder = surfaceViewFrame.getHolder();
holder.addCallback(this);
}
#Subscribe
public void attachPlayer(MediaPlayer player) {
player.setDisplay(holder);
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
public void surfaceCreated(SurfaceHolder holder) {
startService(new Intent(this, MediaPlayerService.class));
}
public void surfaceDestroyed(SurfaceHolder holder) {
}
#Override
protected void onStart() {
super.onStart();
BusProvider.getInstance().register(this);
}
#Override
protected void onStop() {
super.onStop();
BusProvider.getInstance().unregister(this);
}
Service
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.IBinder;
import android.util.Log;
import java.io.IOException;
public class MediaPlayerService
extends Service
implements MediaPlayer.OnPreparedListener,
MediaPlayer.OnCompletionListener,
MediaPlayer.OnSeekCompleteListener {
private static final String TAG = "MediaService";
private static final String ACTION_PLAY = "com.example.action.PLAY";
private MediaPlayer player;
public String[]
video_path =
{"https://ellovidsout.s3.amazonaws.com/1265/9/1422967594.mp4.m3u8", "https://ellovidsout.s3.amazonaws.com/1260/9/1422887544.mp4.m3u8"};
#Override
public void onCreate() {
super.onCreate();
player = new MediaPlayer();
player.setOnPreparedListener(this);
player.setOnCompletionListener(this);
player.setOnSeekCompleteListener(this);
player.setScreenOnWhilePlaying(true);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
playVideo();
Notification note = new Notification(
R.drawable.ic_launcher, "Can you hear the music?", System.currentTimeMillis()
);
Intent i = new Intent(this, MediaPlayerService.class);
i.setFlags(
Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP
);
PendingIntent pi = PendingIntent.getActivity(
this, 0, i, 0
);
note.setLatestEventInfo(
this, "Fake Player", "Now Playing: \"Ummmm, Nothing\"", pi
);
note.flags |= Notification.FLAG_NO_CLEAR;
startForeground(1337, note);
return super.onStartCommand(intent, flags, startId);
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onDestroy() {
super.onDestroy();
player.stop();
player.release();
player = null;
}
private Thread playback = new Thread(
new Runnable() {
public void run() {
try {
try {
player.setDataSource(
MediaPlayerService.this, Uri.parse(
video_path[0]
)
);
player.prepareAsync();
} catch (IOException e) {
Log.e(TAG, "Error while playing video: " + e.getMessage());
}
} catch (IllegalArgumentException e) {
Log.e(TAG, "Error while playing video: " + e.getMessage());
}
}
}
);
private void playVideo() {
if (player!=null&&!playback.isAlive()) playback.start();
}
public void onPrepared(MediaPlayer mp) {
if (!player.isPlaying()) {
player.start();
BusProvider.getInstance()
.post(player);
}
}
public void onCompletion(MediaPlayer mp) {
try {
player.setDataSource(
MediaPlayerService.this, Uri.parse(
video_path[0]
)
);
} catch (IOException e) {
Log.e(TAG, "Error while playing video: " + e.getMessage());
}
player.prepareAsync();
}
public void onSeekComplete(MediaPlayer mp) {
}
}
you missed in onStop:
#Override
protected void onStop() {
holder.removeCallback(this);
super.onStop();
}
please add the crash report
I want a service which runs a CountDownTimer and in every tick I want to show the countdown in a Activity and after some interval play a sound.
All the process are going fine in a single Activity but during incoming call the countdown not working that's why I want to do this using a Service.
Can anybody help me?
thanks in advance.
Update...
mCountDownTimer = new CountDownTimer(mTimerDuration, 1000) {
#Override
public void onTick(long millisUntilFinished) {
if (mTimerDuration > 0) {
mDurationCount += 1000;
showCountDown(
ActivityA.this,
(mSimpleDateFormat.format(mTimerDuration
- mDurationCount)));
if (mDurationCount == mTimerDuration) {
if (mRepeatTime > 1) {
startRepeatTimer();
}
finishTimer();
}
}
}
#Override
public void onFinish() {
}
}.start();
The easiest way is probably to create a broadcast receiver in your activity and have the service send broadcasts to the receiver. Here's a full listing for a service class with a simplified CountDownTimer.
package com.example.cdt;
import android.app.Service;
import android.content.Intent;
import android.os.CountDownTimer;
import android.os.IBinder;
import android.util.Log;
public class BroadcastService extends Service {
private final static String TAG = "BroadcastService";
public static final String COUNTDOWN_BR = "your_package_name.countdown_br";
Intent bi = new Intent(COUNTDOWN_BR);
CountDownTimer cdt = null;
#Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "Starting timer...");
cdt = new CountDownTimer(30000, 1000) {
#Override
public void onTick(long millisUntilFinished) {
Log.i(TAG, "Countdown seconds remaining: " + millisUntilFinished / 1000);
bi.putExtra("countdown", millisUntilFinished);
sendBroadcast(bi);
}
#Override
public void onFinish() {
Log.i(TAG, "Timer finished");
}
};
cdt.start();
}
#Override
public void onDestroy() {
cdt.cancel();
Log.i(TAG, "Timer cancelled");
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
#Override
public IBinder onBind(Intent arg0) {
return null;
}
}
And here are the relevant lines from a main activity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
startService(new Intent(this, BroadcastService.class));
Log.i(TAG, "Started service");
}
private BroadcastReceiver br = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
updateGUI(intent); // or whatever method used to update your GUI fields
}
};
#Override
public void onResume() {
super.onResume();
registerReceiver(br, new IntentFilter(BroadcastService.COUNTDOWN_BR));
Log.i(TAG, "Registered broacast receiver");
}
#Override
public void onPause() {
super.onPause();
unregisterReceiver(br);
Log.i(TAG, "Unregistered broacast receiver");
}
#Override
public void onStop() {
try {
unregisterReceiver(br);
} catch (Exception e) {
// Receiver was probably already stopped in onPause()
}
super.onStop();
}
#Override
public void onDestroy() {
stopService(new Intent(this, BroadcastService.class));
Log.i(TAG, "Stopped service");
super.onDestroy();
}
private void updateGUI(Intent intent) {
if (intent.getExtras() != null) {
long millisUntilFinished = intent.getLongExtra("countdown", 0);
Log.i(TAG, "Countdown seconds remaining: " + millisUntilFinished / 1000);
}
}
You'll also need to define the service between the start/end application tags in your manifest file.
<service android:name=".BroadcastService" />
Download source code Android Countdown Timer Run In Background
activity_main.xml
<RelativeLayout android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/et_hours"
android:hint="Hours"
android:inputType="time"
android:layout_marginRight="5dp"
/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/btn_timer"
android:layout_above="#+id/btn_cancel"
android:text="Start Timer"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:id="#+id/btn_cancel"
android:text="cancel timer"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/tv_timer"
android:layout_centerInParent="true"
android:textSize="25dp"
android:textColor="#000000"
android:text="00:00:00"/>
</RelativeLayout>
Timer_Service.java
package com.countdowntimerservice;
import android.app.Service;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Handler;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.support.annotation.Nullable;
import android.util.Log;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;
public class Timer_Service extends Service {
public static String str_receiver = "com.countdowntimerservice.receiver";
private Handler mHandler = new Handler();
Calendar calendar;
SimpleDateFormat simpleDateFormat;
String strDate;
Date date_current, date_diff;
SharedPreferences mpref;
SharedPreferences.Editor mEditor;
private Timer mTimer = null;
public static final long NOTIFY_INTERVAL = 1000;
Intent intent;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
mpref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
mEditor = mpref.edit();
calendar = Calendar.getInstance();
simpleDateFormat = new SimpleDateFormat("HH:mm:ss");
mTimer = new Timer();
mTimer.scheduleAtFixedRate(new TimeDisplayTimerTask(), 5, NOTIFY_INTERVAL);
intent = new Intent(str_receiver);
}
class TimeDisplayTimerTask extends TimerTask {
#Override
public void run() {
mHandler.post(new Runnable() {
#Override
public void run() {
calendar = Calendar.getInstance();
simpleDateFormat = new SimpleDateFormat("HH:mm:ss");
strDate = simpleDateFormat.format(calendar.getTime());
Log.e("strDate", strDate);
twoDatesBetweenTime();
}
});
}
}
public String twoDatesBetweenTime() {
try {
date_current = simpleDateFormat.parse(strDate);
} catch (Exception e) {
}
try {
date_diff = simpleDateFormat.parse(mpref.getString("data", ""));
} catch (Exception e) {
}
try {
long diff = date_current.getTime() - date_diff.getTime();
int int_hours = Integer.valueOf(mpref.getString("hours", ""));
long int_timer = TimeUnit.HOURS.toMillis(int_hours);
long long_hours = int_timer - diff;
long diffSeconds2 = long_hours / 1000 % 60;
long diffMinutes2 = long_hours / (60 * 1000) % 60;
long diffHours2 = long_hours / (60 * 60 * 1000) % 24;
if (long_hours > 0) {
String str_testing = diffHours2 + ":" + diffMinutes2 + ":" + diffSeconds2;
Log.e("TIME", str_testing);
fn_update(str_testing);
} else {
mEditor.putBoolean("finish", true).commit();
mTimer.cancel();
}
}catch (Exception e){
mTimer.cancel();
mTimer.purge();
}
return "";
}
#Override
public void onDestroy() {
super.onDestroy();
Log.e("Service finish","Finish");
}
private void fn_update(String str_time){
intent.putExtra("time",str_time);
sendBroadcast(intent);
}
}
MainActivity.java
package com.countdowntimerservice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import java.text.SimpleDateFormat;
import java.util.Calendar;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button btn_start, btn_cancel;
private TextView tv_timer;
String date_time;
Calendar calendar;
SimpleDateFormat simpleDateFormat;
EditText et_hours;
SharedPreferences mpref;
SharedPreferences.Editor mEditor;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
listener();
}
private void init() {
btn_start = (Button) findViewById(R.id.btn_timer);
tv_timer = (TextView) findViewById(R.id.tv_timer);
et_hours = (EditText) findViewById(R.id.et_hours);
btn_cancel = (Button) findViewById(R.id.btn_cancel);
mpref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
mEditor = mpref.edit();
try {
String str_value = mpref.getString("data", "");
if (str_value.matches("")) {
et_hours.setEnabled(true);
btn_start.setEnabled(true);
tv_timer.setText("");
} else {
if (mpref.getBoolean("finish", false)) {
et_hours.setEnabled(true);
btn_start.setEnabled(true);
tv_timer.setText("");
} else {
et_hours.setEnabled(false);
btn_start.setEnabled(false);
tv_timer.setText(str_value);
}
}
} catch (Exception e) {
}
}
private void listener() {
btn_start.setOnClickListener(this);
btn_cancel.setOnClickListener(this);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_timer:
if (et_hours.getText().toString().length() > 0) {
int int_hours = Integer.valueOf(et_hours.getText().toString());
if (int_hours<=24) {
et_hours.setEnabled(false);
btn_start.setEnabled(false);
calendar = Calendar.getInstance();
simpleDateFormat = new SimpleDateFormat("HH:mm:ss");
date_time = simpleDateFormat.format(calendar.getTime());
mEditor.putString("data", date_time).commit();
mEditor.putString("hours", et_hours.getText().toString()).commit();
Intent intent_service = new Intent(getApplicationContext(), Timer_Service.class);
startService(intent_service);
}else {
Toast.makeText(getApplicationContext(),"Please select the value below 24 hours",Toast.LENGTH_SHORT).show();
}
/*
mTimer = new Timer();
mTimer.scheduleAtFixedRate(new TimeDisplayTimerTask(), 5, NOTIFY_INTERVAL);*/
} else {
Toast.makeText(getApplicationContext(), "Please select value", Toast.LENGTH_SHORT).show();
}
break;
case R.id.btn_cancel:
Intent intent = new Intent(getApplicationContext(),Timer_Service.class);
stopService(intent);
mEditor.clear().commit();
et_hours.setEnabled(true);
btn_start.setEnabled(true);
tv_timer.setText("");
break;
}
}
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String str_time = intent.getStringExtra("time");
tv_timer.setText(str_time);
}
};
#Override
protected void onResume() {
super.onResume();
registerReceiver(broadcastReceiver,new IntentFilter(Timer_Service.str_receiver));
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(broadcastReceiver);
}
}
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();
}
}