If you run this code, what does isCharging give back when it's charging and when it's full?
public void onReceive(Context context, Intent intent) {
IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent batteryStatus = context.registerReceiver(null, ifilter);
int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||
status == BatteryManager.BATTERY_STATUS_FULL;
}
isCharging will be true if either of those conditions are met.
Related
I have a really bad problem.
I have one notification service which works fine. When I test it works just fine I turn off/on 10 times to see if service failed or return null but it works fine. I also close application many time to see if its return null but it works fine.
but sometimes when I'm using my phone application show force close such as when I'm using other apps, crash system of firebase say getaction or intent is null.
What am I doing wrong?
crash system
this is my service code:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
sp = getSharedPreferences("accdata", Context.MODE_PRIVATE);
namesaveget = sp.getString("nameacc","No Account");
int getwhattodo = intent.getIntExtra("service_call",0);
if (intent == null || intent.getAction() == null || getwhattodo == 0) {
Log.e("receiver","service faild");
Crashlytics.log("service faild to call");
if (getwhattodo == 0) {
stopSelf();
}
}
if (intent != null && getwhattodo == 2) {
Log.e("receiver","call done");
createNotificationChannel();
showMainNotification();
showSubNotifications();
Crashlytics.log("service call noti");
}
return START_STICKY;
}
this is my receiver that call my service:
#Override
public void onReceive(Context context, Intent intent) {
Log.e("receiver","work");
if (isNetworkConnected(context) == true) {
Log.e("receiver","wifi on");
Intent i = new Intent(context,ServiceNotifications.class);
i.putExtra("service_call",2);
context.startService(i);
} else {
Log.e("receiver","wifi off");
}
}
public static boolean isNetworkConnected(Context c) {
ConnectivityManager connectivityManager =
(ConnectivityManager) c.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
I also tried:
use start_stick service it won't work.
I'm trying use intent extra int instead of getaction but it didn't work either.
if you are not sure if intent is null or not but still you are making a call just move int getwhattodo = intent.getIntExtra("service_call",0); call inside your null check
int getwhattodo = intent.getIntExtra("service_call",0);
if (intent == null || intent.getAction() == null || getwhattodo == 0) {
Log.e("receiver","service faild");
Crashlytics.log("service faild to call");
if (getwhattodo == 0) {
stopSelf();
}
}
The three methods: ringtone(); onActivityResult(); saveRingtone(); do work.
During the first load of the app the fourth method loadRingtone(); works too, it can play repeatingly any sound the user chooses.
But as the app restarts:
It does save and bring back the string of the User's chosen notification sound. But just as its supposed to play the sound, converted from that string, it plays the default instead.
I used some toasts to check the values.
Toast.makeText(this,uri.toString(),Toast.LENGTH_SHORT).show();
Toast.makeText(this,ringPath,Toast.LENGTH_SHORT).show();
public void ringtone(View view){
final Uri currentTone = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Intent intent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, currentTone);
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_NOTIFICATION);
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE, "Select Tone");
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, (Uri) null);
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, false);
this.startActivityForResult(intent, 5);
}
#Override
protected void onActivityResult(final int requestCode, final int resultCode, final Intent intent) {
if (resultCode == Activity.RESULT_OK && requestCode == 5){
uri = intent.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
if (uri == null) {
uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
}
sound = RingtoneManager.getRingtone(getApplicationContext(), uri);
saveRingtone();
}
}
public void saveRingtone(){
SharedPreferences sharedPreferences = getSharedPreferences(SHARED_PREFS, MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(Ring, uri.toString());
editor.apply();
}
public void loadRingtone(){
SharedPreferences sharedPreferences = getSharedPreferences(SHARED_PREFS, MODE_PRIVATE);
ringPath = sharedPreferences.getString(Ring, "");
if(ringPath == ""){
uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
}else {
uri.parse(ringPath);
}
sound = RingtoneManager.getRingtone(getApplicationContext(), uri);
sound.play();
}
Its expected to play the notification that the "sound" variable is set up with in the loadRingtone(); method (not default sound).
I am having trouble to stop the alarm from ringing even after I have pressed the stopAlarm button. I cannot figure out how to get access to the same Ringtone instance and call stop().
This is my start alarm switch in MainActivity java class.
public void switchClicked(View view) {
if (((Switch) view).isChecked()) {
Log.d("MainActivity", "Alarm On");
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, alarmTimePicker.getHour());
calendar.set(Calendar.MINUTE, alarmTimePicker.getMinute());
Intent myIntent = new Intent(MainActivity.this, AlarmReceiver.class);
pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, myIntent, 0);
alarmManager.set(AlarmManager.RTC, calendar.getTimeInMillis(), pendingIntent);
setAlarmText("ON");
} else {
alarmManager.cancel(pendingIntent);
setAlarmText("OFF");
Log.d("MainActivity", "Alarm Off");
}
}
public void setAlarmText(String alarmText) {
alarmTextView.setText(alarmText);
}
Here is my StopAlarm button in MainActivity java class.
public void stopAlarm(View view) {
setAlarmText("Alarm stopped");
Intent myIntent = new Intent(MainActivity.this, AlarmReceiver.class);
pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.cancel(pendingIntent);
}
This is the AlarmReciver java class.
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(final Context context, Intent intent) {
MainActivity inst = MainActivity.instance();
inst.setAlarmText("Alarm! Wake up! Wake up!");
Uri alarmUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
if (alarmUri == null) {
alarmUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
}
Ringtone ringtone = RingtoneManager.getRingtone(context, alarmUri);
ringtone.play();
}
}
steps:
add RingtonePlayingService to your project (don't forget to declare it in manifest)
public class RingtonePlayingService extends Service{
private Ringtone ringtone = null;
#Override
public int onStartCommand(Intent intent, int flags, int startId){
Uri alarmUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
if (alarmUri == null)
alarmUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
this.ringtone = RingtoneManager.getRingtone(this, alarmUri);
ringtone.play();
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent){
return null;
}
#Override
public void onDestroy(){
super.onDestroy();
shutUpRingtone();
}
private void shutUpRingtone(){
if(ringtone != null)
ringtone.stop();
ringtone = null;
}
}
remove code you have inside onReceive and put this:
#Override
public void onReceive(final Context context, Intent intent) {
Intent startIntent = new Intent(context, RingtonePlayingService.class);
context.startService(startIntent);
}
now RingtonePlayingService is handling ringtone playing and keeps reference to it. Your stopAlarm method is just cancelling potentially pending alarm, so if it didn't fired yet until stop button click it won't never fire. But when it started ringing already then you should stop ringtone instance held by started service. Add on the end of your method:
public void stopAlarm(View view) {
...
Intent stopIntent = new Intent(context, RingtonePlayingService.class);
stopService(stopIntent);
}
Now stopAlarm do both: cancels pending alarm (if any) and stops service (if is alive), which is potentially playing ringtone
also remove MainActivity.instance() pattern, it is bad as hell... When you set future alarm (e.g. now+1h) and system (or user) remove app from memory before it gets fired then you will get NullPointerException, as .instance() is null, and you are immediatelly trying to access inst.setAlarmText method. Intead of you may use Local Broadcasting or service binding to update your UI - send broadcasts/messages to your Activity from working RingtonePlayingService with start/stop/current status
I am developing a mobile app which keeps the screen ON when launched and all of you know that this kind of app drains the battery. So I wanted to keep the screen ON only when the device is plugged in. I found this code on stackoverflow (thanks to all of you).
IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Context context = this;
Intent batteryStatus = context.registerReceiver(null, ifilter);
int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING || status == BatteryManager.BATTERY_STATUS_FULL;
int chargePlug = batteryStatus.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
boolean usbCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_USB;
boolean acCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_AC;
if (isCharging) {
if (usbCharge) {
tv1.setText("USB plugged in");
} else {
if (acCharge) {
tv1.setText("AC plugged in");
}
}
} else {
tv1.setText("Connect your charger");
}
}
I put this code in oncreate. But the problem is that it shows status only once(when app is launched). So I put a timer task to repeat checking like this
t = new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Context context = this;
Intent batteryStatus = context.registerReceiver(null, ifilter);
int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING || status == BatteryManager.BATTERY_STATUS_FULL;
int chargePlug = batteryStatus.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
boolean usbCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_USB;
boolean acCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_AC;
if (isCharging) {
if (usbCharge) {
tv1.setText("USB plugged in");
} else {
if (acCharge) {
tv1.setText("AC plugged in");
}
}
But this doesn't work and gives the error
Type missmatch : Cannot convert from new Runnable(){} to Context
I am a newbie so please see if you could help me with some modification or even a new code. Thanks in advance.
Important note: I work on Sketchware which lets you only to put codes in MainActivity.xml or MainActivity.java other features like manifest.xml is not editable. Please keep this in mind while answering.
Use Broadcast Receiver to get Battery Status.
Like That:-
// Initialize a new BroadcastReceiver instance
private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver()
{
#Override
public void onReceive(Context context, Intent intent)
{
int status=intent.getIntExtra(BatteryManager.EXTRA_STATUS,-1);
if(status==BatteryManager.BATTERY_STATUS_CHARGING)
{
//Do anything if Charging
}
else
{
//Do anything if not Charging
}
}
}
Call it Like That:-
// Get the application context
Context mContext = getApplicationContext();
// Initialize a new IntentFilter instance
IntentFilter iFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
// Register the broadcast receiver
mContext.registerReceiver(mBroadcastReceiver,iFilter);
Hope this will help you!!!
I was reading the guide here about setting up a BroadcastReceiver to check changes in the battery. And it stated that I could setup a BroadcastReceiver like this:
<receiver android:name=".PowerConnectionReceiver">
<intent-filter>
<action android:name="android.intent.action.ACTION_POWER_CONNECTED"/>
<action android:name="android.intent.action.ACTION_POWER_DISCONNECTED"/>
</intent-filter>
</receiver>
in my manifest and this as a class:
public class PowerConnectionReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||
status == BatteryManager.BATTERY_STATUS_FULL;
int chargePlug = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
boolean usbCharge = chargePlug == BATTERY_PLUGGED_USB;
boolean acCharge = chargePlug == BATTERY_PLUGGED_AC;
}
}
Is the BroadcastReceiver call onReceive(...) ONLY when a CHANGE occurs in the battery state? For example, what if the user had the device plugged into their computer and it was charging the entire time the BroadcastReceiver was running. Would it detect a change, since technically, the device's battery status didn't change? Whenever I get isCharging, would it be the current value, or the value at the last change? I want to check if it did change and what it always is so that I can optimize my application and save battery life.
It will get called only on these actions, as you specified...
android.intent.action.ACTION_POWER_CONNECTED
android.intent.action.ACTION_POWER_DISCONNECTED
And that's when...
1) External power has been connected to the device.
2) External power has been removed from the device.
If you need to track battery power changes, you should include this filter in your manifest.
android.intent.action.ACTION_BATTERY_CHANGED
Btw.
isCharging would be the current state, of course.
1. BroadcastReceiver uses the Publisher-Subscriber Pattern.
2. Its used in this way.." If xyz happens inform me, and i will take action on the basis of that".
Its not only on the CHANGE in battery states, but many more, like When Booting is completed etc...
See this for more details:
http://developer.android.com/reference/android/content/BroadcastReceiver.html
This is what you want put it in onCreate method
BroadcastReceiver batteryReceiver = new BroadcastReceiver()
{
int scale = -1;
int level = -1;
int voltage = -1;
int temp = -1;
#Override
public void onReceive(Context context, Intent intent)
{
level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
temp = intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, -1);
voltage = intent.getIntExtra(BatteryManager.EXTRA_VOLTAGE, -1);
Log.e("BatteryManager", "level is "+level+"/"+scale+", temp is "+temp+", voltage is "+voltage);
}
};
IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
registerReceiver(batteryReceiver, filter);