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);
}
};
Related
Can I get a code for android app which run in background and continuously checks the battery percentage and notify me when battery level reaches to 7 percentage,
I tried its installing but not showing the app on screen.
Here we listen to a Intent (ACTION_BATTERY_CHANGED) and register a receiver when the intent is fired. In ActionScript, this is i believe is DispatchEvent, and we would call mBatInfoReceiver and get the current level of our battery life and put that int value to our textfield or TextView.
public class Main extends Activity {
private TextView contentTxt;
private BroadcastReceiver mBatInfoReceiver = new BroadcastReceiver(){
#Override
public void onReceive(Context arg0, Intent intent) {
int level = intent.getIntExtra("batterylevel", 7);
contentText.setText(String.valueOf(level) + "%");
}
};
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main_layout);
contentText = (TextView) this.findViewById(R.id.mspaceTxt);
this.registerReceiver(this.mBatInfoReceiver,
new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
}
}
Currently im writing a camera app which should take pictures in a regular time intervall. For this my activity creates a IntentService, which starts a TimerTask with the desired delay. First time I start my app everything works fine. The pictures are taken in an regular time intervall of 10 seconds. But if i pause and resume my application the pictures are taken more frequently.
Here is my activity:
public class AndroidCameraExample extends Activity implements PictureTakenListener {
private static String CLASSTAG = "Android Surveillance Camera";
private Button captureButton;
private Context context;
private LinearLayout layoutForPreview;
private SurveillanceCamera camera;
// for calling the background service
private Intent backgroundServiceIntent = null;
// will send a notification if time has lapsed and we should
// take a new picture
private SurveillanceBroadcastReceiver receiver = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = this;
layoutForPreview = (LinearLayout) findViewById(R.id.camera_preview);
camera = new SurveillanceCamera(this, layoutForPreview);
captureButton = (Button) findViewById(R.id.button_capture);
captureButton.setOnClickListener(PictureCaptureListener);
camera.addPictureTakenListener(this);
startSurveillance();
}
private void startSurveillance() {
Settings.surveillanceIsActive = true;
camera.start();
startBackroundService();
registerBroadcastReceiver();
}
private void stopSurveillance() {
Settings.surveillanceIsActive = false;
if (receiver != null) {
unregisterReceiver(receiver);
receiver = null;
}
if (backgroundServiceIntent != null) {
stopService(backgroundServiceIntent);
backgroundServiceIntent = null;
}
camera.stop();
}
private void startBackroundService() {
if (isServiceRunning(SurveillanceBackgroundService.class)) {
Log.d(Settings.APPTAG, "The Service is already running");
}
if (backgroundServiceIntent == null) {
backgroundServiceIntent = new Intent(this, SurveillanceBackgroundService.class);
startService(backgroundServiceIntent);
}
}
private boolean isServiceRunning(Class<?> serviceClass) {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
private void registerBroadcastReceiver() {
if (receiver == null) {
IntentFilter filter = new IntentFilter(SurveillanceBroadcastReceiver.ACTION_RESP);
filter.addCategory(Intent.CATEGORY_DEFAULT);
receiver = new SurveillanceBroadcastReceiver();
registerReceiver(receiver, filter);
}
}
public void onResume() {
super.onResume();
startSurveillance();
}
#Override
protected void onPause() {
super.onPause();
stopSurveillance();
}
class SurveillanceBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
camera.takePicture();
}
}
My Service
public class SurveillanceBackgroundService extends IntentService {
#Override
protected void onHandleIntent(Intent intent) {
Timer t = new Timer();
t.schedule(new TimerTask() {
#Override
public void run() {
notifyTimeLapsed();
}
}, 100, Settings.timeIntervall * 1000);
}
private void notifyTimeLapsed() {
Intent broadcastIntent = new Intent();
broadcastIntent.setAction(SurveillanceBroadcastReceiver.ACTION_RESP);
broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT);
sendBroadcast(broadcastIntent);
}
}
I aleady checked that the service isn't running (in background) while the app is paused and started again afterwards, so I don't see any reason why the pictureTaking Event should be triggered more ofter after resuming.
I also use a small wrapper class for camera handling but i don't think this causes the problem. if you need to code for suggesting any solutions i will post it here anyway.
Any hints or help for this`?
EDIT: I overwrite onDestroy and onStart to Cancel the Timer and start it again but the problem stays the same. After resume more pictures are taken than before.
UPDATE: If I remove the method onStart the timer seems to get canceled directly and isn't started again? I added some Logger output in the methods and get this information:
05-15 18:56:03.478: I/com.test.androidcameraexample(10061): SurveillanceBackgroundService onHandleIntent
05-15 18:56:03.498: I/com.test.androidcameraexample(10061): SurveillanceBackgroundService onDestroy
#Override
protected void onHandleIntent(Intent intent) {
if (t == null) {
t = new Timer();
t.schedule(new TimerTask() {
#Override
public void run() {
notifyTimeLapsed();
}
}, 100, Settings.timeIntervall * 1000);
}
}
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
if (t == null) {
t = new Timer();
t.schedule(new TimerTask() {
#Override
public void run() {
notifyTimeLapsed();
}
}, 100, Settings.timeIntervall * 1000);
}
}
#Override
public void onDestroy() {
super.onDestroy();
t.cancel();
t = null;
}
My original answer was this:
You need to call either Timer.cancel() or TimerTask.cancel()
on the Timer or TimerTask that the service created, or else the
timer task will keep running in a background thread.
And then I added this:
To get this to work reliably, you could specify one Intent action
for starting the timer, and another action for stopping the timer.
But, there is actually a big (and subtle) problem with storing a Timer variable in an IntentService. An IntentService creates its own background thread, and it quickly kills itself (after onHandleIntent () returns) if there are no intents in its queue -- which would also mean your Timer value would be lost. So, even if you have 2 intent actions (for starting and stopping the timer), there is no way to guarantee that the stop action would have access to the original Timer value (since it could very well be creating a brand new IntentService instance)!
So, I recommend that you use the AlarmManager to schedule periodic alarms. See here for some training on how to do that.
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 have a following chronometer implementation. I'd like to use it inside Service then sent its output to my fragment. The problem is that Service has no findViewById() because obviously it has no View at all. Is there any way I can get the chronometer to work inside Service and if not what can I use instead?
code:
Chronometer chronometer = (Chronometer) findViewById(R.id.chronometer);
chronometer.setBase(SystemClock.elapsedRealtime());
chronometer.setOnChronometerTickListener(
new Chronometer.OnChronometerTickListener() {
#Override
public void onChronometerTick(Chronometer chronometer) {
// TODO Auto-generated method stub
long myElapsedMillis = SystemClock.elapsedRealtime() - chronometer.getBase();
String strElapsedMillis = String.valueOf(myElapsedMillis);
// Toast.makeText(AndroidChronometer.this, strElapsedMillis, Toast.LENGTH_SHORT).show();
TextView tw5 = (TextView) findViewById(R.id.textView2);
tw5.setText(strElapsedMillis.format("%d min : %d sec",
TimeUnit.MILLISECONDS.toMinutes(myElapsedMillis),
TimeUnit.MILLISECONDS.toSeconds(myElapsedMillis) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(myElapsedMillis))));
}
}
);
chronometer.start();
One option is just to use
postDelayed(Runnable r, long milliseconds)
to trigger your runnable update method for whatever you update period is, without using a service. And then update the UI in your update method.
Another option is to use AsyncTask instead of Service, if your intention is to do something in the background. AsyncTask has access to the UI on its onProgressUpdate() method and you can do your stuff there.
If you have to use a Service, then you have to broadcast from the service to the UI activity and let the UI Activity do the view update:
This in your main activity:
private StatusReceiver mReceiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
...
mReceiver = new StatusReceiver();
...
}
#Override
protected void onStart() {
// Register the broadcast receiver
IntentFilter filter = new IntentFilter();
filter.addAction(getString(R.string.ACTION_UPDATE_CHRONO));
filter.addCategory(Intent.CATEGORY_DEFAULT);
registerReceiver(mReceiver, filter);
...
}
#Override
protected void onStop() {
...
unregisterReceiver(mReceiver);
...
}
public class StatusReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if( action.equals(getString(R.string.ACTION_UPDATE_CHRONO)) ) {
// Do your UI stuff here
}
}
}
In the service class:
private void broadcast(String status, Exception error) {
Intent broadcastIntent = new Intent((Intent) getText(R.string.ACTION_UPDATE_CHRONO));
broadcastIntent.putExtra("STATUS", status);
broadcastIntent.putExtra("ERROR", error);
sendBroadcast(broadcastIntent);
}
Call this method when you want to communicate some "status" to your main activity, like "Time for update" or "set chrono to " + x + "milli".
my application requires a service that changes the system wallpaper in a particular time interval how should I implement this, please help???
Create your service class
class WallpaperService extends IntentService {
#Override
protected void onHandleIntent(Intent intent) {
Timer progressTimer = new Timer();
timeTask = new ProgressTimerTask();
progressTimer.scheduleAtFixedRate(timeTask, 0, 1000);
}
private class ProgressTimerTask extends TimerTask {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
int currenMinutes = 0; // set your time here
changeWallpapers(currentMinutes);
}
});
}
}
private void changeWallpapers(int minutes) {
if(minutes == 1)
layout.setBackGround(Color.RED);
if(minutes == 2)
layout.setBackGround(Color.BLUE);
}
}
}
And then call your service Intent where your want
Well, I have implemented this function. I register an Alarm in the system and connect it to a BroadcastReceiver. When the BroadcastReceiver is triggered, in the OnReceive() method, you can set a wallpaper for the system.