android Charge intent has no extra data - android

I am trying to display an alert in a specific Activity when the charging status changes.
this is my receiver class:
public class BatteryChargeReceiver extends BroadcastReceiver {
private String TAG = "receiver";
private ChargeReceiverCallback callback;
public BatteryChargeReceiver(ChargeReceiverCallback callback) {
this.callback =callback;
Log.v(TAG,"Inside Constructor (Callback)");
}
public interface ChargeReceiverCallback {
public void onReceive(Intent intent);
}
#Override
public void onReceive(Context context, Intent intent) {
callback.onReceive(intent);
}
}
And below is how I instantiate it from my MainActivity's onResume. MainActivity implements my interface and overrides onReceive(intent). I found out that at no stage does intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1) return anything else then -1.
BatteryChargeReceiver batteryReceiver = new BatteryChargeReceiver(this);
IntentFilter filterPower = new IntentFilter("android.intent.action.ACTION_POWER_CONNECTED");
registerReceiver(batteryReceiver, filterPower);

Intent.ACTION_POWER_CONNECTED not delivering current plugged-in state - this is probably a change in how API works, but I could not locate any mention of such change in docs.
The broadcast Intent.ACTION_POWER_CONNECTED was never meant to receive current plugged-in type, but it merely lets the receiving end of power connection (ref.). In fact, BatteryService.java broadcasts plain intent without any extra values (lines 410~412 as of this writing):
Intent statusIntent = new Intent(Intent.ACTION_POWER_CONNECTED);
statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
mContext.sendBroadcastAsUser(statusIntent, UserHandle.ALL);
However, following code with
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="19" />
worked on Nexus 5:
public class MainActivity extends Activity {
private static final String TAG = "PowerReceiver";
private final BroadcastReceiver mPowerReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (Intent.ACTION_POWER_CONNECTED.equals(action)) {
Log.d(TAG, "Power connected");
checkPluggedState(context, intent);
} else if (Intent.ACTION_POWER_DISCONNECTED.equals(action)) {
Toast.makeText(context, "Power disconnected", Toast.LENGTH_SHORT).show();
} else {
Log.wtf(TAG, "Unknown action: " + action);
}
}
};
private void checkPluggedState(Context context, Intent intent) {
Intent chargingIntent = registerReceiver(null, new IntentFilter(
Intent.ACTION_BATTERY_CHANGED));
final int pluggedState = chargingIntent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
final String msg;
switch (pluggedState) {
case 0:
msg = "The device is running on battery";
break;
case BatteryManager.BATTERY_PLUGGED_AC:
msg = "Plugged into AC charger";
break;
case BatteryManager.BATTERY_PLUGGED_USB:
msg = "Plugged into USB charger";
break;
case BatteryManager.BATTERY_PLUGGED_WIRELESS:
msg = "Plugged into wireless charger";
break;
default:
msg = "Unknown state: " + pluggedState;
}
Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
protected void onResume() {
super.onResume();
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_POWER_CONNECTED);
filter.addAction(Intent.ACTION_POWER_DISCONNECTED);
registerReceiver(mPowerReceiver, filter);
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(mPowerReceiver);
}
}
Hope this helps.

According to The docs, EXTRA_STATUS is for ACTION_BATTERY_CHANGED

Related

Perform a bluetooth scan with BluetoothAdapter in Xamarin.android

I am implementing an APP with Xamarin.
I want to perform a Bluetooth scan. And get the device found.
Here is my code.
How could I implement this to start a scan and collect the result once"Button_Scan()" is triggered?
Thank you.
[BroadcastReceiver(Enabled = true)]
public class BluetoothReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
var action = intent.Action;
if (action != BluetoothDevice.ActionFound)
{
return;
}
if (BluetoothDevice.ActionFound.Equals(action))
{
var device = (BluetoothDevice)intent.GetParcelableExtra(BluetoothDevice.ExtraDevice);
var ConnectState = device.BondState;
/*
switch (ConnectState)
{
case Bond.None:
break;
case Bond.Bonded:
break;
case Bond.Bonding:
break;
}
*/
if (device.Name != null)
{
Xamarin.Forms.Application.Current.MainPage.DisplayAlert("Found device", device.Name, "ok");
}
}
}
}
public async void Button_Scan(object sender, EventArgs e)
{
try
{
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.DefaultAdapter;
mBluetoothAdapter.Enable();
mBluetoothAdapter.StartDiscovery();
}
catch(Exception ex)
{
DisplayAlert("ex", ex.ToString(), "ok");
}
}
You have defined a BluetoothReceiver to receive the result ,you just add the device information into a deviceList.
public static List<string> mDeviceList = new List<string>();
public override void OnReceive(Context context, Intent intent)
{
string action = intent.Action;
if (BluetoothDevice.ActionFound.Equals(action))
{
BluetoothDevice device = (BluetoothDevice)intent.GetParcelableExtra(BluetoothDevice.ExtraDevice);
mDeviceList.Add(device.Name + ";" + device.Address);
}
}
Don't forget to regist the broadcast.
BluetoothReceiverreceiver = new BluetoothReceiver();
IntentFilter filter = new IntentFilter(BluetoothDevice.ActionFound);
RegisterReceiver(receiver, filter);

