When you plug in charger what service and classes android calls? - java

I have been trying to use reflection in case when anybody plug in charger or usb cable to charge their device. Can anybody please tell me what does android implements to interact with the hardware.
I am not exactly interested in the USB
I am interested more in the red(amber in case of HTC) led that glow when we connect our device for charging or in case of notification.

Set up a BroadcastReceiver for ACTION_BATTERY_CHANGED. An Intent extra will tell you what the charging state is -- see BatteryManager for details.
<application android:icon="#drawable/icon" android:label="#string/app_name">
<receiver android:name=".receiver.PlugInControlReceiver">
<intent-filter>
<action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
<action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" />
</intent-filter>
</receiver>
</application>
Then
public void onReceive(Context context , Intent intent) {
String action = intent.getAction();
if(action.equals(Intent.ACTION_POWER_CONNECTED)) {
// Do something when power connected
}
else if(action.equals(Intent.ACTION_POWER_DISCONNECTED)) {
// Do something when power disconnected
}
}

see this link
you can monitor battery charging state by registering following intent filter
< 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>
and in code
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;
}
}

Related

Receiver not getting invoked if removed app from recents

I am developing app which sends SMS on active call ends.
Manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="xxx.xxxx.xxxx.xxxx">
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.WRITE_SMS" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.READ_CALL_LOG" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:theme="#style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".MonitorService"
android:enabled="true"
android:exported="true" />
<service
android:name=".SendText"
android:exported="false" />
<receiver
android:name=".BootReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
</manifest>
I have taken all the runtime permissions if its above Marshmallow too from MainActivity.
My Receiver :
public class BootReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
Log.d("BootTest : ", "\nOnBootReceiver - Received a broadcast!");
Toast.makeText(context, "InstaPromo Is Ready !!", Toast.LENGTH_LONG).show();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
context.startForegroundService(new Intent(context, MonitorService.class));
}
else
{
context.startService(new Intent(context, MonitorService.class));
}
}
}
Implemented receiver runtime as :
public class MonitorService extends Service
{
// Notification variables
private BroadcastReceiver mCallBroadcastReceiver = new BroadcastReceiver()
{
#Override
public void onReceive(Context context, Intent intent)
{
String action = intent.getAction();
if (action.equalsIgnoreCase("android.intent.action.PHONE_STATE"))
{
if (intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(TelephonyManager.EXTRA_STATE_RINGING))
{
Log.d("RECEIVER X: ", "INCOMING CALL...");
}
if (intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(TelephonyManager.EXTRA_STATE_IDLE))
{
Log.d("RECEIVER X: ", "CALL ENDS HERE...");
Intent Dispatcher = new Intent(context, SendText.class);
startService(Dispatcher);
}
if (intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(TelephonyManager.EXTRA_STATE_OFFHOOK))
{
Log.d("RECEIVER X: ", "ACTIVE CALL GOING ON...");
}
}
}
};
public MonitorService() { }
#Override
public void onCreate()
{
super.onCreate();
// created notification here
// also registered broadcast receiver here
mBuilder.setChannelId(NOTIFICATION_CHANNEL_ID);
startForeground(17, mBuilder.build());
}
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
Log.d("WatchMan : ", "\nmCallBroadcastReceiver Listening....");
//return super.onStartCommand(intent, flags, startId);
return START_STICKY;
}
#Override
public void onDestroy()
{
this.unregisterReceiver(mCallBroadcastReceiver);
Log.d("WatchMan : ", "\nDestroyed....");
Log.d("WatchMan : ", "\nWill be created again....");
}
#Override
public IBinder onBind(Intent intent)
{
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
}
Broadcastreceiver works fine from service class; even if App removed from recent app list, But If removed from recents then on next boot_complete it never calls receiver again. If App is not removed from recents... then on every boot_complete / quick boot it gets triggered and broadcast-receiver works perfectly. I have tried android:exclude_from_recents..., But it is not the way to achieve it.
Can someone please help me to resolve this situation. Thanks
Update 2
I have studied Firebase JobDispatcher documentation over github and used it as belows :
Implemented dependancy in gradle project file
Success in sync thenafter
Created a JobService
Created a job and scheduled it.
It is getting triggered on boot_completed too..
public class MyJobService extends JobService
{
#Override
public boolean onStartJob(JobParameters job)
{
// Do some work here
Log.d("MY_JOB :", "STARTED HERE... \n");
return false;
// Answers the question: "Is there still work going on?"
}
#Override
public boolean onStopJob(JobParameters job)
{
Log.d("MY_JOB :", "STOPPED HERE... \n");
return true;
// Answers the question: "Should this job be retried?"
}
}
FirebaseJobDispatcher dispatcher = new FirebaseJobDispatcher(new GooglePlayDriver(MainActivity.this));
Bundle myExtrasBundle = new Bundle();
myExtrasBundle.putString("some_key", "some_value");
Job myJob = dispatcher.newJobBuilder()
// the JobService that will be called
.setService(MyJobService.class)
// uniquely identifies the job
.setTag("my-unique-tag")
// one-off job
.setRecurring(false)
// don't persist past a device reboot
.setLifetime(Lifetime.FOREVER)
// start between 0 and 60 seconds from now
.setTrigger(Trigger.executionWindow(10, 10+2))
// don't overwrite an existing job with the same tag
.setReplaceCurrent(false)
// retry with exponential backoff
.setRetryStrategy(RetryStrategy.DEFAULT_EXPONENTIAL)
// constraints that need to be satisfied for the job to run
.setConstraints(
// only run when device is idle
Constraint.DEVICE_IDLE
)
.setExtras(myExtrasBundle)
.build();
dispatcher.mustSchedule(myJob);
How should i schedule it just for running once on reboot/boot_complete
I want to recur only once stopped.. : setRecurring(false), IS IT OKAY to false or true it should be true?
setLifetime(Lifetime.UNTIL_NEXT_BOOT) SET it to FOREVER THIS IS OKAY
setTrigger(Trigger.executionWindow(0, 60)) NOT GETTING THIS
setReplaceCurrent(false) YES ITS OKAY.
retry with exponential backoff What is This?
How to set these tags to get started on BOOT / REBOOT and only once, try if fails to start, do not start again ..?
Use FirebaseJobDispatcher to restart your service after every boot. For more on JobDispatcher please see this.
If the app is first installed or force stopped by user, BroadcastReceviers will not run until user runs the app manually at least once.
AS per doc & answer
Note that an application's stopped state is not the same as an Activity's stopped state. The system manages those two stopped states separately.
Applications are in a stopped state when they are first installed but are not yet launched and when they are manually
stopped by the user (in Manage Applications). (They mean force
stop an app)
Htc devices add com.htc.intent.action.QUICKBOOT_POWERON >> From this answer.
<receiver android:enabled="true" android:name=".receivers.BootUpReceiver">
<intent-filter>
<category android:name="android.intent.category.DEFAULT" />
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.intent.action.QUICKBOOT_POWERON"/>
<action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/>
</intent-filter>
</receiver>
Starting from Android O,
You can not start a service from a background app without being blessed with an exception: java.lang.IllegalStateException: Not allowed to start service Intent (my_service) : app is in background If you still need to launch a service at device start up, you can now use the new JobIntentService.
Add your BroadcastReceiver and JobIntentService to your manifest
<receiver android:name=".BootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
<service android:name=".MyService"
android:permission="android.permission.BIND_JOB_SERVICE"/>
Enqueue work for your JobIntentService:
public class BootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
MyService.enqueueWork(context, new Intent());
}
}
}
Define your JobIntentService:
public class MyJobIntentService extends JobIntentService {
public static final int JOB_ID = 0x01;
public static void enqueueWork(Context context, Intent work) {
enqueueWork(context, MyJobIntentService.class, JOB_ID, work);
}
#Override
protected void onHandleWork(#NonNull Intent intent) {
// your code
}
/**
* This will be called if the JobScheduler has decided to stop this job. The job for
* this service does not have any constraints specified, so this will only generally happen
* if the service exceeds the job's maximum execution time.
*
* #return True to indicate to the JobManager whether you'd like to reschedule this work,
* false to drop this and all following work. Regardless of the value returned, your service
* must stop executing or the system will ultimately kill it. The default implementation
* returns true, and that is most likely what you want to return as well (so no work gets
* lost).
*/
public boolean onStopCurrentWork() {
return true;
}
}

