I'm new at Android,
so please excuse my low experience.
I need this service to check if BroadcastReceiver is running or not every period of time.
If it's running then I want it to do nothing, but if not running I want it to run it.
In this code the service run the receiver every 20 sec, but it didn't check if receiver running or not, so every 20 sec I will get new receiver and the running receiver.
Any idea to solve this problem please?
Receiver.java
public class Receiver extends BroadcastReceiver
{
int numberr =0;
private static final String TAG = "RestartServiceReceiver";
#Override
public void onReceive(Context context, Intent intent) {
int delay = 0;
int period = 10000;
Timer basic_timer = new Timer();
basic_timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
Log.e("view", ""+numberr );
numberr++;
}
}, delay, period);
}
}
Service1.java
public class Service1 extends Service {
public Service1() {
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
int delay = 0;
int period =20000;
Timer basic_timer = new Timer();
basic_timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
sendBroadcast(new Intent("run"));
}
}, delay, period);
return Service.START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public void onCreate() {
Toast.makeText(this, "Service was Created", Toast.LENGTH_LONG).show();
}
#Override
public void onStart(Intent intent, int startId) {
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
}
#Override
public void onDestroy() {
Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
}
}
I think u just forget to register the receiver in menifest.
try to add this beside service in menifest~
<receiver android:name=".Receiver">
<intent-filter>
<action android:name="run" />
</intent-filter>
</receiver>
<service ...
ps. make sure your service has been started . or try to call this in your activity
startService(new Intent(this, Service1.class));
Related
I am trying to make an app in which I have a receiver which sends out a broadcast:
public class PhoneStateReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent) {
try {
System.out.println("Receiver start");
String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
String incomingNumber = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
if(state.equals(TelephonyManager.EXTRA_STATE_RINGING)){
Intent callIntent = new Intent("INCOMING_CALL");
callIntent.putExtra("number", incomingNumber);
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
}
if ((state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK))){
//Toast.makeText(context,"Call Received State",Toast.LENGTH_SHORT).show();
}
if (state.equals(TelephonyManager.EXTRA_STATE_IDLE)){
//Toast.makeText(context,"Call Idle State",Toast.LENGTH_SHORT).show();
}
}
catch (Exception e){
e.printStackTrace();
}
}
}
I also have a service running and I want to capture the broadcast in that service, I have tried the following but it does not work:
public class NotifierService extends Service
{
...//something goes here
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
LocalBroadcastManager.getInstance(this).registerReceiver(lbReceiver, new IntentFilter("INCOMING_CALL"));
return START_STICKY;
}
private BroadcastReceiver lbReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(action.equals("INCOMING_CALL"))
{
//do something
}
}
};
Can someone please tell me the correct way to receive a broadcast in a service, if it is not possible to receive a broadcast then what else can i use ?
[UPDATE]
This is how my service is declared in the manifest
<service
android:name=".NotifierService"
android:enabled="true"
android:exported="true"
>
</service>
I need to create a service that allow my application to work also when I close it, I’ve tried with STICKY_SERVICE but it doesn’t work... if anyone can decribe me how I can do this please answer this question.
It works with android 7.1 and it doesn’t with other versions
Here is my code...
public class SensorService extends Service {
public int counter=0;
public SensorService(Context applicationContext) {
super();
Log.i("HERE", "here I am!");
}
public SensorService() {
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
startTimer();
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
Log.i("EXIT", "ondestroy!");
stoptimertask();
Intent broadcastIntent = new Intent("RestartSensor");
sendBroadcast(broadcastIntent);
}
private Timer timer;
private TimerTask timerTask;
long oldTime=0;
public void startTimer() {
//set a new Timer
timer = new Timer();
//initialize the TimerTask's job
initializeTimerTask();
//schedule the timer, to wake up every 1 second
timer.schedule(timerTask, 1000, 1000); //
}
/**
* it sets the timer to print the counter every x seconds
*/
public void initializeTimerTask() {
timerTask = new TimerTask() {
public void run() {
Log.i("in timer", "in timer ++++ "+ (counter++));
}
};
}
/**
* not needed
*/
public void stoptimertask() {
//stop the timer, if it's not already null
if (timer != null) {
timer.cancel();
timer = null;
}
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
This is my service Restarter...
public class SensorRestarterBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.i(SensorRestarterBroadcastReceiver.class.getSimpleName(), "Service Stops");
context.startService(new Intent(context, SensorService.class));
}
}
And the mainClass
public class MainActivity extends AppCompatActivity {
Intent mServiceIntent;
private SensorService mSensorService;
Context ctx;
public Context getCtx() {
return ctx;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ctx = this;
setContentView(R.layout.activity_main);
mSensorService = new SensorService(getCtx());
mServiceIntent = new Intent(getCtx(), mSensorService.getClass());
if (!isMyServiceRunning(mSensorService.getClass())) {
startService(mServiceIntent);
}
}
private boolean isMyServiceRunning(Class<?> serviceClass) {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
Log.i ("isMyServiceRunning?", true+"");
return true;
}
}
Log.i ("isMyServiceRunning?", false+"");
return false;
}
#Override
protected void onDestroy() {
stopService(mServiceIntent);
Log.i("MAINACT", "onDestroy!");
super.onDestroy();
}
}
This restartthe service correctly but after 3/4 seconds it die.
I've added this to my manifest
<service
android:name=".SensorService"
android:enabled="true" >
</service>
<receiver
android:name=".SensorRestarterBroadcastReceiver"
android:enabled="true"
android:exported="true"
android:label="RestartServiceWhenStopped">
<intent-filter>
<action android:name="RestartSensor"/>
</intent-filter>
</receiver>
Add the following code to your sensor service and edit as per your need. You need to bind the sticky service to a notification to keep the service alive and start in the foreground.
#Override
public void onCreate() {
super.onCreate();
Intent notifIntent = new Intent(this, SensorService.class);
PendingIntent pi = PendingIntent.getActivity(this, 0, notifIntent, 0);
Notification notification = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.smslogo_100x100)
.setColor(ContextCompat.getColor(this, R.color.colorAccent))
.setContentTitle(getResources().getString(R.string.app_name))
.setContentText("Running")
.setContentIntent(pi)
.build();
startForeground(101010, notification);
}
This will rectify the issue you are facing and the service will run forever.
This question already has an answer here:
Want to Access Power Button events in android [duplicate]
(1 answer)
Closed 4 years ago.
I am developing an application in which call on an number on power button click (4 times) but now issue is when user press home button 4 times it will trigged the call and I want only side power button click.
My receiver and service in manifest
<receiver
android:name=".services.SOSBroadcastReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.SCREEN_OFF"/>
<action android:name="android.intent.action.SCREEN_ON"/>
</intent-filter>
</receiver>
<service
android:name=".services.SOSService"
android:enabled="true">
</service>
and my BroadcastReceiver class
public class SOSBroadcastReceiver extends BroadcastReceiver
{
private static long lastTriggerTime = 0;
private static final int ONE_MILLI = 1000;
protected static final long ONE_SEC = 1 * ONE_MILLI;
protected static final long TWO_SEC = 2 * ONE_MILLI;
protected static final long THREE_SEC = 3 * ONE_MILLI;
protected static final int TRIGGER_THRESHOLD = 3;
protected static boolean triggerInProgress = false;
protected static int triggerCounter = 0;
#Override
public void onReceive(Context context, Intent intent)
{
if (intent.getAction().contains(Intent.ACTION_SCREEN_ON))
{
if (!triggerInProgress)
{
checkAndCreateAlert(context);
}
}
else if (intent.getAction().contains(Intent.ACTION_SCREEN_OFF))
{
if (!triggerInProgress)
{
checkAndCreateAlert(context);
}
}
}
private void checkAndCreateAlert(Context context)
{
/*---- If the gap between power button press is less than 2 seconds ----*/
if ((System.currentTimeMillis() - lastTriggerTime) <= TWO_SEC
|| (triggerCounter == 0))
{
triggerCounter++;
lastTriggerTime = System.currentTimeMillis();
}
else
{
triggerCounter = 0;
}
if (triggerCounter > TRIGGER_THRESHOLD)
{
((Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE)).vibrate(1000);
triggerInProgress = true;
Intent intent = new Intent(context, SOSActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("timer", true);
context.startActivity(intent);
triggerInProgress = false;
triggerCounter = 0;
}
}
}
My code will keep the count of power button click in terms of screen_on and screen_off event and execute the other method if power button is pressed more than 3 time in 2secs.
This is my Service class
public class SOSService extends Service
{
BroadcastReceiver mReceiver;
IntentFilter pqrs_intentFilter;
#Override
public IBinder onBind(Intent intent)
{
return null;
}
#Override
public void onCreate()
{
super.onCreate();
}
#Override
public void onDestroy()
{
unregisterReceiver(mReceiver);
}
#Override
public void onStart(Intent intent, int startid)
{
pqrs_intentFilter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
pqrs_intentFilter.addAction(Intent.ACTION_SCREEN_ON);
mReceiver = new SOSBroadcastReceiver();
registerReceiver(mReceiver, pqrs_intentFilter);
}
public void onStop(Intent intent)
{
unregisterReceiver(mReceiver);
}
}
public class ExampleActivity extends Activity {
#Override
protected void onCreate() {
// INITIALIZE RECEIVER
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
BroadcastReceiver mReceiver = new ScreenReceiver();
registerReceiver(mReceiver, filter);
// YOUR CODE
}
#Override
protected void onPause() {
// WHEN THE SCREEN IS ABOUT TO TURN OFF
if (ScreenReceiver.wasScreenOn) {
// THIS IS THE CASE WHEN ONPAUSE() IS CALLED BY THE SYSTEM DUE TO A SCREEN STATE CHANGE
System.out.println("SCREEN TURNED OFF");
} else {
// THIS IS WHEN ONPAUSE() IS CALLED WHEN THE SCREEN STATE HAS NOT CHANGED
}
super.onPause();
}
#Override
protected void onResume() {
// ONLY WHEN SCREEN TURNS ON
if (!ScreenReceiver.wasScreenOn) {
// THIS IS WHEN ONRESUME() IS CALLED DUE TO A SCREEN STATE CHANGE
System.out.println("SCREEN TURNED ON");
} else {
// THIS IS WHEN ONRESUME() IS CALLED WHEN THE SCREEN STATE HAS NOT CHANGED
}
super.onResume();
}
}
Receiver
public class ScreenReceiver extends BroadcastReceiver {
private boolean screenOff;
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
screenOff = true;
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
screenOff = false;
}
Intent i = new Intent(context, UpdateService.class);
i.putExtra("screen_state", screenOff);
context.startService(i);
}
}
Service
public static class UpdateService 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 void onStart(Intent intent, int startId) {
boolean screenOn = intent.getBooleanExtra("screen_state", false);
if (!screenOn) {
// YOUR CODE
} else {
// YOUR CODE
}
}
}
Hopefully this was useful. Let me know if you have questions.
This code isn't working for me it should make notification every 2 sec the app runs with no errors and then after 2 sec keeps giving me messages you're app has stopped working.
I added these codes:
AndroidManifest.xml
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<service android:name="NotificationService" android:exported="false"/>
<receiver android:name="BootReceiver">
<intent-filter>
<action android:name="com.company.app"/>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
MainActivity.java
startActivity(new Intent(this,NotificationService.class));
NotificationService.java
public class NotificationService extends Service {
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
mTimer=new Timer();
mTimer.schedule(timerTask,2000,2*1000);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
try {
}catch (Exception e){
e.printStackTrace();
}
return super.onStartCommand(intent, flags, startId);
}
private Timer mTimer;
TimerTask timerTask=new TimerTask() {
#Override
public void run() {
Log.e("log","Running");
notifiy();
}
};
#Override
public void onDestroy() {
try {
mTimer.cancel();
timerTask.cancel();
}catch (Exception e){
e.printStackTrace();
}
Intent intent=new Intent("com.company.app");
intent.putExtra("your value","torestore");
sendBroadcast(intent);
}
public void notifiy(){
IntentFilter intentFilter=new IntentFilter();
intentFilter.addAction("RSSPullService");
Intent mIntent=new Intent(Intent.ACTION_VIEW, Uri.parse(""));
PendingIntent pendingIntent=PendingIntent.getActivity(getBaseContext(),0,mIntent,Intent.FLAG_ACTIVITY_NEW_TASK);
Context context=getApplicationContext();
Notification.Builder builder=new Notification.Builder(context)
.setContentTitle("T")
.setContentText("M")
.setContentIntent(pendingIntent)
.setDefaults(Notification.DEFAULT_SOUND)
.setAutoCancel(true)
;//.setSmallIcon();
Notification notification=builder.build();
NotificationManager notificationManager=(NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(1,notification);
}
}
BootReceiver.java
public class BootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.i("Service stops","ohhhhhhh");
context.startService(new Intent(context,NotificationService.class));
}
}
i tired this a few months ago but failed.
what i'm trying to do is count the number of times the user unlocks his phone and show it on the screen but i'm getting vague numbers each time i unlock the phone.
my code is a follows.
My main activity oncreate
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startService(new Intent(getApplicationContext(), LockService.class));
TextView ticker;
ticker = (TextView) findViewById(R.id.textView);
ticker.setText(String.valueOf(Tick.tick));
Log.e("but this is awesome ", String.valueOf(Tick.tick));
}
The Service class
public class LockService extends Service {
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
final IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_USER_PRESENT);
final BroadcastReceiver mReceiver = new ScreenReceiver();
registerReceiver(mReceiver, filter);
return super.onStartCommand(intent, flags, startId);
}
public class LocalBinder extends Binder {
LockService getService() {
return LockService.this;
}
}
}
The BroadcastReceiver Class
public class ScreenReceiver extends BroadcastReceiver {
public static boolean wasScreenOn = true;
#Override
public void onReceive(final Context context, final Intent intent) {
Log.e("test", "onReceive");
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
wasScreenOn = false;
Log.e("test", "wasScreenOn" + wasScreenOn);
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
wasScreenOn = true;
Log.e("test", "wasScreenOn and user present" + wasScreenOn);
} else if (intent.getAction().equals(Intent.ACTION_USER_PRESENT)) {
Tick.tick ++;
Log.e("test", "userpresent" + Tick.tick);
}
}
}
please help me understand what i'm doing wrong
I believe what's happening is this:
each time you open your activity, you call start service. So even if your service is already running, onStartCommand is being called. This way, you register your broadcast multiple times, and then when you unlock your device your counters are being incremented for each time you reciver has been registered.
You should do one of these options:
1. Define your recievers in your manifest so you won't have to deal with registration and unregisteration each time.
2. Register you recievers in your service onCreate instead onStartCommand. Also, make sure you unregister them in your service onDestroy.