app which will record the ussd or sms

As we know that, when we use any menu in sim toolkit it send command to mobile network in ussd or sms format.
I need that sms or ussd to record and show it to me in android application.
I am calling the library service which i got in main activity like this
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent srvIntent = new Intent(this, CDUSSDService.class);
startService(srvIntent);
}
}
USSD Service Class is like that:
public class CDUSSDService extends Service{
private String TAG = CDUSSDService.class.getSimpleName();
private boolean mActive = true;//false //we will only activate this "USSD listener" when we want it
BroadcastReceiver receiver = new BroadcastReceiver()
{
#Override
public void onReceive(Context context, Intent intent)
{
if(intent.getAction().equals(Intent.ACTION_INSERT))
{
//activity wishes to listen to USSD returns, so activate this
mActive = true;
Log.d(TAG, "activate ussd listener");
showtoast(""+"activate ussd listener");
}
else if(intent.getAction().equals(Intent.ACTION_DELETE))
{
mActive = false;
Log.d(TAG, "deactivate ussd listener");
showtoast(""+"DeActivate ussd listener");
}
}
};
private final IExtendedNetworkService.Stub mBinder = new IExtendedNetworkService.Stub ()
{
public void clearMmiString() throws RemoteException
{
Log.d(TAG, "called clear");
showtoast("called clear.");
}
public void setMmiString(String number) throws RemoteException
{
Log.d (TAG, "setMmiString:" + number);
showtoast("setMmiString:"+number);
}
public CharSequence getMmiRunningText() throws RemoteException
{
if(mActive == true)
{
return null;
}
return "USSD Running";
}
public CharSequence getUserMessage(CharSequence text)
throws RemoteException {
Log.d(TAG, "get user message " + text);
showtoast("GET Usr Message:"+text);
if(mActive == false){
//listener is still inactive, so return whatever we got
Log.d(TAG, "inactive " + text);
showtoast("inactive:"+text);
return text;
}
//listener is active, so broadcast data and suppress it from default behavior
//build data to send with intent for activity, format URI as per RFC 2396
Uri ussdDataUri = new Uri.Builder()
.scheme(getBaseContext().getString(R.string.uri_scheme))
.authority(getBaseContext().getString(R.string.uri_authority))
.path(getBaseContext().getString(R.string.uri_path))
.appendQueryParameter(getBaseContext().getString(R.string.uri_param_name), text.toString())
.build();
sendBroadcast(new Intent(Intent.ACTION_GET_CONTENT, ussdDataUri));
mActive = false;
return null;
}
};
#Override
public IBinder onBind(Intent intent) {
Log.i(TAG, "called onbind");
//the insert/delete intents will be fired by activity to activate/deactivate listener since service cannot be stopped
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_INSERT);
filter.addAction(Intent.ACTION_DELETE);
filter.addDataScheme(getBaseContext().getString(R.string.uri_scheme));
filter.addDataAuthority(getBaseContext().getString(R.string.uri_authority), null);
filter.addDataPath(getBaseContext().getString(R.string.uri_path), PatternMatcher.PATTERN_LITERAL);
registerReceiver(receiver, filter);
return mBinder;
}
public void showtoast(String str)
{
Toast.makeText(getApplicationContext(), str, Toast.LENGTH_LONG).show();
}
}
I have created MainActivity inside the UssdLibray structure is like that in the below picture:
you can do this with the help of this library https://github.com/alaasalman/ussdinterceptor

How to receive external sensor data even when the app is closed or screen is off?

