I am trying to monitor the current battery status using a Service. I wrote some code and I can show the battery level using the log once but I want to monitor the battery level according to a timer every 5 seconds.
public class ServiceStatusUpdate extends Service {
GPSTracker gps;
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
while (true) {
new Handler().postDelayed(new Runnable() {
public void run() {
batteryLevel();
Log.e("Status changed", "Status changed");
}
}, 5000);
return START_STICKY;
}
}
private void batteryLevel() {
BroadcastReceiver batteryLevelReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
context.unregisterReceiver(this);
int rawlevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
int level = -1;
if (rawlevel >= 0 && scale > 0) {
level = (rawlevel * 100) / scale;
}
Log.e("Batarry status iss", level + "mm");
}
};
IntentFilter batteryLevelFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
registerReceiver(batteryLevelReceiver, batteryLevelFilter);
return;
}
}
MainActivity.java:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startService(new Intent(this, ServiceStatusUpdate.class));
}
}
manifest.xml source:
<receiver
android:name=".OnBootReceiver"
android:enabled="true"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<service
android:name=".ServiceStatusUpdate"
android:enabled="true" />
OnBootReceiver:
public class OnBootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
//int batteryLevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
Intent serviceLauncher = new Intent(context, ServiceStatusUpdate.class);
context.startService(serviceLauncher);
}
}
}
I am also trying to send an HTTP request every /xxx times. The HTTP request will include some text, the battery status, and latitude and longitude.
I know how to send the request with parameters, but my service is working only once.
You are unregistering the batteryLevelReceiver after the first time it receives a broadcast. Remove this line from onReceive to continue to receive broadcasts:
context.unregisterReceiver(this);
Also, you probably only want to register and unregister your broadcast receiver once when the server is created/destroyed so you should register in onCreate and unregister in onDestroy.
Here is some code that should be very close to what you want. Note that all of this will run on the UI thread currently.
public class ServiceStatusUpdate extends Service {
private static final int CHECK_BATTERY_INTERVAL = 5000;
private GPSTracker gps;
private double batteryLevel;
private Handler handler;
private BroadcastReceiver batInfoReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent batteryIntent) {
int rawlevel = batteryIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
int scale = batteryIntent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
if (rawlevel >= 0 && scale > 0) {
batteryLevel = (rawlevel * 100.0) / scale;
}
Log.e("Battery status is", batteryLevel + "mm");
}
};
private Runnable checkBatteryStatusRunnable = new Runnable() {
#Override
public void run() {
//DO WHATEVER YOU WANT WITH LATEST BATTERY LEVEL STORED IN batteryLevel HERE...
// schedule next battery check
handler.postDelayed(checkBatteryStatusRunnable, CHECK_BATTERY_INTERVAL);
Log.e("Battery status is", batteryLevel + "mm cached");
}
};
#Override
public void onCreate() {
handler = new Handler();
handler.postDelayed(checkBatteryStatusRunnable, CHECK_BATTERY_INTERVAL);
registerReceiver(batInfoReceiver,
new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
}
#Override
public void onDestroy() {
unregisterReceiver(batInfoReceiver);
handler.removeCallbacks(checkBatteryStatusRunnable);
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
}
Related
I make a service for countdown timer, in activity i put a text view for show time every seconds: 100 - 0, but when i leave activity and back to that. i see timer as run very fast, but i want to this run just every second. where is problem ?
MainActivity:
public static final String mBroadcastIntegerAction = "com.example.broadcast.integer";
private IntentFilter mIntentFilter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
showTime = (TextView) findViewById(R.id.textView1);
mIntentFilter = new IntentFilter();
mIntentFilter.addAction(mBroadcastIntegerAction);
Intent serviceIntent = new Intent(this, AppServiceDay.class);
startService(serviceIntent);
}
#Override
public void onResume() {
super.onResume();
registerReceiver(mReceiver, mIntentFilter);
}
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(mBroadcastIntegerAction)) {
int second = intent.getIntExtra("Time", 0);
showTime.setText("" + second);
}
}
};
#Override
protected void onPause() {
registerReceiver(mReceiver, mIntentFilter);
// unregisterReceiver(mReceiver);
super.onPause();
}
Service:
public class AppServiceDay extends Service {
CountDownTimer cdt;
public static Handler mHandler;
int downer = 1000;
int time = 100;
int mainTime = 100000;
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
cdt = new CountDownTimer(mainTime, downer) {
#Override
public void onTick(long millisUntilFinished) {
time -= 1;
Intent broadcastIntent = new Intent();
broadcastIntent.setAction(MainActivity.mBroadcastIntegerAction);
broadcastIntent.putExtra("Time", time);
sendBroadcast(broadcastIntent);
}
#Override
public void onFinish() {
time = 100;
this.start();
}
};
cdt.start();
return super.onStartCommand(intent, flags, startId);
}
#Override
public IBinder onBind(Intent arg0) {
return null;
}
}
onStartCommand is triggered everytime startService is called and in onStartCommand you are creating new countdown object,
Add a null check before creating new countdown object it will fix your duplicate timer running at same time.
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
If(cdt == null) {
cdt = new CountDownTimer(mainTime, downer) {
#Override
public void onTick(long millisUntilFinished) {
time -= 1;
Intent broadcastIntent = new Intent();
broadcastIntent.setAction(MainActivity.mBroadcastIntegerAction);
broadcastIntent.putExtra("Time", time);
sendBroadcast(broadcastIntent);
}
#Override
public void onFinish() {
time = 100;
this.start();
}
};
cdt.start();
}
return super.onStartCommand(intent, flags, startId);
}
How to run long running service in android in all devices greater than api level 16. I have written below code for the service but somehow not working for api 17 - 19. and its working for all devices above 19 api level. Please have a look and suggest me how to do it. I am new android and writing service for the first time.
below is code
public class MyService extends Service {
public int counter = 0;
public ViksitService(Context applicationContext) {
super();
Log.i("HERE", "here I am!");
}
public MyService() {
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
startTimer();
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
Log.i("EXIT", "ondestroy!");
Intent broadcastIntent = new Intent("MyService_RESTART_SERVICE");
sendBroadcast(broadcastIntent);
stoptimertask();
}
private Timer timer;
private TimerTask timerTask;
long oldTime = 0;
public void startTimer() {
//set a new Timer
timer = new Timer();
//initialize the TimerTask's job
initializeTimerTask();
//schedule the timer, to wake up every 1 second
timer.schedule(timerTask, 1000, 1000); //
}
/**
* it sets the timer to print the counter every x seconds
*/
public void initializeTimerTask() {
timerTask = new TimerTask() {
public void run() {
Log.i("in timer", "in timer ++++ " + (counter++));
}
};
}
/**
* not needed
*/
public void stoptimertask() {
//stop the timer, if it's not already null
if (timer != null) {
timer.cancel();
timer = null;
}
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
below is broadcast reciever :
public class ServiceRestarterBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.i(ServiceRestarterBroadcastReceiver.class.getSimpleName(), "Service Stops! Oooooooooooooppppssssss!!!!");
context.startService(new Intent(context, MyService.class));;
}
}
below is manifest :
<service
android:name=".services.MyService"
android:enabled="true"
android:exported="true">
</service>
<receiver
android:name=".services.ServiceRestarterBroadcastReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="MyService_RESTART_SERVICE"/>
</intent-filter>
</receiver>
I m new on android
I want to start two services and one service sendbroadcast another will catch this broadcast but it is not working even if I register another service in this broadcasting
here is my code am I doing something wrong ?
Thanks advice.
public class MainActivity extends Activity {
Intent i;
Intent i2;
static final String LOG_TAG = "ServiceActivity";
/**
* Called when the activity is first created.
*/
#Override
public void onCreate(Bundle savedInstanceState) {
Log.d(LOG_TAG, "onCreate");
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
//Start service
i = new Intent(this, com.example.user.sensorservicetest.SimpleService.class);
i2= new Intent(this,com.example.user.sensorservicetest.AnotherService.class);
Log.d(LOG_TAG, "onCreate/startService");
}
#Override
public void onResume() {
super.onResume();
Log.d(LOG_TAG, "onResume/registering receiver");
//Register BroadcastReceiver to receive accelerometer data from service
startService(i);
startService(i2);
}
}
#Override
public void onPause() {
super.onPause();
Log.d(LOG_TAG, "onPause/unregistering receiver");
stopService(i);
stopService(i2);
}
#Override
protected void onStop() {
super.onStop();
Log.d(LOG_TAG, "onStop");
stopService(i);
stopService(i2);
}
}
SimpleService
public class SimpleService extends Service implements SensorEventListener {
private String reading;
private SensorManager mgr;
private List<Sensor> sensorList;
static final String LOG_TAG = "SimpleService";
Intent intent = new Intent("com.practice.SimpleService.MY_ACTION");
final static String MY_ACTION = "com.practice.SimpleService.MY_ACTION";
#Override
//public void onStartCommand() {
public void onCreate() {
Log.d(LOG_TAG, "onStartCommand");
mgr = (SensorManager) getSystemService(SENSOR_SERVICE);
sensorList = mgr.getSensorList(Sensor.TYPE_ACCELEROMETER);
for (Sensor sensor : sensorList) {
mgr.registerListener(this, sensor,
SensorManager.SENSOR_DELAY_NORMAL);
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent,flags,startId);
}
#Override
public void onDestroy() {
Log.d(LOG_TAG, "onDestroy");
mgr.unregisterListener(this);
super.onDestroy();
}
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
#Override
public void onSensorChanged(SensorEvent event) {
Log.d(LOG_TAG, "onSensorChanged");
StringBuilder builder = new StringBuilder();
for (int i = 0; i < event.values.length; i++) {
builder.append(" [");
builder.append(i);
builder.append("] = ");
builder.append(event.values[i]);
builder.append("\n");
}
reading = builder.toString();
//Send back reading to Activity
intent.putExtra("measurement", reading);
sendBroadcast(intent);
}
}
AnotherService
public class AnotherService extends Service {
static final String TAG = "AnotherService";
private AnotherServiceReceiver anotherServiceReceiver = new AnotherServiceReceiver();
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG,"onStartCommand");
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("com.practice.SimpleService.MY_ACTION");
registerReceiver(anotherServiceReceiver, intentFilter);
return super.onStartCommand(intent,flags,startId);
}
#Override
public void onDestroy() {
if (anotherServiceReceiver != null)
unregisterReceiver(anotherServiceReceiver);
super.onDestroy();
}
public static class AnotherServiceReceiver extends BroadcastReceiver {
static final String receiverTag = "AnotherServiceReceiver";
#Override
public void onReceive(Context context, Intent intent) {
Log.d(receiverTag, "onReceive");
String measurement = intent.getStringExtra("measurement");
Log.d(receiverTag, "measurement - 2 : " + measurement);
}
}
}
Manifest
<service android:name=".SimpleService" ></service>
<service android:name=".AnotherService"></service>
<receiver android:name=".AnotherService$AnotherServiceReceiver" android:enabled="true">
<intent-filter>
<action android:name="here is problem I think"
</intent-filter>
</receiver>
According #Evgeniy Mishustin answer (thanks to him)
Solution is adding service in manifest xml file now working each service communication
<service android:name=".SimpleService" ></service>
<service android:name=".AnotherService"></service>
<receiver android:name=".AnotherService$AnotherServiceReceiver" android:enabled="true">
<intent-filter>
<action android:name="com.practice.SimpleService.MY_ACTION"></action>
</intent-filter>
</receiver>
</application>
I want do develop an Android App, which calculates the battery app
So here's my idea how to do that: When the user starts the app, the app gets the battery level of the phone (For example: 80%). And after 1h the app gets the battery status again (Then it is for example: 76%). The calculation: in 1h the battery loses 4%, that means the battery will last about 20h (80/4)
I know, how to get the battery status, etc..
My question: How can I set the countdown for 1h in the background? There shouldn't be any textView where the countdown is displayed. The coundown needs to run in the background. How can I do that?
I googled and found this, but this isn't working: (I put these method in onCreate()
CountDownTimer countDownTimer = new CountDownTimer(5000, 1000) {
#Override
public void onTick(long millisUntilFinished) {
IntentFilter intFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
BroadcastReceiver batteryLevelReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
}
};
}
#Override
public void onFinish() {
BroadcastReceiver batteryLevelReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
Toast toast = Toast.makeText(context, "Battery: " + level/4, Toast.LENGTH_LONG); // this is just, to check, if the countDown is still running
toast.show();
}
};
}
};
You need register once your broadcast receiver.
//in Oncreate
...
IntentFilter intFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
BatteryReceiver batteryReceiver = new BatteryReceiver();
registerReceiver(batteryReceiver , intFilter);
...
public class BatteryReceiver extends BroadcastReceiver {
int startlevel = 0;
long lastUpdateTime = 0;
boolean isStartCheck = false;
#Override
public void onReceive(Context context, Intent intent) {
if(!isStartCheck){
startlevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
lastUpdateTime = System.currentTimeMillis();
isStartCheck = true;
} else {
if((System.currentTimeMillis() - lastUpdateTime)/1000 > 3600) {
// 1h was going. do your work.
reset();
}
}
}
public void reset() {
lastUpdateTime = System.currentTimeMillis();
isStartCheck = false;
startLevel = 0;
}
}
I want to display Battery level stats in my app. How can we obtain such information like Battery Power, Battery Voltage, etc.?
BroadcastReceiver batteryLevelReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
context.unregisterReceiver(this);
int rawlevel = intent.getIntExtra("level", -1);
int scale = intent.getIntExtra("scale", -1);
int level = -1;
if (rawlevel >= 0 && scale > 0) {
level = (rawlevel * 100) / scale; /* This is your battery level */
}
}
};
IntentFilter batteryLevelFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
registerReceiver(batteryLevelReceiver, batteryLevelFilter);
}
or check out this guy (who wrote the code I posted): http://mihaifonoage.blogspot.com/2010/02/getting-battery-level-in-android-using.html
Is this of any help?
public class Main extends Activity {
private TextView contentTxt;
private BroadcastReceiver mBatInfoReceiver = new BroadcastReceiver(){
#Override
public void onReceive(Context arg0, Intent intent) {
// TODO Auto-generated method stub
int level = intent.getIntExtra("level", 0);
contentTxt.setText(String.valueOf(level) + "%");
}
};
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
contentTxt = (TextView) this.findViewById(R.id.monospaceTxt);
this.registerReceiver(this.mBatInfoReceiver,
new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
}
}
Also, see this.