Receiving media key events in Service

I know it has been explained a hundred times, and I've looked at them all and still can't figure it out. I have experience on BlackBerry 10 QT/C++ but am trying to ride the BlackBerry train into Android and that means learning both Java and the Android way of doing things.
I am following (among other guides) this one
in AndroidManifest.xml
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:theme="#style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:enabled="true" android:name=".myService" >
</service>
<receiver android:name="android.support.v4.media.session.MediaButtonReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter>
</receiver>
</application>
I think I have things where they need to be? No?
In myService.java
public class myService extends Service {
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
private MediaSessionCompat.Callback mediaSessionCompatCallBack = new MediaSessionCompat.Callback()
{
#Override
public boolean onMediaButtonEvent(Intent mediaButtonEvent) {
Log.d("MEDIAKEY", "Key Event");
return super.onMediaButtonEvent(mediaButtonEvent);
}
};
private MediaSessionCompat mediaSessionCompat;
#Override
public void onCreate() {
Toast.makeText(this, "My Service Created", Toast.LENGTH_LONG).show();
Log.d("SERVICE", "onCreate");
mediaSessionCompat = new MediaSessionCompat(this, "MEDIA");
}
#Override
public void onDestroy() {
Toast.makeText(this, "My Service Stopped", Toast.LENGTH_LONG).show();
Log.d("SERVICE", "onDestroy");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "My Service Started", Toast.LENGTH_LONG).show();
Log.d("SERVICE_STARTUP", "onStart");
mediaSessionCompat.setCallback(mediaSessionCompatCallBack);
mediaSessionCompat.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS);
MediaButtonReceiver.handleIntent(mediaSessionCompat, intent);
mediaSessionCompat.setActive(true);
return START_STICKY;
}
Any help would be great,
Thanks
EDIT:
Ok I've changed the onCreate() to:
context = getApplicationContext();
mediaSessionCompat = new MediaSessionCompat(context, "MEDIA");
mediaSessionCompat.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
mediaSessionCompat.setCallback(new MediaSessionCompat.Callback() {
#Override
public boolean onMediaButtonEvent(Intent mediaButtonEvent) {
Log.d("MEDIA", "event");
return super.onMediaButtonEvent(mediaButtonEvent);
}
});
and onStartCommand() to:
MediaButtonReceiver.handleIntent(mediaSessionCompat, intent);
mediaSessionCompat.setActive(true);
return super.onStartCommand(intent, flags, startId);
But still no Log.d() on pressing any media keys, I watched the video and it helped me understand it but not getting what the problem is, I'm on API 22 (5.1.1) by the way.
There's a few things in the MediaButtonReceiver documentation you are missing firstly:
You need to add the <intent-filter> for android.intent.action.MEDIA_BUTTON to your .myService - without this, MediaButtonReceiver won't know which Service to forward media buttons to
You need to call handleIntent() in your onStartCommand()
After that, your Service will be set up correctly, but you still won't receive media buttons. As explained in the Media Playback the Right Way talk, you need to become the preferred media button receiver by calling mediaSessionCompat.setActive(true).
You'll also want to make sure you are calling
mediaSessionCompat.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS |
MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
mediaSessionCompat.setCallback(mediaSessionCompatCallBack);
This ensures that you say you can handle media buttons and registers your Callback instance with the MediaSessionCompat.
Note that MediaSessionCompat will automatically translate media buttons into the appropriate Callback methods (i.e., play will translate to onPlay() being called, etc) so in many cases you don't need to directly override onMediaButtonEvent().