How can I receive external sensor data even when the app is closed or screen is off?
I am currently collecting data via bluetooth low energy using this function:
public void onDataRecieved(BleSensor<?> sensor, String text) {
if (sensor instanceof BleHeartRateSensor) {
final BleSensor hSensor = (BleSensor) sensor;
float[] values = hSensor.getData();
//Start service to write data to a file
viewText.setText(text);
}
Here is the class that is used to implement the BLE sensor listener. It is an activity. I am having trouble trying to convert it to a service.
public abstract class DemoSensorActivity extends Activity {
private final static String TAG = DemoSensorActivity.class.getSimpleName();
public static final String EXTRAS_DEVICE_ADDRESS = "DEVICE_ADDRESS";
public static final String EXTRAS_SENSOR_UUID = "SERVICE_UUID";
private BleService bleService;
private String serviceUuid;
private String deviceAddress;
// Handles various events fired by the Service.
// ACTION_GATT_CONNECTED: connected to a GATT server.
// ACTION_GATT_DISCONNECTED: disconnected from a GATT server.
// ACTION_GATT_SERVICES_DISCOVERED: discovered GATT services.
// ACTION_DATA_AVAILABLE: received data from the device. This can be a result of read
// or notification operations.
private final BroadcastReceiver gattUpdateReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (BleService.ACTION_GATT_DISCONNECTED.equals(action)) {
//TODO: show toast
finish();
} else if (BleService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {
final BleSensor<?> sensor = BleSensors.getSensor(serviceUuid);
bleService.enableSensor(sensor, true);
} else if (BleService.ACTION_DATA_AVAILABLE.equals(action)) {
final BleSensor<?> sensor = BleSensors.getSensor(serviceUuid);
final String text = intent.getStringExtra(BleService.EXTRA_TEXT);
onDataRecieved(sensor, text);
}
}
};
// Code to manage Service lifecycle.
private final ServiceConnection serviceConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName componentName, IBinder service) {
bleService = ((BleService.LocalBinder) service).getService();
if (!bleService.initialize()) {
Log.e(TAG, "Unable to initialize Bluetooth");
finish();
}
// Automatically connects to the device upon successful start-up initialization.
bleService.connect(deviceAddress);
}
#Override
public void onServiceDisconnected(ComponentName componentName) {
bleService = null;
//TODO: show toast
finish();
}
};
public abstract void onDataRecieved(BleSensor<?> sensor, String text);
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final Intent intent = getIntent();
deviceAddress = intent.getStringExtra(EXTRAS_DEVICE_ADDRESS);
serviceUuid = intent.getStringExtra(EXTRAS_SENSOR_UUID);
getActionBar().setDisplayHomeAsUpEnabled(true);
final Intent gattServiceIntent = new Intent(this, BleService.class);
bindService(gattServiceIntent, serviceConnection, BIND_AUTO_CREATE);
}
#Override
protected void onResume() {
super.onResume();
registerReceiver(gattUpdateReceiver, makeGattUpdateIntentFilter());
if (bleService != null) {
final boolean result = bleService.connect(deviceAddress);
Log.d(TAG, "Connect request result=" + result);
}
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(gattUpdateReceiver);
}
#Override
protected void onDestroy() {
super.onDestroy();
unbindService(serviceConnection);
bleService = null;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case android.R.id.home:
onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
private static IntentFilter makeGattUpdateIntentFilter() {
final IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BleService.ACTION_GATT_SERVICES_DISCOVERED);
intentFilter.addAction(BleService.ACTION_GATT_DISCONNECTED);
intentFilter.addAction(BleService.ACTION_DATA_AVAILABLE);
return intentFilter;
}
}
Currently this is only running when the app is open and the screen is turned on. Is there a way to continue to run this data collection when the app is closed and the screen is off?

BroadcastReceiver onReceive being called multiple times

