It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I am trying to send SMS when the battery Level reached a particular value from a Service. I am not getting any errors but the SMS is not been sent.
MY CODE:
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.BatteryManager;
import android.os.IBinder;
import android.telephony.SmsManager;
import android.util.Log;
import android.widget.Toast;
public class BatteryStatus extends Service {
int scale = -1;
int level = -1;
int voltage = -1;
int temp = -1;
String batteryNumber = "012345567";
String moderate=" Battery Level is 50 ";
String low = "Battery Level is low. Need to be charged immediately";
public IBinder onBind(Intent intent) {
return null;
}
public void onCreate() {
super.onCreate();
Toast.makeText(getApplicationContext(),"Service Running", Toast.LENGTH_SHORT).show();
//BATTERY STATUS
BroadcastReceiver batteryReceiver = new BroadcastReceiver() {
#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);
Log.e("NumberBattery ", "Number is "+batteryNumber);
}
};
IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
registerReceiver(batteryReceiver, filter);
if(batteryNumber!=null && level==49){
SmsManager bat = SmsManager.getDefault();
bat.sendTextMessage(batteryNumber,null,moderate,null,null);
}else if(batteryNumber!=null && level==20){
SmsManager bat = SmsManager.getDefault();
bat.sendTextMessage(batteryNumber, null,low, null, null);
}
}
}
LOGCAT:
03-09 03:41:40.390: E/BatteryManager(11086): level is 49/100, temp is 321, voltage is 7574
03-09 03:41:40.390: E/NumberBattery(11086): Number is 01234567
Can you please tell what is wrong her?
It's because you never send the SMS.
When the following line is executed:
if (batteryNumber != null && level == 49){
level has not been initialized yet.
Change your code like this:
#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);
Log.e("NumberBattery ", "Number is "+batteryNumber);
if (batteryNumber != null && level == 49) {
SmsManager bat = SmsManager.getDefault();
bat.sendTextMessage(batteryNumber,null,moderate,null,null);
} else if(batteryNumber!=null && level==20){
SmsManager bat = SmsManager.getDefault();
bat.sendTextMessage(batteryNumber, null,low, null, null);
}
}
Related
I want to get battery Current, and Voltage at an interval of 5 seconds.
But in my source, the Voltage and Current changes at an random interval.
such as 5 seconds, 10 seconds, 9 seconds, .......
I heard BroadcastReceiver requires a return value within 10 seconds.
I guess this is a cause, but I have no idea how to solve this problem.
package com.example.hubertlee.batterywearrate;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.BatteryManager;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private TextView batteryInfo;
Long avgCurrent = null, currentNow = null;
int count = 0;
float power = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BatteryManager mBatteryManager = (BatteryManager) getSystemService(Context.BATTERY_SERVICE);
batteryInfo = (TextView) findViewById(R.id.textViewBatteryInfo);
this.registerReceiver(this.batteryinfoReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
avgCurrent = mBatteryManager.getLongProperty(BatteryManager.BATTERY_PROPERTY_CURRENT_AVERAGE);
currentNow = mBatteryManager.getLongProperty(BatteryManager.BATTERY_PROPERTY_CURRENT_NOW);
}
}
private BroadcastReceiver batteryinfoReceiver = new BroadcastReceiver(){
public void onReceive(Context context, Intent intent){
int health = intent.getIntExtra(BatteryManager.EXTRA_HEALTH, 0);
int icon_small = intent.getIntExtra(BatteryManager.EXTRA_ICON_SMALL,0);
int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
int plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0);
boolean present = intent.getExtras().getBoolean(BatteryManager.EXTRA_PRESENT);
int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 0);
int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, 0);
String technology = intent.getExtras().getString(BatteryManager.EXTRA_TECHNOLOGY);
float temp = intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, 0);
float voltage = intent.getIntExtra(BatteryManager.EXTRA_VOLTAGE, 0);
batteryInfo.setText("Health: " + health + "\n" + "Icon small : "+icon_small+"\n" +
"Level : "+level+"\n"+"Present : "+present+"\n"+"Scale: "+
scale+"\n"+"Status :"+status+"\n"+ "Technology:"+technology+"\n"+
"Temperature :"+temp/10+"'C\n"+"Voltage:"+voltage/1000+"V\n"+"BATTERY_PROPERTY_CURRENT_AVERAGE = "
+ avgCurrent + "mAh"+"\n"+"BATTERY_PROPERTY_CURRENT_NOW = " + currentNow + "mAh"+"\n"+"count ="+count);
count++;
}
};
}
If you want to have a code run at fix interval, take a look at Alarm manager :
https://developer.android.com/reference/android/app/AlarmManager.html
Like Selvin said, the broadcast is called only when it change.
I have register battery low broadcast receiver.
Like this
import com.save.sharedpreference.SharedPreference;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.SmsManager;
import android.widget.Toast;
public class BootReceiver extends BroadcastReceiver {
String user_phone_key = "phone_number";
int last_level = 0;
#Override
public void onReceive(Context context, Intent intent) {
int rlevel = intent.getIntExtra("level", -1);
int scale = intent.getIntExtra("scale", -1);
int level = -1;
if (rlevel >= 0 && scale > 0) {
level = (rlevel * 100) / scale;
}
if (level == 48 && last_level == level + 1) {
SharedPreference save_data = new SharedPreference(
context.getApplicationContext());
String phone = save_data.get_string(user_phone_key, null);
Toast.makeText(context, "Level Decrease", Toast.LENGTH_SHORT)
.show();
try {
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(phone, null,
"Your Battery level is less ", null, null);
} catch (Exception e) {
Toast.makeText(context.getApplicationContext(),
"SMS faild, please try again later!", Toast.LENGTH_LONG)
.show();
e.printStackTrace();
}
}
last_level = level + 1;
}
}
Its working fine but the problem is when my battery level is reach 45% it start sending me sms until battery level change from 45%.
I want that when my battery level is reach 45% it just send me sms only one time and again waiting when battery level is 45%.
Is it possible?
Any help please.
Can you just use a local variable, like this?
public class BootReceiver extends BroadcastReceiver {
String user_phone_key = "phone_number";
int last_level = 0;
#Override
public void onReceive(Context context, Intent intent) {
int rlevel = intent.getIntExtra("level", -1);
int scale = intent.getIntExtra("scale", -1);
int level = -1;
if (rlevel >= 0 && scale > 0) {
level = (rlevel * 100) / scale;
}
if (level == 45 && last_level == 46) {
...
last_level = level;
}
}
I know it's not the most elegant solution, but it should work.
The more "official" solution is to use the ACTION_BATTERY_LOW intent to detect charge decreases, which IIRC only fires once, when the device hits low battery. Is there a reason you need to detect the battery level hitting 45%, in particular?
Create a boolean variable to send message only once.Like-
boolean isMsgSent=false;
and modify if loop as-
if(level==45 && !isMsgSent){
// send Msg
isMsgSent=true;
}
else{
isMsgSent=false;
}
It will send message only once when battery level is 45.
I have successfully monitor incoming SMS and sent it to database for viewing later. I have read about monitor outgoing sms and I don't really understand how it works. Can someone guide me how to code to monitor outgoing sms by using ContentObserver? I will post all my current codes for incoming sms.need guide from where I should start.
smsReceiver.java
package terima.sms.inbox;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.gsm.SmsMessage;
import java.net.*;
import java.io.*;
#SuppressWarnings("deprecation")
public class SmsReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
Object messages[] = (Object[]) bundle.get("pdus");
SmsMessage SMS[] = new SmsMessage[messages.length];
for (int n = 0; n < messages.length; n++) {
SMS[n] = SmsMessage.createFromPdu((byte[]) messages[n]);
}
String member_id = "1";
inbox(SMS[0].getOriginatingAddress(), SMS[0].getMessageBody(), member_id);
}
public static Boolean inbox(String telefon, String message, String member_id){
String mesej = "";
for(int i = 0; i < message.length(); i++)
{
if(message.charAt(i) == ' ' || message.charAt(i) == '+')
{
if(message.charAt(i) == ' ')
mesej += "%20";
else
mesej += "%2B";
}
else
{
mesej += message.charAt(i);
}
}
try
{
URL oracle = new URL("http://192.168.1.111/inbox.php?message=" + mesej + "&telefon=" + telefon + "&member=" + member_id);
BufferedReader in = new BufferedReader(new InputStreamReader(oracle.openStream()));
String fetch, total = "";
while ((fetch = in.readLine()) != null)
total += fetch;
in.close();
if(total.equals("1"))
return true;
return false;
}
catch(Exception e)
{
return false;
}
}
}
thanks in advance.
To catch outgoing SMS you should use a ContentObserver coupled with a ContentResolver. Here is the code I use in the ContentObserver:
public class SmsObserver extends ContentObserver{
int smsCount;
public SmsObserver(Context context) {
super(new Handler());
smsCount = 0;
}
public void onChange(boolean selfChange){
super.onChange(selfChange);
readSms();
}
private void readSms(){
Uri uriSMS = Uri.parse("content://sms");
Cursor cur = context.getContentResolver().query(uriSMS, null, null, null, "_id");
cur.moveToLast();
int id = Integer.parseInt(cur.getString(cur.getColumnIndex("_id")));
if(cur != null && id != smsCount && id>0){
smsCount = id;
int type = Integer.parseInt(cur.getString(cur.getColumnIndex("type")));
if(type == 1){
// handle the received sms
}
else{
// handle the sent sms
}
}
cur.close();
}
}
After that you should create an instance of SmsOberver and register it on "content://sms". It will be triggered more often than when you send or receive a new message, so this is why I have a smsCount field.
I have a battery widget, and for some reason it does not receive the BATTERY_PLIGGED_AC integer when the phone is plugged into AC.
I have another widget for the BATTERY_PLUGGED_USB which works just fine.
I can't see anything wrong with my code:
public void onReceive(Context context, Intent intent) {
status = intent.getIntExtra("status", BatteryManager.BATTERY_STATUS_UNKNOWN);
batterylevel = intent.getIntExtra("level", 0);
updateAppWidget(context);
}
public void updateAppWidget(Context context){
RemoteViews updateViews = new RemoteViews(context.getPackageName(), R.layout.androidbatterywidget_layout);
updateViews.setTextViewText(R.id.textView1, " " + batterylevel + "%");
if (status == BatteryManager.BATTERY_PLUGGED_USB)
updateViews.setImageViewResource(R.id.imageView2, R.drawable.usb);
else if (status == BatteryManager.BATTERY_PLUGGED_AC)
updateViews.setImageViewResource(R.id.imageView2, R.drawable.bolt);
else
updateViews.setImageViewResource(R.id.imageView2, R.drawable.empty);
Hopefully someone will be able to spot what I have done wrong. Thanks!
Figured a way around. Sorry for this post I should have looked at it for a little longer myself. For future reference if people seem to have the same problem, it seems to me that the USB value is bundled with the BatteryManager.BATTERY_STATUS_UNKNOWN, but not the AC. So instead all i did was assign a new private int charging, to the value of the BatteryManager.BATTERY_PLUGGED_AC variable. If this is true (and the device is charging throygh AC), then the value is 1, so I simply replaced my previous if statement with
if (charging == 1)
updateViews.setImageViewResource(R.id.imageView2, R.drawable.bolt);
Now the code reads;
private int batterylevel = 0;
private int status;
private int charging;
private BroadcastReceiver myReceiver = new BroadcastReceiver()
{
public void onReceive(Context context, Intent intent)
{
status = intent.getIntExtra("status", BatteryManager.BATTERY_HEALTH_UNKNOWN);
charging = intent.getIntExtra("plugged", BatteryManager.BATTERY_PLUGGED_AC);
batterylevel = intent.getIntExtra("level", 0);
updateAppWidget(context);
}
public void updateAppWidget(Context context){
RemoteViews updateViews = new RemoteViews(context.getPackageName(), R.layout.androidbatterywidget_layout);
updateViews.setTextViewText(R.id.textView1, " " + batterylevel + "%");
if (charging == 1)
updateViews.setImageViewResource(R.id.imageView2, R.drawable.bolt);
else if (status == BatteryManager.BATTERY_PLUGGED_USB)
updateViews.setImageViewResource(R.id.imageView2, R.drawable.usb);
else
updateViews.setImageViewResource(R.id.imageView2, R.drawable.empty);
Im sure that there is a far more "majestic" way to do this, but i was just puzzled at why the USB int was passed if it was plugged into USB (2), but not the AC (1).
Thanks!
Is there a way to get battery information from the Android SDK? Such as battery life remaining and so on? I cannot find it through the docs.
Here is a quick example that will get you the amount of battery used, the battery voltage, and its temperature.
Paste the following code into an activity:
#Override
public void onCreate() {
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);
}
On my phone, this has the following output every 10 seconds:
ERROR/BatteryManager(795): level is 40/100 temp is 320, voltage is 3848
So this means that the battery is 40% full, has a temperature of 32.0 degrees celsius, and has voltage of 3.848 Volts.
You can register an Intent receiver to receive the broadcast for ACTION_BATTERY_CHANGED: http://developer.android.com/reference/android/content/Intent.html#ACTION_BATTERY_CHANGED. The docs say that the broadcast is sticky, so you'll be able to grab it even after the moment the battery state change occurs.
public static String batteryLevel(Context context)
{
Intent intent = context.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 100);
int percent = (level*100)/scale;
return String.valueOf(percent) + "%";
}
I needed to have a monitor on the battery and check the Level and the status. I am developing on MonoForAndroid, so here is what I came up with. I am putting it here in case somebody have a similar requirement. (I have tested this and works nicely).
try
{
var ifilter = new IntentFilter(Intent.ActionBatteryChanged);
Intent batteryStatusIntent = Application.Context.RegisterReceiver(null, ifilter);
var batteryChangedArgs = new AndroidBatteryStateEventArgs(batteryStatusIntent);
_Battery.Level = batteryChangedArgs.Level;
_Battery.Status = batteryChangedArgs.BatteryStatus;
}
catch (Exception exception)
{
ExceptionHandler.HandleException(exception, "BatteryState.Update");
throw new BatteryUpdateException();
}
namespace Leopard.Mobile.Hal.Battery
{
public class AndroidBatteryStateEventArgs : EventArgs
{
public AndroidBatteryStateEventArgs(Intent intent)
{
Level = intent.GetIntExtra(BatteryManager.ExtraLevel, 0);
Scale = intent.GetIntExtra(BatteryManager.ExtraScale, -1);
var status = intent.GetIntExtra(BatteryManager.ExtraStatus, -1);
BatteryStatus = GetBatteryStatus(status);
}
public int Level { get; set; }
public int Scale { get; set; }
public BatteryStatus BatteryStatus { get; set; }
private BatteryStatus GetBatteryStatus(int status)
{
var result = BatteryStatus.Unknown;
if (Enum.IsDefined(typeof(BatteryStatus), status))
{
result = (BatteryStatus)status;
}
return result;
}
}
}
#region Internals
public class AndroidBattery
{
public AndroidBattery(int level, BatteryStatus status)
{
Level = level;
Status = status;
}
public int Level { get; set; }
public BatteryStatus Status { get; set; }
}
public class BatteryUpdateException : Exception
{
}
#endregion