How to get notified when the users Wifi changes from one network to other

I have an app in which I need to detect users Wifi connection and based on that, the user can see some data. The point is that I want to get notified when the user was on some other network while starting the app and moves to some other network while the app was running. Let me make a scenario:
Suppose I have 2 wifi, one inside my house and other outside. When starting the app, I was inside the house and accordingly the data shown to me was "ABC". Now when I move outside the house, my app should give a notification and kill the activity and hence I should not be able to see the same data "ABC" when I am outside the house.
Write a BroadcastReceiver as follows
public class TheBroadcastReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
WifiManager wifiManager = (WifiManager) context
.getSystemService(Context.WIFI_SERVICE);
NetworkInfo datainfo = intent
.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
if (datainfo != null)
{
if (datainfo.getType() == ConnectivityManager.TYPE_WIFI)
{
//have different network states here
if (datainfo.getState() == datainfo.State.CONNECTING || datainfo.getState() == datainfo.State.CONNECTED) {
//work accordingly
}
}
}
}
}
Register a BroadcastReceiver and register these entries at manifest
<receiver android:name="yours package details like com.a.b.c.TheBroadcastReceiver " >
<intent-filter>
<action android:name="android.net.wifi.supplicant.CONNECTION_CHANGE" />
<action android:name="android.net.wifi.STATE_CHANGE" />
</intent-filter>
</receiver>
Add following permission sets at manifest
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
Also visit http://developer.android.com/training/monitoring-device-state/connectivity-monitoring.html
Each time the user changes the connection you can catch in BroadcastReceiver.
First of all you require to declare following permissions in AndroidManifest.xml
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
Create a BroadcastReceiver
public class BrodcastNetwork extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
// Write your code here
}
}
Apply the filters to BroadcastReceiver
<receiver android:name="com.example.datausage.BrodcastNetwork" >
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" >
</action>
</intent-filter>
</receiver>
Register a broadcast receiver to listen for the Action "android.net.ConnectivityManager.CONNECTIVITY_ACTION"
When connection changed to "connected" state, call WifiManager.getConnectionInfo().getBSSID() to check the current access point ID

BroadcastReceiver - how to trigger service every time user ON/OFF screen

