android TelephoneManager getting null in service - android

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" />

Related

Service stops when main app si closed

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.

SCREEN_OFF Broadcast Receiver not firing inside of Service in separate process

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.

Service is NOT running always even after I have used START_STICKY

Issues
Service is NOT running always even after I have used START_STICKY.
Sometimes I dont get any Toast Action for Outgoing call, is that mean service stops after some time ?
My Requirment
Application shows a Toast whenever user makes a outgoing call from the phone. For this I am using a BroadcastReceiver to tap the call action and a service (to run Receiver always). once I start this activity, it starts showing toast when a outgoing call get initiated ..but not Always.
Below is the complete code -
MainActivity.class
public class MainActivity extends Activity
{
CallNotifierService m_service;
boolean isBound = false;
private ServiceConnection m_serviceConnection = new ServiceConnection()
{
#Override
public void onServiceConnected(ComponentName className, IBinder service)
{
m_service = ((CallNotifierService.MyBinder)service).getService();
Toast.makeText(MainActivity.this, "Service Connected", Toast.LENGTH_LONG).show();
isBound = true;
Intent intent = new Intent(MainActivity.this, CallNotifierService.class);
startService(intent);
}
#Override
public void onServiceDisconnected(ComponentName className)
{
m_service = null;
isBound = false;
}
};
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent(this, CallNotifierService.class);
bindService(intent, m_serviceConnection, Context.BIND_AUTO_CREATE);
}
.
.
.
}
CallNotifierService.class
public class CallNotifierService extends Service
{
private final IBinder myBinder = new MyBinder();
private static final String ACTION_OUTGOING_CALL = "android.intent.action.NEW_OUTGOING_CALL";
private CallBr br_call;
#Override
public IBinder onBind(Intent arg0)
{
return myBinder;
}
#Override
public void onDestroy()
{
Log.d("service", "destroy");
this.unregisterReceiver(this.br_call);
Toast.makeText(CallNotifierService.this, "Receiver Un-Registered", Toast.LENGTH_LONG).show();
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
final IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_OUTGOING_CALL);
this.br_call = new CallBr();
this.registerReceiver(this.br_call, filter);
Toast.makeText(CallNotifierService.this, "onStartCommand Called", Toast.LENGTH_LONG).show();
return START_STICKY;
}
public class MyBinder extends Binder
{
CallNotifierService getService()
{
return CallNotifierService.this;
}
}
public class CallBr extends BroadcastReceiver
{
public CallBr() {}
#Override
public void onReceive(Context context, Intent intent)
{
Toast.makeText(context, "Action:"+intent.getAction(), Toast.LENGTH_LONG).show();
}
}
}
You are getting the wrong approach here, by mixing a simple idea (that would work if done correctly) with more complicated ideas (that cannot work).
Keep in mind: services are not "always running" components, even when using START_STICKY.
The Android system will not hesitate to kill your service if it needs memory somewhere else. START_STICKY only means that the Android system will re-start your service when it can, calling onStartCommand as specified in the documentation.
If you need a service to really stick around, then you must use a foreground service. But it will have consequences on the UI (annoying notification icon always showing), and battery life, and you do not need this here.
Now here is the magic trick: your app does not need to be running for your BroadcastReceiver to work. All you need to do is to register it in your AndroidManifest.xml with the correct intent-filter:
<receiver android:name=".broadcastreceivers.CallBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL"/>
</intent-filter>
</receiver>
(also make sure your app has the required permissions, namely PROCESS_OUTGOING_CALLS).
Then all you need in code is:
public class CallBroadcastReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
Toast.makeText(context, "Action: " + intent.getAction(), Toast.LENGTH_LONG).show();
}
}
No activity (except to ask for the PROCESS_OUTGOING_CALLS permission on Android 6+), no service, nothing. Simple and battery-efficient !
The service does get re-created, not not re-started.
If you override the onCreate and do a Log.d or a Toast, you will see that it gets called after your app is destroyed.
So the trick to keep it running after it is recreated is to do your code on the onCreate method and use the onStartCommand just to return START_STICKY.

How to catch GPS off broadcast once?

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.

Register Battery Changed broadcast in Android service

I'm starting a service from an Activity. The service registers for Battery Changed broadcast Receiver. I receive broadcasts as long as the screen is ON. Once the screen is turned OFF, I stop receiving broadcasts, however, the service doesn't die.
My activity code,
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
context = this.getApplicationContext();
Intent intent = new Intent(this,BatteryStatusService.class);
startService(intent);
}
and my service code,
public class BatteryStatusService extends Service{
private final static String TAG = BatteryStatusService.class.getSimpleName();
private BroadcastReceiver timeTickReceiver;//changeReceiver;
private boolean registered = false;
public class LocalBinder extends Binder {
BatteryStatusService getService() {
return BatteryStatusService.this;
}
}
private final IBinder mBinder = new LocalBinder();
#Override
public void onStart(Intent intent, int startId){
Log.i(TAG,"Starting service");
IntentFilter filter = new IntentFilter();
filter.addAction(Constants.ACTION_BATTERY_CHANGED);
timeTickReceiver = new TimeTickReceiver();
this.getApplicationContext().registerReceiver(timeTickReceiver, filter);
registered = true;
}
#Override
public void onDestroy(){
Log.d(TAG,"Stopping service");
if(registered){
this.getApplicationContext().unregisterReceiver(timeTickReceiver);
}
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return mBinder;
}
public class TimeTickReceiver extends BroadcastReceiver {
private String action = null;
private final String TAG = TimeTickReceiver.class.getSimpleName();
#Override
public void onReceive(Context context, Intent intent) {
action = intent.getAction();
if(action.equals(Constants.ACTION_BATTERY_CHANGED)){
Log.d(TAG,"I got action = "+action);
}
}
}
}
}
use AlarmManager and get last broadcasted level with
Intent BATTERYintent=this.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
However there are mobiles where it would work either. I have t-mobile MOVE which will not update battery value/broadcast no matter what in sleep mode... but most mobiles will do it as they should
by the way dont listen to dcanh121 there are cases when u need to get battery level even when phone is in sleepmode.
Once the screen is turned OFF, I stop receiving broadcasts, however, the service doesn't die.
When the screen is turned off, shortly thereafter the device goes into sleep mode. Your code does not execute again until something wakes up the device from sleep mode.
Also:
You do not need to use getApplicationContext() here
You do not need a Binder here, since you are not binding to the service, so just have onBind() return null
You need to have some code somewhere to stop this service, so it does not run forever
why don't you try by using onResume() and onPause()

Categories

Resources