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;
}
}
Related
Currentlly I am implementing pattern lock application and I want to set limit when user enter wrong pattern many time.Example,If user enter wrong pattern at that time set limit(3 or 4 time limit) and set delay 30 second and after 30 second give permission to enter pattern.
So,If anyone know how i can do this please give idea of that.
Here this my Reciever
public class LockScreenReceiver extends DeviceAdminReceiver {
Context context;
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.i("Action...","..."+action);
//If the screen was just turned on or it just booted up, start your Lock Activity
if(action.equals(Intent.ACTION_SCREEN_OFF) || action.equals(Intent.ACTION_BOOT_COMPLETED))
{
Intent i = new Intent(context, MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
}
#Override
public void onPasswordFailed(Context ctxt, Intent intent) {
DevicePolicyManager mgr = (DevicePolicyManager) ctxt.getSystemService(Context.DEVICE_POLICY_SERVICE);
int no = mgr.getCurrentFailedPasswordAttempts();
if (no >= 3) {
context.startActivity(new Intent(context,ChangeActivity.class));
}
}
}
Service
public class LockScreenService extends Service {
DeviceAdminReceiver receiver;
#Override
public IBinder onBind(Intent intent) {
return null;
}
// Register for Lockscreen event intents
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
receiver = new LockScreenReceiver();
registerReceiver(receiver, filter);
startForeground();
return START_STICKY;
}
// Run service in foreground so it is less likely to be killed by system
private void startForeground() {
Notification notification = new NotificationCompat.Builder(this)
.setContentTitle(getResources().getString(R.string.app_name))
.setTicker(getResources().getString(R.string.app_name))
.setContentText("Running")
.setContentIntent(null)
.setOngoing(true)
.build();
startForeground(9999,notification);
}
#Override
#SuppressWarnings("deprecation")
public void onCreate() {
KeyguardManager.KeyguardLock key;
KeyguardManager km = (KeyguardManager)getSystemService(KEYGUARD_SERVICE);
//This is deprecated, but it is a simple way to disable the lockscreen in code
key = km.newKeyguardLock("IN");
key.disableKeyguard();
//Start listening for the Screen On, Screen Off, and Boot completed actions
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_BOOT_COMPLETED);
//Set up a receiver to listen for the Intents in this Service
receiver = new LockScreenReceiver();
registerReceiver(receiver, filter);
super.onCreate();
}
#Override
public void onDestroy() {
unregisterReceiver(receiver);
super.onDestroy();
}
}
Activity
public class MainActivity extends ActionBarActivity {
private Lock9View lock9View;
private static String MY_PREFS_NAME = "PatternLock";
private static String PATTERN_KEY;
SharedPreferences prefs;
Button btnChange;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
startService(new Intent(MainActivity.this, LockScreenService.class));
makeFullScreen();
setContentView(R.layout.activity_main);
btnChange = (Button)findViewById(R.id.btnChange);
btnChange.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent in = new Intent(MainActivity.this,ChangeActivity.class);
startActivity(in);
}
});
prefs = getSharedPreferences(MY_PREFS_NAME, MODE_PRIVATE);
lock9View = (Lock9View) findViewById(R.id.lock_9_view);
lock9View.setCallBack(new Lock9View.CallBack() {
#Override
public void onFinish(String password) {
PATTERN_KEY = prefs.getString("Pattern", "invalid");
if (PATTERN_KEY.equals("invalid")) {
Toast.makeText(MainActivity.this, "Options --> Create new Pattern", Toast.LENGTH_LONG).show();
} else {
if (password.equals(PATTERN_KEY)) {
Intent startMain = new Intent(Intent.ACTION_MAIN);
startMain.addCategory(Intent.CATEGORY_HOME);
startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(startMain);
}else{
Context context = getApplicationContext();
// Create layout inflator object to inflate toast.xml file
LayoutInflater inflater = getLayoutInflater();
// Call toast.xml file for toast layout
View toastRoot = inflater.inflate(R.layout.layout_toast3, null);
Toast toast = new Toast(context);
// Set layout to toast
toast.setView(toastRoot);
toast.setGravity(Gravity.HORIZONTAL_GRAVITY_MASK | Gravity.BOTTOM,
0, 0);
toast.setDuration(Toast.LENGTH_LONG);
toast.show();
}
}
}
});
}
private void makeFullScreen() {
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
if(Build.VERSION.SDK_INT < 19) { //View.SYSTEM_UI_FLAG_IMMERSIVE is only on API 19+
this.getWindow().getDecorView()
.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
} else {
this.getWindow().getDecorView()
.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE);
}
}
#Override
public void onBackPressed() {
return; //Do nothing!
}
public void unlockScreen(View view) {
//Instead of using finish(), this totally destroys the process
android.os.Process.killProcess(android.os.Process.myPid());
}
}
So,How i can achieve this...
Have a int field like failedCounter and increment it each time user inputs invalid patterns check if reached the limit then disable the input interface and have a handler to reset the value after the time delay.
int failedCount = 0;
final static int LIMIT = 5; //set your limit here
private void invalidPattern() {
if (++failedCount == LIMIT) {
//disable the input
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
//reset the failed count
faildCount = 0;
//Enable the input interface here
}
}, 30000); // 30Sec delay
}
}
Use this two methods -
ScheduledThreadPoolExecutor c1;
private void IncorrectCallCounter() {
if (failedCounter>=0)
{
c1.shutdownNow();
LockScreenFor30Second();
}else
{
if (c1!=null)
c1.shutdownNow();
}
c1 = new ScheduledThreadPoolExecutor(1);
c1.schedule(new Runnable() {
#Override
public void run() {
failedCounter=0;
c1.shutdownNow();
}
}, 15, TimeUnit.SECONDS);
}
ScheduledThreadPoolExecutor c2;
private void LockScreenFor30Second() {
//Lock Screen Here
c2 = new ScheduledThreadPoolExecutor(1);
c2.schedule(new Runnable() {
#Override
public void run() {
//Unlock Screen Here
c2.shutdownNow();
}
}, 30, TimeUnit.SECONDS);
}
Declare failedCounter globally
private int failedCounter=0;
And call this method when you detect wrong pattern -
failedCounter=failedCounter+1;
IncorrectCallCounter();
If user enter wrong pattern 4 times in 15 seconds then this will call LockScreenFor30Second method. and inside LockScreenFor30Second add your code.
Edit: Thanks for the replies. I ended up figuring out a nice solution (which I posted below) that uses a foreground service and broadcast receivers for those interested.
Original Question:
I have a simple count up timer using a handler which updates a textview. What Im trying to achieve is to
Continue the timer even if the app closes
Put out a notification and wake up the phone(if asleep) when the timer reaches its duration
I've read about using a service as it operates separate from the activity however all the examples I found seem more complicated for what I'm trying to do.
For reference heres my timer class
public class MyTimer implements Runnable {
MainActivity activity;
Handler handler;
TextView timerView;
long current_time,duration;
public MyTimer(MainActivity activity){
this.activity = activity;
this.handler = new Handler();
this.current_time = 0L;
timerView = (TextView) activity.findViewById(R.id.timerValue);
}
public MyTimer startTimer(int duration){
this.duration = duration;
handler.postDelayed(this,1000);
return this;
}
public MyTimer resetTimer(){
timerView.setText("0:00");
handler.removeCallbacks(this);
return this;
}
#Override
public void run() {
if(current_time == duration){
Toast.makeText(activity,"Timer is done",Toast.LENGTH_SHORT).show();
resetTimer();
return;
}
current_time += 1000;
int secs = (int) (current_time / 1000);
int minutes = secs / 60;
timerView.setText(Integer.toString(minutes) + ":" + String.format("%02d", secs%60));
handler.postDelayed(this, 1000);
}
}
timerView and two buttons for start/stop
I was also thinking of just storing the timer in a database during onStop/onDestroy and using the system time and its difference between the saved time to just update the timer that way. But that wouldn't solve the issue of issuing a notification and/or waking up the phone.
The examples that you find are not too complicated - in order to achieve what you want you'll need:
Bound Service which will keep track of elapsed time and will register alarm with AlarmManager
Fragment/Activity that can bind the above Service and execute methods like resetTimer(), startTimer(), getElapsedTime(). You need to perform a query to getElapsedTime() using a Handler, but 1 second timeout is too long (I'd use 0.1 second or similar).
Last note: you can't use the timeout that you set on postDelayed() in order to increment the timer. Better use something like this:
public void startTimer(long duration) {
mStartTime = System.currentTimeMillis();
mDuration = duration;
// register alarm with AlarmManager here
}
public long getElapsedTime() {
return System.currentTimeMillis() - mStartTime;
}
For those out there who might need an answer to this, after some research I decided the best approach was to use a foreground service and a handler because an alarm manager would be inefficient for such a short and constant timer.
So in Summary
In Service Class
Broadcasts the timer to main activity in which the MainActivity will receive it using a broadcastreceiver and updates the UI
Service class uses its own broadcast receiver to check if phone screen is on/off and updates the timer when it returns from sleep.
In Main Activity class
Receive the broadcast sent from the timer service and update the UI
Other logistics such as when to register/unregister broadcast receiver and sending actions to the service to either stop/start
Service Class:
//Timer service which uses a handler to monitor tick rate. Also uses a broadcast receiver
//to update the timer if the device was in sleep mode.
public class TimerService extends Service{
Intent intent;
public static final String TAG = TimerService.class.getSimpleName();
private final Handler handler = new Handler();
long currentTime, duration;
long timeSinceLastOn, elapsedTimeSinceOff;
#Override
public void onCreate() {
super.onCreate();
currentTime = duration = elapsedTimeSinceOff = 0L;
timeSinceLastOn = SystemClock.elapsedRealtime();
intent = new Intent(Constants.ACTION.BROADCAST_ACTION);
/**Starting Timer here**/
handler.removeCallbacks(timerThread);
handler.postDelayed(timerThread,0);
/**********************/
/**Broadcast receiver to check if the screen is on **/
IntentFilter screenStateFilter = new IntentFilter();
screenStateFilter.addAction(Intent.ACTION_SCREEN_ON);
screenStateFilter.addAction(Intent.ACTION_SCREEN_OFF);
registerReceiver(broadcastReceiver, screenStateFilter);
/***************************************************/
}
#Override
/**Depending on action issued by MainActivity either puts service in
*foreground with duration or destroys the service**/
public int onStartCommand(Intent intent, int flags, int startId) {
if(intent != null) {
if (intent.getAction().equals(Constants.ACTION.STARTFOREGROUND_ACTION)) {
if (intent.hasExtra(Constants.TIMER.DURATION))
duration = intent.getLongExtra(Constants.TIMER.DURATION, 0);
startForeground(Constants.NOTIFICATION_ID.FOREGROUND_SERVICE, createTimerNotification());
} else if (intent.getAction().equals(Constants.ACTION.STOPFOREGROUND_ACTION)) {
stopForeground(true);
stopSelf();
}
}
return START_STICKY;
}
/**Thread the handler uses to push to message queue. This creates a timer effect.**/
private Runnable timerThread = new Runnable() {
#Override
public void run() {
if(currentTime == duration){
stopSelf();
return;
}
currentTime += 1000;
sendTimerInfo();
handler.postDelayed(this,1000);
}
};
/**Broadcasts the timer in which the MainActivity will receive it and update the UI**/
private void sendTimerInfo(){
Log.d(TAG, "timer running: tick is " + currentTime);
intent.putExtra(Constants.TIMER.CURRENT_TIME, currentTime);
sendBroadcast(intent);
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG,"timer service finished");
unregisterReceiver(broadcastReceiver);
handler.removeCallbacks(timerThread);
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
/******************** Broadcast Receiver To Check if Screen is on**************************************/
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
handler.removeCallbacks(timerThread);
/**If the screen is back on then update the timer and start it again**/
if(intent.getAction().equals(Intent.ACTION_SCREEN_ON)){
Log.d(TAG,"Screen is turned on");
elapsedTimeSinceOff = SystemClock.elapsedRealtime() - timeSinceLastOn;
Log.d(TAG," screen was off and updating current time by"+elapsedTimeSinceOff);
currentTime += elapsedTimeSinceOff;
handler.postDelayed(timerThread,0);
}
/**Turns off the timer when the screen is off**/
else if(intent.getAction().equals(Intent.ACTION_SCREEN_OFF)){
Log.d(TAG,"Screen is turned off");
timeSinceLastOn = SystemClock.elapsedRealtime();
}
}
};
/**Since this is foreground service it must have a notification**/
private Notification createTimerNotification() {
Intent notificationIntent = new Intent(this, MainActivity.class);
notificationIntent.setAction(Constants.ACTION.MAIN_ACTION);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
notificationIntent,0);
Bitmap icon = BitmapFactory.decodeResource(getResources(),
R.mipmap.ic_launcher);
Notification notification = new NotificationCompat.Builder(this)
.setContentTitle("Service Timer")
.setTicker("Count up timer")
.setContentText("timer")
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(Bitmap.createScaledBitmap(icon, 128, 128, false))
.setContentIntent(pendingIntent)
.setOngoing(true)
.build();
return notification;
}
}
MainActivity:
public class MainActivity extends Activity {
TextView timerView;
Intent timerService;
//Example duration of 3minutes
long currentTime, duration = 180000;
#Override
protected void onStart() {
super.onStart();
timerService = new Intent(this, TimerService.class);
//Register broadcast if service is already running
if(isMyServiceRunning(TimerService.class)){
registerReceiver(broadcastReceiver, new IntentFilter(Constants.ACTION.BROADCAST_ACTION));
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button startButton, stopButton;
timerView = (TextView) findViewById(R.id.timerValue);
startButton = (Button) findViewById(R.id.startButton);
stopButton = (Button) findViewById(R.id.stopButton);
//Button to Start the service when pushed
startButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
if(!isMyServiceRunning(TimerService.class)) {
timerService.setAction(Constants.ACTION.STARTFOREGROUND_ACTION);
timerService.putExtra(Constants.TIMER.DURATION,duration);
startService(timerService);
registerReceiver(broadcastReceiver, new IntentFilter(Constants.ACTION.BROADCAST_ACTION));
}
}
});
//Button to stop the service when pushed
stopButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
if(isMyServiceRunning(TimerService.class)) {
timerView.setText("0:00");
timerService.setAction(Constants.ACTION.STOPFOREGROUND_ACTION);
startService(timerService);
unregisterReceiver(broadcastReceiver);
}
}
});
}
#Override
protected void onResume() {
super.onResume();
if(!isMyServiceRunning(TimerService.class)) {
//Resets timer if no service is running
timerView.setText("0:00");
}
}
#Override
protected void onStop() {
super.onStop();
if(isMyServiceRunning(TimerService.class)) {
unregisterReceiver(broadcastReceiver);
Log.d(MainActivity.class.getSimpleName(), "unregistered broadcast");
}
}
/******************** Broadcast Receiver **************************************/
//Receives the broadcast sent out by the service and updates the UI accordingly.
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if(!updateUI(intent)){
if(!updateUI(timerService)){
timerService.setAction(Constants.ACTION.STOPFOREGROUND_ACTION);
startService(timerService);
showTimerCompleteNotification();
}
}
}
};
//Receives the timer from the service and updates the UI
public boolean updateUI(Intent intent){
if(!intent.hasExtra(Constants.TIMER.CURRENT_TIME)) return false;
this.currentTime = intent.getLongExtra(Constants.TIMER.CURRENT_TIME, 0L);
if(this.currentTime == duration){
timerView.setText("0:00");
Toast.makeText(this,"Timer done",Toast.LENGTH_SHORT).show();
return false;
}
int secs = (int) (currentTime / 1000);
int minutes = secs / 60;
timerView.setText(Integer.toString(minutes) + ":" + String.format("%02d", secs%60));
return true;
}
/******************************************************************************************/
/************* Helper Methods ****************************/
private void showTimerCompleteNotification() {
Intent resultIntent = new Intent(this, MainActivity.class);
PendingIntent resultPendingIntent =
PendingIntent.getActivity(
this,
0,
resultIntent,
PendingIntent.FLAG_UPDATE_CURRENT
);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("Timer Done!")
.setContentText("Congrats")
.setContentIntent(resultPendingIntent)
.setColor(Color.BLACK)
.setLights(Color.BLUE, 500, 500)
.setDefaults(NotificationCompat.DEFAULT_VIBRATE)
.setDefaults(NotificationCompat.DEFAULT_SOUND)
.setStyle(new NotificationCompat.InboxStyle());
// Gets an instance of the NotificationManager service
final NotificationManager mNotifyMgr =
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
// Builds the notification and issues it.
mNotifyMgr.notify(Constants.NOTIFICATION_ID.FOREGROUND_SERVICE, mBuilder.build());
//Cancel the notification after a little while
Handler h = new Handler();
long delayInMilliseconds = 5000;
h.postDelayed(new Runnable() {
public void run() {
mNotifyMgr.cancel(Constants.NOTIFICATION_ID.FOREGROUND_SERVICE);
}
}, delayInMilliseconds);
}
private boolean isMyServiceRunning(Class<?> serviceClass) {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
}
Constants class:
package com.example.admin.servicetimer.service;
public class Constants {
public interface ACTION {
public static String MAIN_ACTION = "com.fahadhd.foregroundservice.action.main";
public static final String STARTFOREGROUND_ACTION = "com.fahadhd.foregroundservice.action.startforeground";
public static final String STOPFOREGROUND_ACTION = "com.fahadhd.foregroundservice.action.stopforeground";
public static final String BROADCAST_ACTION = "com.fahadhd.foregroundservice.action.broadcast";
}
public interface TIMER {
public static final String CURRENT_TIME = "com.fahadhd.foregroundservice.timer.current_time";
public static final String DURATION = "com.fahadhd.foregroundservice.timer.duration";
}
public interface NOTIFICATION_ID {
public static int FOREGROUND_SERVICE = 1;
}
}
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;
}
}
Hello every one I am developing an app in which I am getting battery level and displaying it in a textview. Now I want to increase this level 1% after each 5 sec and want to show this increment.
I have tried following code but i can't get my output
java code
public class ChargingActivity extends Activity {
TextView textBatteryLevel = null;
int level;
private BroadcastReceiver mBatInfoReceiver = new BroadcastReceiver(){
#Override
public void onReceive(Context ctxt, Intent intent) {
level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
Timer timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
// add your stuff here
level++;
}
}
, 5000);
textBatteryLevel.setText(String.valueOf(level) + "%");
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.chargingactivity);
textBatteryLevel = (TextView) findViewById(R.id.btrylevel);
this.registerReceiver(this.mBatInfoReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
But Level of Battery is not increasing after each 5 sec. What I am doing wrong?
I'd suggest using the postDelayed(...) method of the View class and also don't use an actual BroadcastReceiver.
For example, Intent.ACTION_BATTERY_CHANGED is a STICKY broadcast and as such doesn't need a BroadcastReceiver to handle it. Instead if we pass null as the first parameter to the registerReceiver(...) method, no receiver is actually registered but the return from that call is the Intent from the sticky broadcast. Example...
Intent batteryIntent = registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
The next step is to setup the 5 second update for the TextView. The Android View class has a postDelayed(...) method which accepts a Runnable parameter as well as a delay in milliseconds. Example...
textBatteryLevel.postDelayed(levelChecker, 5000);
The postDelayed(...) method of View is a one-shot (non-repeating) 'post' so make sure it is reset within the run() method of the Runnable each time it is called.
I haven't tested the following code but I think it should work. Bear in mind however, there's no guarantee that the level of battery charge will change within any 5 second period. It probably takes about 1 minute per 1% to charge my tablet and similar on my phone so I certainly wouldn't expect to see an update to the TextView every 5 seconds.
public class ChargingActivity extends Activity {
TextView textBatteryLevel = null;
int level;
LevelChecker levelChecker = new LevelChecker();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.chargingactivity);
textBatteryLevel = (TextView) findViewById(R.id.btrylevel);
// Get the current battery level
Intent batteryIntent = registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
level = batteryIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
// Set the starting level
textBatteryLevel.setText(String.valueOf(level) + "%");
}
#Override
protected void onResume() {
super.onResume();
textBatteryLevel.postDelayed(levelChecker, 5000);
}
#Override
protected void onPause() {
textBatteryLevel.removeCallbacks(levelChecker);
}
private class LevelChecker extends Runnable {
#Override
public void run() {
Intent batteryIntent = registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
int currentLevel = batteryIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
if (currentLevel != level) {
level = currentLevel;
textBatteryLevel.setText(String.valueOf(level) + "%");
}
textBatteryLevel.postDelayed(levelChecker, 5000);
}
}
}
Move text changing code inside TimerTask.
Timer timer = new Timer();
private BroadcastReceiver mBatInfoReceiver = new BroadcastReceiver(){
#Override
public void onReceive(Context ctxt, Intent intent) {
level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
timer.schedule(new TimerTask() {
public void run() {
level++;
textBatteryLevel.setText(String.valueOf(level) + "%");
}
}
, 5000);
}
};
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.