I am trying to capture screen on/off event on moto g phone. Main activity has
Intent intentscreen = new Intent(getApplicationContext(), ScreenService.class);
startService(intentscreen);
where as "ScreenService" looks like:
public int onStartCommand(Intent intent, int flags, int startId)
{
if (intent!=null)
{
super.onCreate();
WifiManager wm = (WifiManager) getSystemService(Context.WIFI_SERVICE);
wifiLock = wm.createWifiLock(WifiManager.WIFI_MODE_FULL , "MyWifiLock");
if(!wifiLock.isHeld()){
wifiLock.acquire();
}
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_SCREEN_ON);
filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
registerReceiver(this.mybroadcast, filter);
return super.onStartCommand(intent, flags, startId);
}
return START_STICKY;
}
#Override
public void onDestroy()
{
super.onDestroy();
unregisterReceiver(mybroadcast);
if(wifiLock.isHeld()){
wifiLock.release();
}
}
while the receiver class looks like:
public class ScreenReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("Screen", "--- I Fire!");
}
}
Manifest file has the permission, but the issue is that my phone receives the event for first few hours and then it stops receiving i.e. Log.d("Screen", "--- I Fire!"); is not displayed in my log cat.
Also to add further, if I acquire PowerManager.WakeLock wakeLock it doesn't work at all, but if I acquire WifiLock wifiLock = null, this works for few hours, any suggestion that how to keep the Wifi active probably?
Any suggestion that what possibly be wrong? Or any other type of lock should I acquire? I dont want to use a lot of battery for locks.
If your service gets killed by the system due to low memory it will later be restarted with null passed as the intent. When this happens it appears you would lose broadcast receiver as you do nothing if intent is null.
Seems like it's not possible to get these broadcasts from a static receiver in the android manifest. So you'll probably have to keep your service.
Something along these lines:
public void onCreate (){
super.onCreate();
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_SCREEN_ON);
filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
registerReceiver(mybroadcast, filter);
}
public int onStartCommand(Intent intent, int flags, int startId)
{
return START_STICKY;
}
#Override
public void onDestroy()
{
super.onDestroy();
unregisterReceiver(mybroadcast);
}
Related
I have a Service that listens to both incoming and outgoing calls.The Service runs when the app is started and keeps on running for some time even after the app is closed.But somehow is the Service is destroyed or something later.I have put START_STICKY as the return of the startCommand() method.I know the System kills the Service when the memory is high.But then how are the call recording apps able to listen to calls continuously?Is there a work around for this kind of problem?How do I make my app listen to phone calls continuously?
Code
PhoneListenerService.class
public class PhoneListenerService extends Service{
private TelephonyManager telephonyManager;
private File file;
OutgoingReceiver outgoingReceiver;
#Override
public void onCreate()
{
super.onCreate();
outgoingReceiver=new OutgoingReceiver();
IntentFilter intentFilter=new IntentFilter();
intentFilter.addAction("android.intent.action.NEW_OUTGOING_CALL");
registerReceiver(outgoingReceiver,intentFilter);
file=new File(Environment.getExternalStorageDirectory().getAbsolutePath());
telephonyManager=(TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
file=new File(Environment.getExternalStorageDirectory(),"AutoCall");
if (!file.exists())
{
Log.e("File","Created");
file.mkdir();
}
else
{
Log.e("File",file.getPath());
}
telephonyManager.listen(new TeleListener(getApplicationContext(),file.getAbsolutePath()),PhoneStateListener.LISTEN_CALL_STATE);
Log.e("Oncreate","Service");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e("OnCommand","Service");
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(outgoingReceiver);
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
public class OutgoingReceiver extends BroadcastReceiver {
public OutgoingReceiver()
{
}
#Override
public void onReceive(Context context, Intent intent) {
Log.e("Out","Track");
String phone_number=intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
Toast.makeText(context,"Outgoing call identified",Toast.LENGTH_SHORT).show();
}
}
}
Start the service as FOREGROUND Service like this
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Register your reporting alarms here.
Log.e("SmsAndCallService", "IN onStartCommand");
startForeground(105, getCompatNotification());
return Service.START_STICKY;
}
private Notification getCompatNotification() {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "105");
builder.setSmallIcon(R.mipmap.ic_launcher).setContentTitle(getString(R.string.app_name) + " running").setTicker("Recording");
Intent intent = new Intent(new Intent(getApplicationContext(), SplashActivity.class));
PendingIntent pendingIntent = PendingIntent.getActivity(this, 2003, intent, 0);
builder.setContentIntent(pendingIntent);
Notification notification = builder.build();
return notification;
}
So system cant kills this service when system run out of resources. `
FOREGROUND SERVICE means some sort of notification stuff keep showing to make the system to aware that service is still running.
Use a static system define broadcast receiver for incoming calls.don't forgot to declare this in manifest
Yea.I use MediaRecorder for that.I have a question.If the deveice is restarted will the service and receiver still run in the background
Like this way you need to have broadcast receiver for reboot restarting your service and jobscheduler for Higher versoin than marshmallow Android 6.0
public class BootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) {
Intent iService = new Intent(context, PhotoService.class);
context.startService(iService);
} else
JobInfoServ.scheduleJob(context);
}
}
AndroidManifest.xml
<receiver
android:name="com.your.package.broadcast.BootReceiver"
android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
I can't stop my service.
I have two services. Service1 starts Service2 with startService(intent).
I stop service1 with stopSelf();
Then I'm doing something in Service2 and start Service1 again and stop Service2.
So they are always starting each other again.
The behavior of the services are different after the first start.
I write some log messages and I can see that the information are multiply times in log cat.
I also tried to stop the activities in the onStartCommand of the other activty with stopService. (In onStartCommand of Service1 I call stopService service2)
Here is a Part of my Code:
Service1:
public class Service1 extends Service{
private int startId;
#Override
public void onCreate(){
super.onCreate();
}
private void doSomething(){
...
...
Intent intent = new Intent(getApplicationContext(), Service2.class);
startService(intent);
this.stopSelf(startId);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
this.startId=startId;
Intent beaconIntent = new Intent(getApplicationContext(), Service2.class);
stopService(beaconIntent);
doSomething();
return START_STICKY;
}
}
Service2:
public class Service2 extends Service implements BeaconConsumer, RangeNotifier{
private BeaconManager mBeaconManager;
private int startId;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Intent service1 = new Intent(getApplicationContext(), Service1.class);
stopService(service1);
mBeaconManager = BeaconManager.getInstanceForApplication(this);
mBeaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout("s:0-1=feaa,m:2-2=00,p:3-3:-41,i:4-13,i:14-19"));
mBeaconManager.bind(this);
this.startId = startId;
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
mBeaconManager.unbind(this);
}
#Override
public void onBeaconServiceConnect() {
region = new Region("all-beacons-region", null, null, null);
try {
mBeaconManager.startRangingBeaconsInRegion(region);
} catch (RemoteException e) {
e.printStackTrace();
}
mBeaconManager.addRangeNotifier(this);
}
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
if(!beacons.isEmpty()){
doSomething...
...
...
Intent intent = new Intent(getApplicationContext(), Service1.class);
startService(intent);
this.stopSelf();
}
}
}
What am I doing wrong?
Edit: I didn't mention, that I'm working with altbeacon library. I thought that doesn't make any impact.
But when I'm looking at the services which are running when I start the app and after I stop the Service2 there are always two altbeacon services running(BeaconIntentProcessor and BeaconService).
Maybe they calling my service mutlipy times.
I got what I did wrong.
The problem was not the service it self, it was the altbeacon library. More concrete the BeaconManager which was still searching in the background for a beacon, even when the service was destroyed.
In the logs it looked like the service is running multiple times.
The solution was to not only unbind, also to stop Ranging and remove the range notifier.
mBeaconManager.stopRangingBeaconsInRegion(region);
mBeaconManager.removeAllRangeNotifiers();
mBeaconManager.unbind(this);
Here is my stuff:
public class NotificationSystem extends Service implements Runnable {
private final Thread worker = new Thread(this);
private boolean alreadyRunning = false;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
IntentFilter filter = new IntentFilter();
ScreenManager screenManager = new ScreenManager();
filter.addAction(Intent.ACTION_SCREEN_OFF);
registerReceiver(screenManager, filter);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (!alreadyRunning) {
worker.start();
this.alreadyRunning = true;
}
return START_STICKY;
}
#Override
public void run() {
while(true) {
System.out.println("Thread doing stuff");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private static class ScreenManager extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
System.out.println("Screen is off");
}
}
}
The broadcast receiver never fires when the screen toggles off, why?
Is there some problem if there is that broadcast receiver inside of a service? Do I need anything in the manifest for SCREEN_OFF to toggle?
Is it another magical decision that the Android core team did instead of me? Maybe firing a broadcast receiver drains battery, ey?
I didn't got your question much but I got the answer for permission question of yours.
For working with Broadcast receivers you are always require to give a permission to AndroidManifest.xml which allows you to listen to state changes in your receiver. Also Register your receiver in your manifest file.
which is added by:
<uses-permission android:name="android.permission.READ_PHONE_STATE" >
I hope this helps !!
It is a firmware bug.
It's not working on my phone, but it works fine in the emulator.
Go figure.
I'm trying to count time that user is using a phone, so i used receiver
it got registered in MainActivity then i am starting TimeService which is registring receiver too so it can work even if user is in other activity or app.
MainActivity
private void registerScreenReceiver(){
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
mReceiver = new ScreenReceiver();
registerReceiver(mReceiver, filter);
}
TimeService
public class TimeService extends Service {
//
#Override
public void onCreate() {
super.onCreate();
// REGISTER RECEIVER THAT HANDLES SCREEN ON AND SCREEN OFF LOGIC
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
BroadcastReceiver mReceiver = new ScreenReceiver();
registerReceiver(mReceiver, filter);
}
#Override
public int onStartCommand(Intent intent, int flags, int start_id) {
boolean screenOn = intent.getBooleanExtra("screen_state", false);
if (!screenOn) {
Log.e("SERVICE","ON");
} else {
Log.e("SERVICE","OFF");
}
return START_NOT_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
The problem is that when i'm not using the app it's being closed by itself and receiver is no longer wroking.
You have to return START_STICKY in onStartCommand() to keep Service working.
You can also set your Service as a foreground Service but this require showing notification in the status bar which may not be a bad idea. Here is an example.
Update
It probably would be even better if you register your BroadcastReceiver in AndroidManifest.xml and start Service work from receiver when system wake it up.
I have broadcast receiver that activates on phone boot
public class autostart extends BroadcastReceiver {
public void onReceive(Context arg0, Intent arg1) {
Intent intent = new Intent(arg0, MyService.class);
arg0.startService(intent);
Log.i("Autostart", "started");
}
}
The service is very simple it just keeps registered an broadcast receiver that can be only registered by code and not from manifest
public class MyService extends Service
{
private static final String TAG = "MyService";
#Override
public IBinder onBind(Intent intent) {
return null;
}
public void onDestroy() {
Toast.makeText(this, "My Service Stopped", Toast.LENGTH_LONG).show();
Log.d(TAG, "onDestroy");
}
ScreenOffReceiver actionScreenOffReceiver;
#Override
public void onStart(Intent intent, int startid)
{
try {
IntentFilter intentfilter = new IntentFilter();
intentfilter.addAction(Intent.MY_ACTION);
registerReceiver(actionScreenOffReceiver = new ScreenOffReceiver(),
intentfilter);
} catch (Exception e) {
}
}
}
The problem is that if the app get closed, for example with call of finish() on some activity, then the service just dies.
How can I keep the service running till the phone is turned on
what is the right way to do this ?
You don't need an BroadcastReceiver just add this code in your Service
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
Source: Service | Android Developers