I want to make an android application that have punch in and punch out functionality. Scenario is when the user entered in an application it enters its task and press punch in button, When punch in button is press current date and time is saved in a local database and timer is running on background even i close an application but issue is it cannot run in background when i close an application and starts again timer starts from beginning.
How to figure out that my service is running and get that data?
MainActivity.java
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
private Button startButton;
private Button pauseButton;
private TextView timerValue;
Intent intent;
long timeSwapBuff = 0L;
long updatedTime = 0L;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
timerValue = (TextView) findViewById(R.id.timerValue);
startButton = (Button) findViewById(R.id.startButton);
startButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
intent = new Intent(MainActivity.this, MyService.class);
startService(intent);
registerReceiver(broadcastReceiver, new IntentFilter(MyService.BROADCAST_ACTION));
}
});
pauseButton = (Button) findViewById(R.id.pauseButton);
pauseButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
unregisterReceiver(broadcastReceiver);
stopService(intent);
}
});
}
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent)
{
updateUI(intent);
}
};
private void updateUI(Intent intent) {
int time = intent.getIntExtra("time", 0);
Log.d("Hello", "Time " + time);
int mins = time / 60;
int secs = time % 60;
timerValue.setText("" + mins + ":" + String.format("%02d", secs));
}
#Override
protected void onStop() {
super.onStop();
intent = new Intent(MainActivity.this, MyService.class);
startService(intent);
registerReceiver(broadcastReceiver, new IntentFilter(MyService.BROADCAST_ACTION));
}
}
MyService.java
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.SystemClock;
import android.support.annotation.Nullable;
import android.widget.Toast;
public class MyService extends Service
{
private Intent intent;
public static final String BROADCAST_ACTION = "com.example.wajid.service";
private Handler handler = new Handler();
private long initial_time;
long timeInMilliseconds = 0L;
#Override
public void onCreate() {
super.onCreate();
initial_time = SystemClock.uptimeMillis();
intent = new Intent(BROADCAST_ACTION);
handler.removeCallbacks(sendUpdatesToUI);
handler.postDelayed(sendUpdatesToUI, 1000); // 1 second
}
private Runnable sendUpdatesToUI = new Runnable() {
public void run() {
DisplayLoggingInfo();
handler.postDelayed(this, 1000); // 1 seconds
}
};
private void DisplayLoggingInfo() {
timeInMilliseconds = SystemClock.uptimeMillis() - initial_time;
int timer = (int) timeInMilliseconds / 1000;
intent.putExtra("time", timer);
sendBroadcast(intent);
}
#Override
public void onDestroy() {
super.onDestroy();
handler.removeCallbacks(sendUpdatesToUI);
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
Why do you want to run a timer? Instead, simply save the check-in time in shared preferences. On check-out, the two can be compared and the relevant time calculated.
If you are worried that the user might try to manipulate the local device clock, then instead of getting the local time, you can use network time.
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);
//
}
}
}
I am trying to understand how this stuff works a little better.
So I learned about Runnables and Threads and ASyncTasks but apparently they have some serious drawbacks when it comes to configuration changes like rotating the screen.
Is it better to instead use IntentService for anything that should run in the background like SQL database commands, file-system procedures, Internet input/output processes, etc -- and then use LocalBroadcastReceiver to pass results back to the Activity?
Is it better to instead use IntentService for anything that should run in the background like SQL database commands, file-system procedures, Internet input/output processes, etc -- and then use LocalBroadcastReceiver to pass results back to the Activity?
A service is needed if your UI might move to the background while the work is going on, and you are concerned that your process might be terminated while the work is going on. I tend to only worry about this if the work might exceed a second or so. Otherwise, a plain thread suffices.
Using an event bus, like LocalBroadcastManager, is a reasonable approach to let other components know when your service/thread is done with its work. This sample app demonstrates this. Personally, I tend to use greenrobot's EventBus — this sample app is a clone of the first one, but using EventBus instead of LocalBroadcastManager.
Follow an example of a chat using one activity (chat activity) that run a class in service (realtime class). I use a mvc webapi to controll chat between chatters. When realtime receive a message "onConnected" or "ReceivedMessageServer" automatically send by LocalBroadcastManager to chat activity. This way in "onReceive" from BroadcastReceiver receives the message and runs other tasks.
a) ChatActivity.class
package br.com.yourapp;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.res.Configuration;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.util.TypedValue;
import android.view.KeyEvent;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import java.util.Calendar;
import br.com.yourapp.model.MessageReceived;
import util.RealTime;
public class ChatActivity extends AppCompatActivity implements View.OnClickListener,
View.OnKeyListener , TextWatcher {
AppController obj;
private ProgressDialog pDialog;
MediaPlayer mp;
private ListView lstChatLog;
private ArrayAdapter<String> listAdapter;
private EditText txtChatMessage;
private TextView lblTyping;
private Button btnSendChat;
private boolean resultRequest = true;
private String errorMessage = "Internet is not working";
private AlertDialog alertDialog;
private AlertDialog.Builder alertBuilder;
String userType = "V";
String spaces = "\u0020\u0020\u0020\u0020";
Calendar time;
MessageReceived msg;
private RealTime realTime;
private final Context mContext = this;
private boolean mBound = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
pDialog = new ProgressDialog(this);
pDialog.setMessage("Loading...");
pDialog.setCancelable(false);
showProgressDialog();
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
obj = (AppController) getApplicationContext();
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
lblTyping = (TextView) findViewById(R.id.lblTyping);
txtChatMessage = (EditText) findViewById(R.id.txtChatMessage);
txtChatMessage.setOnKeyListener(this);
txtChatMessage.addTextChangedListener(this);
btnSendChat = (Button) findViewById(R.id.btnSendChat);
btnSendChat.setOnClickListener(this);
alertDialog = new AlertDialog.Builder(this).create();
alertDialog.setTitle("Alert");
alertBuilder = new AlertDialog.Builder(this);
lstChatLog = (ListView) findViewById(R.id.lstChatLog);
listAdapter = new ArrayAdapter<String>(ChatActivity.this, android.R.layout.simple_list_item_1, android.R.id.text1) {
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = super.getView(position, convertView, parent);
TextView tv = (TextView) view.findViewById(android.R.id.text1);
tv.setHeight(20);
tv.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 12);
return view;
}
};
Intent intent = new Intent();
intent.setClass(mContext, RealTime.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
IntentFilter filter = new IntentFilter("Connect");
filter.addAction("RecMsg");
LocalBroadcastManager.getInstance(ChatActivity.this).registerReceiver(mMessageReceiver, filter);
}
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().toString().equals("Connect")) {
msg = (MessageReceived) intent.getExtras().getParcelable("msg");
if (msg == null || msg.Message == null)
return;
listAdapter.add(msg.Destiny + "" + msg.CurrentTime + " : " + msg.Message);
lstChatLog.setAdapter(listAdapter);
realTime.SendToSpecific(msg.Sender, "Hi !", userType, obj.getRiderId(), obj.getDriverId());
hideProgressDialog();
}
else
if (intent.getAction().toString().equals("RecMsg")) {
msg = (MessageReceived) intent.getExtras().getParcelable("msg");
if (msg == null || msg.Message == null)
return;
if (msg.Message.equals("*0.+9=&!*#_&1|8%digi")) {
lblTyping.setVisibility(View.VISIBLE);
}
else
if (msg.Message.equals("*0.+9=&!*#_&1|8%"))
{
lblTyping.setVisibility(View.INVISIBLE);
}
else
{
lblTyping.setVisibility(View.INVISIBLE);
listAdapter.add(msg.Sender + "" + msg.CurrentTime + " : " + msg.Message);
lstChatLog.setAdapter(listAdapter);
mp = MediaPlayer.create(ChatActivity.this, R.raw.notify);
mp.setLooping(false);
mp.setVolume(100, 100);
mp.start();
}
}
}
};
private final ServiceConnection mConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName className, IBinder service) {
RealTime.LocalBinder binder = (RealTime.LocalBinder) service;
realTime = binder.getService();
mBound = true;
realTime.Connect(obj.getRiderName(), userType, obj.getRiderId(), obj.getLatitudeRider(), obj.getLongitudeRider(), obj.getDriverId(), obj.getVehicieId());
hideProgressDialog();
}
#Override
public void onServiceDisconnected(ComponentName arg0) {
mBound = false;
}
};
#Override
protected void onStop() {
if (mBound) {
unbindService(mConnection);
mBound = false;
}
super.onStop();
}
public void SendToSpecific(String sender, String message, String userType, long userId, long operatorId) {
realTime.SendToSpecific(sender, message, userType, userId,operatorId);
if (!message.equals("*0.+9=&!*#_&1|8%digi") && !message.equals("*0.+9=&!*#_&1|8%"))
{
time = Calendar.getInstance();
listAdapter.add(spaces + sender + " " + "(" + time.get(Calendar.HOUR) + ":" + time.get(Calendar.MINUTE) + ")" + " : " + message);
lstChatLog.setAdapter(listAdapter);
txtChatMessage.setText("");
}
}
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode==KeyEvent.KEYCODE_ENTER) {
if (txtChatMessage.getText().length() > 0)
{
InputMethodManager imm = (InputMethodManager) this.getSystemService(Context.
INPUT_METHOD_SERVICE);
if (this.getCurrentFocus() != null)
imm.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), 0);
SendToSpecific(obj.getRiderName(), txtChatMessage.getText().toString(), userType, obj.getRiderId(), obj.getDriverId());
}
}
return false;
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (txtChatMessage.getText().toString().length() > 0) {
if (txtChatMessage.getText().length() == 1) {
SendToSpecific(obj.getRiderName(), "*0.+9=&!*#_&1|8%digi", userType, obj.getRiderId(), obj.getDriverId());
}
} else {
SendToSpecific(obj.getRiderName(), "*0.+9=&!*#_&1|8%", userType, obj.getRiderId(), obj.getDriverId());
}
}
#Override
public void afterTextChanged(Editable s) {
}
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnSendChat:
if (txtChatMessage != null && txtChatMessage.getText().length() > 0) {
InputMethodManager imm = (InputMethodManager) this.getSystemService(Context.
INPUT_METHOD_SERVICE);
if (this.getCurrentFocus() != null)
imm.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), 0);
SendToSpecific(obj.getRiderName(), txtChatMessage.getText().toString(), userType, obj.getRiderId(), obj.getDriverId());
}
break;
}
}
private void showProgressDialog() {
if (!pDialog.isShowing())
pDialog.show();
}
private void hideProgressDialog() {
if (pDialog.isShowing())
pDialog.hide();
}
#Override
protected void onDestroy() {
try {
if (pDialog != null && pDialog.isShowing())
pDialog.dismiss();
} catch (Exception e) {
e.printStackTrace();
}
super.onDestroy();
}
#Override
public boolean onTouchEvent(MotionEvent event) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.
INPUT_METHOD_SERVICE);
if (getCurrentFocus() != null)
imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
mMessageReceiver.clearAbortBroadcast();
Intent i = new Intent(this, MenuPageActivity.class);
obj.setLastActivity("Chat");
startActivity(i);
return true;
}
public void ShowAlert() {
hideProgressDialog();
if (resultRequest)
errorMessage = "Internet is not working";
alertBuilder.setTitle("Alert");
alertBuilder.setMessage(errorMessage);
alertBuilder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
arg0.dismiss();
}
});
alertDialog = alertBuilder.create();
alertDialog.show();
errorMessage = "";
resultRequest = true;
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
}
b) Realtime.class
package util;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import java.util.concurrent.ExecutionException;
import br.com.yourapp.model.MessageReceived;
import microsoft.aspnet.signalr.client.Platform;
import microsoft.aspnet.signalr.client.SignalRFuture;
import microsoft.aspnet.signalr.client.http.android.AndroidPlatformComponent;
import microsoft.aspnet.signalr.client.hubs.HubConnection;
import microsoft.aspnet.signalr.client.hubs.HubProxy;
import microsoft.aspnet.signalr.client.hubs.SubscriptionHandler1;
import microsoft.aspnet.signalr.client.transport.ClientTransport;
import microsoft.aspnet.signalr.client.transport.ServerSentEventsTransport;
public class RealTime extends Service {
private HubConnection mHubConnection;
private HubProxy mHubProxy;
private Handler mHandler;
private final IBinder mBinder = new LocalBinder();
public RealTime() { }
#Override
public void onCreate() {
super.onCreate();
mHandler = new Handler(Looper.getMainLooper());
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
int result = super.onStartCommand(intent, flags, startId);
startSignalR();
return result;
}
#Override
public void onDestroy() {
mHubConnection.stop();
super.onDestroy();
}
#Override
public IBinder onBind(Intent intent) {
startSignalR();
return mBinder;
}
public class LocalBinder extends Binder {
public RealTime getService() {
return RealTime.this;
}
}
public void Connect(String userName, String userType, long userId, double latitude, double longitude, long driverId, long vehicleId) {
mHubProxy.invoke("Connect", userName, userType, userId, latitude, longitude, driverId, vehicleId);
}
public void SendMessageToGroup(String userName, String userGroup, String userType, long userId, double latitude, double longitude, long vehicleId, short option)
{
mHubProxy.invoke("SendMessageToGroup", userName, userGroup, userType, userId, latitude, longitude, vehicleId, option);
}
public void SendToSpecific(String sender, String message, String userType, long userId, long operatorId)
{
mHubProxy.invoke("SendToSpecific", sender, message, userType, userId, operatorId);
}
private void startSignalR() {
Platform.loadPlatformComponent(new AndroidPlatformComponent());
mHubConnection = new HubConnection("http://webapi.com");
mHubProxy = mHubConnection.createHubProxy("ChatHub");
ClientTransport clientTransport = new ServerSentEventsTransport(mHubConnection.getLogger());
SignalRFuture<Void> signalRFuture = mHubConnection.start(clientTransport);
try {
signalRFuture.get();
} catch (InterruptedException | ExecutionException e) {
Log.e("SimpleSignalR", e.toString());
return;
}
mHubProxy.on("onConnected",
new SubscriptionHandler1<MessageReceived>() {
#Override
public void run(final MessageReceived msg) {
mHandler.post(new Runnable() {
#Override
public void run() {
Intent intent = new Intent("Connect");
intent.putExtra("msg", msg);
LocalBroadcastManager.getInstance(RealTime.this).sendBroadcast(intent);
}
});
}
}
, MessageReceived.class);
}
}
mHubProxy.on("ReceivedMessageServer",
new SubscriptionHandler1<MessageReceived>() {
#Override
public void run(final MessageReceived msg) {
mHandler.post(new Runnable() {
#Override
public void run() {
Intent intent = new Intent("RecMsg");
intent.putExtra("msg", msg);
LocalBroadcastManager.getInstance(RealTime.this).sendBroadcast(intent);
}
});
}
}
, MessageReceived.class);
}
Hello I am new to android programming. I am writing an app for school and I need to save Accelerometer data to a txt file.
The problem is that when I lock screen or turn screen saving on, the data recording stops.
Can you please give me advice ?
Here is my code:
package emzet.data2text;
import android.app.Activity;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.os.Environment;
import android.os.PowerManager;
import android.view.View;
import android.widget.Button;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
public class MainActivity extends Activity implements SensorEventListener {
private SensorManager sensorManager;
private Sensor accelerometer;
private FileWriter writer;
private Button btnStart, btnStop;
String root = Environment.getExternalStorageDirectory().toString();
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnStart = (Button) findViewById(R.id.btnStart);
btnStop = (Button) findViewById(R.id.btnStop);
btnStart.setEnabled(true);
btnStop.setEnabled(true);
//PowerManager mgr = (PowerManager)this.getSystemService(Context.POWER_SERVICE);
//PowerManager.WakeLock wakeLock = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "MyWakeLock");
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
}
public void onStartClick(View view) {
sensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_NORMAL);
btnStop.setEnabled(true);
btnStart.setEnabled(false);
}
public void onStopClick(View view) {
sensorManager.unregisterListener(this);
btnStart.setEnabled(true);
btnStop.setEnabled(false);
}
protected void onResume() {
super.onResume();
try {
writer = new FileWriter(root + "/acc2txt-file.txt",true);
} catch (IOException e) {
e.printStackTrace();
}
}
protected void onPause() {
super.onPause();
if(writer != null) {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
#Override
public void onSensorChanged(SensorEvent event) {
float x = event.values[0];
float y = event.values[1];
float z = event.values[2];
SimpleDateFormat time = new SimpleDateFormat("HH:mm:ss:SSS");
String s = time.format(new java.util.Date());
try {
writer.write(s+"\t"+x+"\t"+y+"\t"+z+"\n");
} catch (IOException e) {
e.printStackTrace();
}
}
}
if you want to save data in app stop as well, you can write a service with START_STICKY option , then the service stays active even if the app is killed. Here is example of STICKY Service, it is easy and would fit your needs example 1 example 2
public class MyService extends Service {
protected String messageData = null;
public static final int MSG_REGISTER_CLIENT = 1;
public static final int MSG_UNREGISTER_CLIENT = 2;
public static final int MSG_CUSTOM_TYPE = 3;
#Override public void onCreate() {
super.onCreate();
MyServiceRunningBackground();
running = true;
}
#Override public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
//TODO for communication return IBinder implementation
return null;
}
#Override public boolean onUnbind(Intent intent) {
return super.onUnbind(intent);
}
#Override public void onRebind(Intent intent) {
super.onRebind(intent);
}
#Override public void onDestroy() {
super.onDestroy();
running = false;
}
private void MyServiceRunningBackground() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
{
final int restartAlarmInterval = 6000;
final int resetAlarmTimer = 2*1000;
final Intent restartIntent = new Intent(this, esService.class);
restartIntent.putExtra("ALARM_RESTART_SERVICE_DIED", true);
final AlarmManager alarmMgr = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Handler restartServiceHandler = new Handler()
{
#Override
public void handleMessage(Message msg) {
PendingIntent pintent = PendingIntent.getService(getApplicationContext(), 0, restartIntent, 0);
alarmMgr.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + restartAlarmInterval, pintent);
sendEmptyMessageDelayed(0, resetAlarmTimer);
}
};
restartServiceHandler.sendEmptyMessageDelayed(0, 0);
}
}
private static final String TAG = "MyService";
}
create this new service and do what work you want to perform in your case saving data in background of your app, even if you app is killed, just start this service like you open new intent in your onCreate of activity. After that this service will be active even user kills app. Start this service like this
Intent intent = new Intent(MyActivity.this, MyService.class);
startService(intent);
I hope I am clear
I'm developing an Android Application to a college work. In this work I want to create a background service with a timer and when I close the application, timer still running. When I open the app, I can see the time since I've started service.
Well, my problem is that when I close the app, the background timer stops and not increments more.
Can you help me please?
Thanks a lot
My launcher class
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
private Button startButton;
private Button pauseButton;
private TextView timerValue;
Intent intent;
long timeSwapBuff = 0L;
long updatedTime = 0L;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
timerValue = (TextView) findViewById(R.id.timerValue);
startButton = (Button) findViewById(R.id.startButton);
startButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
intent = new Intent(MainActivity.this, CounterService.class);
startService(intent);
registerReceiver(broadcastReceiver, new IntentFilter(CounterService.BROADCAST_ACTION));
}
});
pauseButton = (Button) findViewById(R.id.pauseButton);
pauseButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
unregisterReceiver(broadcastReceiver);
stopService(intent);
}
});
}
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
updateUI(intent);
}
};
private void updateUI(Intent intent) {
int time = intent.getIntExtra("time", 0);
Log.d("Hello", "Time " + time);
int mins = time / 60;
int secs = time % 60;
timerValue.setText("" + mins + ":"
+ String.format("%02d", secs));
}
}
and here, the service class
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.SystemClock;
public class CounterService extends Service {
private Intent intent;
public static final String BROADCAST_ACTION = "com.javacodegeeks.android.androidtimerexample.MainActivity";
private Handler handler = new Handler();
private long initial_time;
long timeInMilliseconds = 0L;
#Override
public void onCreate() {
super.onCreate();
initial_time = SystemClock.uptimeMillis();
intent = new Intent(BROADCAST_ACTION);
handler.removeCallbacks(sendUpdatesToUI);
handler.postDelayed(sendUpdatesToUI, 1000); // 1 second
}
private Runnable sendUpdatesToUI = new Runnable() {
public void run() {
DisplayLoggingInfo();
handler.postDelayed(this, 1000); // 1 seconds
}
};
private void DisplayLoggingInfo() {
timeInMilliseconds = SystemClock.uptimeMillis() - initial_time;
int timer = (int) timeInMilliseconds / 1000;
intent.putExtra("time", timer);
sendBroadcast(intent);
}
#Override
public void onDestroy() {
super.onDestroy();
handler.removeCallbacks(sendUpdatesToUI);
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
you need to start your service in the onStop() method in your activity like this:
#Override
protected void onStop() {
super.onStop();
//write your code here to start your service
}
Kindly go through the link hope it will be helpful if you want to run timer in background Timer 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>
MainActivity.java
package playstore.com.a02backgroundtimer;
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);
}
}
Timer_Service.java
package playstore.com.a02backgroundtimer;
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);
}
}
Once the app starts you need to mention the hours you want timer for ... Then also after killing the app when you restarts the app it will show the start time of the timer ... Now you customize you application a per your requirement .