I'm writing an app that checks external storage state. For monitoring the state I use BroadcastReceiver and I've noticed, that onReceive is called multiple times (eg.: 3x for unmount and 1x for mount) for one event (eg.: unplug usb).
Here is my code:
public class MainActivity extends ActionBarActivity {
final static String TAG = "BroadcastReceiverDemo";
private IntentFilter filter;
private BroadcastReceiver receiver;
private void registerReceiver() {
filter = new IntentFilter();
filter.addAction(Intent.ACTION_MEDIA_MOUNTED);
filter.addAction(Intent.ACTION_MEDIA_UNMOUNTED);
filter.addAction(Intent.ACTION_MEDIA_REMOVED);
filter.addAction(Intent.ACTION_MEDIA_SHARED);
filter.addDataScheme("file");
filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String broadcast;
String state = Environment.getExternalStorageState();
Log.d(TAG, "State: " + state);
if (Environment.MEDIA_MOUNTED.equals(state) && !Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
broadcast = "External storage aviable";
} else {
broadcast = "External storage NOT aviable";
}
String msg = intent.getAction() + " received broadcast: " + broadcast;
Log.d(TAG, msg);
}
};
this.registerReceiver(receiver, filter);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
registerReceiver();
}
#Override
protected void finalize() throws Throwable {
if (receiver != null) {
this.unregisterReceiver(receiver);
}
super.finalize();
}
}
Q: Why is onReceive called so many times and how to make it call only once?
Thanks for any help.

How to Communicate with Service

I'm using a USSDInterceptor service to get the USSD responce in my application. Here is the service:
package com.codedemigod.services;
import com.android.internal.telephony.IExtendedNetworkService;
public class CDUSSDService extends Service{
private String TAG = CDUSSDService.class.getSimpleName();
private boolean mActive = false; //we will only activate this "USSD listener" when we want it
BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(Intent.ACTION_INSERT)){
//activity wishes to listen to USSD returns, so activate this
mActive = true;
Log.d(TAG, "activate ussd listener");
}
else if(intent.getAction().equals(Intent.ACTION_DELETE)){
mActive = false;
Log.d(TAG, "deactivate ussd listener");
}
}
};
private final IExtendedNetworkService.Stub mBinder = new IExtendedNetworkService.Stub () {
public void clearMmiString() throws RemoteException {
Log.d(TAG, "called clear");
}
public void setMmiString(String number) throws RemoteException {
Log.d (TAG, "setMmiString:" + number);
}
public CharSequence getMmiRunningText() throws RemoteException {
if(mActive == true){
return null;
}
return "USSD Running";
}
public CharSequence getUserMessage(CharSequence text)
throws RemoteException {
Log.d(TAG, "get user message " + text);
//getApplicationContext().sendBroadcast(new Intent("ussdMsg"));
if(mActive == false){
//listener is still inactive, so return whatever we got
Log.d(TAG, "inactive " + text);
return text;
}
//listener is active, so broadcast data and suppress it from default behavior
//build data to send with intent for activity, format URI as per RFC 2396
Uri ussdDataUri = new Uri.Builder()
.scheme(getBaseContext().getString(R.string.uri_scheme))
.authority(getBaseContext().getString(R.string.uri_authority))
.path(getBaseContext().getString(R.string.uri_path))
.appendQueryParameter(getBaseContext().getString(R.string.uri_param_name), text.toString())
.build();
getApplicationContext().sendBroadcast(new Intent(Intent.ACTION_GET_CONTENT, ussdDataUri));
mActive = false;
return null;
}
};
#Override
public IBinder onBind(Intent intent) {
Log.i(TAG, "called onbind");
//the insert/delete intents will be fired by activity to activate/deactivate listener since service cannot be stopped
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_INSERT);
filter.addAction(Intent.ACTION_DELETE);
filter.addDataScheme(getBaseContext().getString(R.string.uri_scheme));
filter.addDataAuthority(getBaseContext().getString(R.string.uri_authority), null);
filter.addDataPath(getBaseContext().getString(R.string.uri_path), PatternMatcher.PATTERN_LITERAL);
registerReceiver(receiver, filter);
return mBinder;
}
}
I dont know how to communicate with this service from my activity. I have used BroadcastReceiver in my activity like this:
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
updateUI(intent);
}
};
#Override
public void onResume() {
super.onResume();
registerReceiver(broadcastReceiver, new IntentFilter(Intent.ACTION_GET_CONTENT));
}
But I couldn't get the broadcast. Am I doing something wrong? I dont know I should use BroadcastReceiver or I should communicate with my service by bindService.
Whould you please help me in this problem?
I solved the problem by myself. The problem was in the place of calling 'unregisterReceiver'. I had called unregisterReceiver() on onPause() and it seemed that during getting USSD result, the BroadcastReceiver was unregistered. so I put it on onDestroy() method and finally I managed to get the broadcast message. Here is my onDestroy method:
#Override
public void onDestroy() {
Log.i(TAG, "unregister");
unregisterReceiver(broadcastReceiver);
super.onDestroy();
}

Categories

Resources