Hello
I want to check whether my service is running or not, if service is running, do nothing.
But if service is not running, restart the service.
So I do something like this.
In Manifest.xml
<receiver android:name="com.varma.android.aws.receiver.Receiver">
<intent-filter>
<action android:name="android.intent.action.SCREEN_ON" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SCREEN_OFF" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
Receiver.java
public class Receiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.i("aws", "Received...");
if(isMyServiceRunning(context)) {
Log.v("aws", "Yeah, it's running, no need to restart service");
}
else {
Log.v("aws", "Not running, restarting service");
Intent intent1 = new Intent(context, Service.class);
context.startService(intent1);
}
}
private boolean isMyServiceRunning(Context context) {
ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (Service.class.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
}
But nothing is happening when I ON/OFF screen
What am I doing wrong?
You can't register screen on/off broadcast through manifest file,tt doesn't work(need to explore why).
Register it in your main activity through code
ifilter=new IntentFilter();
ifilter.addAction(Intent.ACTION_SCREEN_OFF);
ifilter.addAction(Intent.ACTION_SCREEN_ON);
registerReceiver(new Receiver(), ifilter);
Till the time your activity remains in memory you will receive these broadcasts in your receiver, i have tested it and able to receive broadcasts.
However if your activity gets finished you won't receive these broadcasts. So registerting these broadcasts in some LocalService in your app with START_STICKY feature will solve your issue.
If you want your service to stay up, you don't need to do this. Just have onStartCommand return START_STICKY. This will cause Android to restart any service it stops as soon as it has sufficient memory.

Broadcast Receiver for ACTION_USER_PRESENT,ACTION_SCREEN_ON,ACTION_BOOT_COMPLETED

I am creating a class which uses broadcast receiver. I want to receive the broadcast on unlocking of the phone. But there is some issue. Please help me out.
My Manifest.xml is :-
<receiver android:name=".MyReciever">
<intent-filter>
<intent-filter>
<action android:name="android.intent.action.ACTION_USER_PRESENT" />
<action android:name="android.intent.action.ACTION_BOOT_COMPLETED" />
<action android:name="android.intent.action.ACTION_SCREEN_ON" />
</intent-filter>
</intent-filter>
</receiver>
and my Broadcast reciever class :-
public class MyReiever extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("My Reciever","is intent null => " + (intent == null));
Log.d("My Reciever",intent.getAction()+"");
}
}
Though other application and services are receiving broadcast for "Screen_on" and "USer_Present" eg. WifiService.
Although the Java constants are android.content.intent.ACTION_USER_PRESENT, android.content.intent.ACTION_BOOT_COMPLETED, and android.content.intent.ACTION_SCREEN_ON, the values of those constants are android.intent.action.USER_PRESENT, android.intent.action.BOOT_COMPLETED, and android.intent.action.SCREEN_ON. It is those values which need to appear in your manifest.
Note, however, that a receiver for ACTION_SCREEN_ON can not be declared in a manifest but must be registered by Java code, see for example this question.
Since implicit broadcast receivers are not working as of Android 8.0, you must register your receiver by code and also in the manifest.
Do these steps:
Add manifest tag
<receiver android:name=".MyReciever">
<intent-filter>
<intent-filter>
<action android:name="android.intent.action.ACTION_USER_PRESENT" />
<action android:name="android.intent.action.ACTION_BOOT_COMPLETED" />
<action android:name="android.intent.action.ACTION_SCREEN_ON" />
</intent-filter>
</intent-filter>
</receiver>
Create a receiver class and add your codes
public class MyReciever extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("My Reciever","is intent null => " + (intent == null));
Log.d("My Reciever",intent.getAction()+"");
}
}
Create a service and register the receiver in it
public class MyService extends Service {
MyReceiver receiver = new MyReceiver();
#Override
public IBinder onBind(Intent intent) { return null; }
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
registerReceiver(receiver);
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(receiver);
}
}
Don't forget to define the service in manifest
<service android:name=".MyService"/>
To make your broadcast work, you have to register it in service. And to keep your service alive you can use tools like alarm managers, jobs, etc which is not related to this question.
Check your Class name, that is extending BroadcastReceiver. It should be "MyReciever" not "MyReiever"
Beside Typo that mentioned in earlier answers and the fact that the receiver class package name should be completely mentioned in receiver tag, I think the problem is that the code in question uses two nested intent filters. I believe this code will work correctly:
<receiver android:name=".MyReciever">
<intent-filter>
<action android:name="android.intent.action.ACTION_USER_PRESENT" />
<action android:name="android.intent.action.ACTION_BOOT_COMPLETED" />
<action android:name="android.intent.action.ACTION_SCREEN_ON" />
</intent-filter>
</receiver>
I can only give you a quick tip as i have gone through that path you are following with much less success. Try to read logcat using java.util.logging so that you will not require permission to read logs. And in log view create listener for the one containing "system disable" as its header. it fires up both at lock and unlock. check for the one that gives access to system.android not the other screen.
Hope it helps. Best of luck

Categories

Resources