I have surfed the web and I haven't found a solution to my problem.
In my android app I have to catch and send a notification to the server everytime the user turn off the GPS. At this time I have writed this code
In the Android manifiest:
<receiver android:name="proguide.prosegur.scr.BL.receivers.GPSStatusBroadcastReceiver">
<intent-filter>
<action android:name="android.location.PROVIDERS_CHANGED" />
</intent-filter>
</receiver>
In the GPSStatusBroadcastReceiver class:
public class GPSStatusBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context arg0, Intent arg1) {
if (arg1.getAction().matches("android.location.PROVIDERS_CHANGED")) {
// here I have to send the notification
}
}
The problem is that everytime the user put down the GPS, I get this function called twice with identical Context and Intent arguments (I can only send 1 notification at a time).
Important note: it has to work under API level 8.
So, why this happen twice? What can I do (doing it right, not messing up the code) to send only 1 notification at a time? Thanks, sorry for my English.
Try this:
public class GpsReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.FROYO) {
final String action = intent.getAction();
if (action.equals(LocationManager.PROVIDERS_CHANGED_ACTION)) {
// GPS is switched off.
if (!context.getSystemService(Context.LOCATION_SERVICE).isProviderEnabled(LocationManager.GPS_PROVIDER)) {
// Do something.
}
}
}
}
}
Also, instead of hardcoding "android.location.PROVIDERS_CHANGED", you should use the variable LocationManager.PROVIDERS_CHANGED_ACTION provided by Android.
Instead of setting your GPS receiver in your AndroidManifest.xml file, register your GPS receiver via a Service as follow:
public class GpsService extends Service {
private BroadcastReceiver mGpsReceiver;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
registerReceiver();
return Service.START_NOT_STICKY;
}
private void registerReceiver() {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.FROYO) {
IntentFilter mIntentFilter = new IntentFilter();
mIntentFilter.addAction(LocationManager.PROVIDERS_CHANGED_ACTION);
this.mGpsReceiver = new GpsReceiver();
this.registerReceiver(this.mGpsReceiver, mIntentFilter);
}
}
}
You can avoid this problem using sharedpreference and with an thread
but it is not a proper way to overcome this problem
my method as follows
#Override
public void onReceive(Context context, Intent intent) {
boolean flage=MainActivity.getpreference();
if(!flage){
MainActivity.putPreferens(true);
Log.e("gpssss","gpssss");
Thread thread = new Thread() {
#Override
public void run() {
try {
sleep(2000);
MainActivity.putPreferens(false);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
thread.start();
}}
}
to the main class am create a sharedpreference and store boolean value false
the broad cast will work once.
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>
When I close main app servic stops broadcasting intents. Where is mistake? I can't find any way to keep it running.
Broadcast recevier:
public class CustomReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Custom Broadcast recevied", Toast.LENGTH_SHORT).show();
}}
Service (AAA.java):
public class AAA extends Service {
final class MyThreadClass implements Runnable {
int service_id;
MyThreadClass(int service_id) {
this.service_id = service_id;
}
#Override
public void run() {
synchronized (this) {
try {
while (true) {
Thread.sleep(3000);
Intent i = new Intent();
i.setAction("cz.johnyapps.custombroadcast");
sendBroadcast(i);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Thread thread = new Thread(new MyThreadClass(startId));
thread.start();
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
}}
Manifest:
<service android:name="cz.johnyapps.notificationservice.AAA"
android:exported="true"
android:process=":ServiceProcess"/>
Main activity: startService(new Intent(this, AAA.class));
Use startForeground method inside the Service to prevent such behavior
According to my knowledge one way is to make service running even after closing the app.
You have to make as notification in you app which will bind the
service to it. if the app is closed that notification will be attached
which will be binding the service to it.
Example: Android phone default Media sound playing app, if you close the app an notification is shown on the notification bar which maintains the service to keep the music playing in the service.
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 have a service consist phone state listener and started by my application.in version 2.3.3
when I exit application Telephone Manager getting null therefore phone state listener does not work service code below any idea? where am I do wrong?
Service does not destroy when i exit application.but listener getting NULL. Telephone manager setting on setCallListener() method.
I have a service to be used initialize phonestatelistener. service is started with two ways:
1-by BOOT_COMPLETED receiver (works fine listener is not null and catch the calls) 2-by my application with startService(new Intent(getApplicationContext(), MyPhoneStateListener.class));
problem is that when the service is started by my application then my application finish in this case my listener does not work. i know that TelephoneManager=null value. How can i provide that make The service intent going on when application finish?
public class MyPhoneStateListener extends Service{
SmsBroadcastReceiver _smsbroadcast;
private Context context;
MyCustomStateListener myCustomStateListener;
TelephonyManager telephonymanager;
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
setCallListener();
_smsbroadcast=new SmsBroadcastReceiver();
GetShieldState();
return START_STICKY;
}
private void setCallListener()
{
try
{
if (telephonymanager==null)
{
telephonymanager = (TelephonyManager) context.getSystemService(context.TELEPHONY_SERVICE);
myCustomStateListener = new MyCustomStateListener(context,telephonymanager);
telephonymanager.listen(myCustomStateListener, PhoneStateListener.LISTEN_CALL_STATE);
}
}
catch(Exception ex)
{
}
}
#Override
public void onCreate()
{
//Log.e("startservis","create");
context=MyPhoneStateListener.this;
super.onCreate();
}
#Override
public void onDestroy()
{
Log.e("onDestroy","destroy");
}
#Override
public boolean onUnbind(Intent intent)
{
//Toast.makeText(getApplicationContext(),"unbind:", Toast.LENGTH_SHORT).show();
return super.onUnbind(intent);
}
}
I think you forgot to give following permission in your AndroidManifest.xml file,
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
I want to make an timer which starts counting when the Android device is woken up and stops when the Android device is set to sleep. I found nothing, how a activity could be triggered
by wake up/sleep.
I hope you can help me with my problem
I used a BroadcastReceiver like timonvlad said but ACTION_SCREEN_ON and ACTION_SCREEN_OFF could not be called by XML so I created an service. The service has to be registered in the XML then I used this code
public class OnOffReceiver extends Service {
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
registerReceiver(new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
//This happens when the screen is switched off
}
}, new IntentFilter(Intent.ACTION_SCREEN_OFF));
registerReceiver(new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
//This happens when the screen is turned on and screen lock deactivated
}
}, new IntentFilter(Intent.ACTION_USER_PRESENT));
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
}
}
Use BroadcastReceiver and service to catch Screen_on and_off.... For example like ...
public class InternetReceiver 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, InternetService.class);
i.putExtra("screen_state", screenOff);
context.startService(i);
}
}
You should create a BroadcastReceiver that listens to the ACTION_BOOT_COMPLETED intent.
In the implementation, you have to store the timestamp of when that intent was received.
After that, you can create an activity that retrieves that timestamp, and calculates how much time has the phone been running.
Set up repeating event that will be fired when the device is awake:
AlarmManager.setRepeating(AlarmManager.RTC, time, period, pendingIntent);
Then catch those alarms and increment your timer counter, it will be counting when device is awake.
Don't start activity when device wakes up. Users will not be happy about such behavior of an app. Use notifications instead.