I am trying to send a broadcast from a service but it is not received in the receiver. Following is my code
Bluetooth Service
public class BluetoothService extends Service {
public final static String TAG = "com.example.linvor.BluetoothService";
Intent intent1 = new Intent(TAG);
static boolean isRunning = false;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(final Intent intent, int flags, int startId) {
android.os.Debug.waitForDebugger();
super.onStartCommand(intent, flags, startId);
//android.os.Debug.waitForDebugger();
sendBroadcast(intent1);
return START_NOT_STICKY;
}
}
My Broadcast receiver is as follows.
ServiceBroadCastReceiver
public class ServiceBroadCastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
MainActivity.myLabel.setText("BroadCAst received");
if(intent.getAction().equals(BluetoothService.TAG)) {
Log.i("Broadcast status","BroadCast received");
}
}
}
and my manifest declaration seems like this.
manifest
<receiver
android:name=".ServiceBroadCastReceiver"
android:label="#string/app_name"
android:exported="true">
<intent-filter>
<action android:name="com.example.linvor.BluetoothService"></action>
</intent-filter>
</receiver>
One more thing:
when my service is running and sends broadcast to my activity(which is not received), my app shows app not responding.
Thanks to #KeLiuyue and #Mike M. for suggesting me solutions. But the problem was not in the broadcast code. The problem was in the service which was causing my app to not respond and hence I was getting problems with sending and receiving broadcasts in my app. And the reason for my service to not respond was this line.
android.os.Debug.waitForDebugger();
I just removed this line and everything is working fine.
Try this.
registerReceiver(receiver,new IntentFilter(BluetoothService.TAG));
Intent intent = new Intent();
//edited here ,your action
intent.setAction(BROADCAST_ACTION);
//send
sendBroadcast(intent);
Edited
// edited here , add your service
Intent startIntent = new Intent(this, BluetoothService.class);
startService(startIntent);
Note
register in AndroidManifest.xml or in the java code
then sendBroadcast in the java code
unregister receiver in onDestroy() method
#Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(receiver);
}
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 want that one of my services runs even if user has restarted device. I've tried this code but didn't succeed. What should I do? Help me please.
Thank you!
MyService2.class:
public class MyService2 extends Service {
private MyReceiver mR = null;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
mR = new MyReceiver();
IntentFilter intentFilter = new IntentFilter(Intent.ACTION_BOOT_COMPLETED);
registerReceiver(mR, intentFilter);
}
}
MyReceiver.class
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)){
context.startService(new Intent(context, MyService.class));
context.startService(new Intent(context,MyService2.class));
}
}
}
You are Registering your BroadcastReciver in your Service , Which your trying to start using your BroadcastReciver which is not registered.
So try registering your broadcast Reciever in your manifest file like this
<receiver android:name="your broadcast class">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter
First no need to register your receiver in service. Add your broadcast receiver in Manifest.
Like :
<receiver android:name="your broadcast class">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
Remember to add permission also :
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
When device is rebooted your receiver will automatically get executed by system as it is declared in manifest. In your receiver just start your service.
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)){
//add a log or toast to confirm the receive
context.startService(new Intent(context, MyService2.class));
}
}
}
AND
public class MyService2 extends Service {
private MyReceiver mR = null;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// do what ever you wanted to do...
}
}
I have tried this
Trying to start a service on boot on Android
Also I have checked with http://blog.vogella.com/2011/12/11/automatically-starting-services-in-android-after-booting/
yet my app wont restart on Phone startup. Here's the code.
AndroidManifest.xml
<service android:name=".MyService">
</service>
<receiver android:name=".Autostart"
android:enabled="true"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
MyService
public class MyService extends Service implements LocationListener {
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
private final IBinder mBinder = new LocalBinder();
public class LocalBinder extends Binder {
MyService getService() {
return MyService.this;
}
}
#Override
public void onCreate() {
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("LocalService", "Received start id " + startId + ": " + intent);
// We want this service to continue running until it is explicitly
// stopped, so return sticky.
return START_STICKY;
}
#Override
public void onDestroy() {
// Cancel the persistent notification.
this.stopSelf();
// Tell the user we stopped.
}
MainActivity
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
startService(new Intent(getBaseContext(), MyService.class));
Am I going wrong anywhere?
Edit:
public void onReceive(Context arg0, Intent arg1)
{
Intent intent = new Intent(arg0,MyService.class);
arg0.startService(intent);
Log.i("Autostart", "started");
}
This is my BroadcastReceiver.
Yet no results.
try register BroadcastReceiver for ACTION_BOOT_COMPLETED. The you can recieve startup broadcast.
public class BootBroadCast extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
Intent service=new Intent(context, MyService.class);
context.startService(service);
}
}
second you need add this in AndroidManifest.xml
<receiver android:name=".BootBroadCast" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" >
</action>
</intent-filter>
</receiver>
I have followed the article at vogella and was able to get my service started at Boot.
First of all, you should have a BroadcastReceiver for the event android.intent.action.BOOT_COMPLETED. Just follow the steps from the blog. It seems you have started the service on your app's 'onCreate'. This will get invoked only if the user starts your app.
When the system boots up, your receiver class's onReceive() method will be invoked. Here is where you should start your activity as below.
public class BootReceiever extebds BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
Intent service = new Intent(context, YourService.class);
context.startService(service);
}
}
From the research that I have done, it is better to start your service after a short delay as many applications / services may start at boot, so chances of low memory are more. I started my service after a small delay.
I am trying to set up a service that checks when a new update of an activity is installed in a device. I have already done so within an application activity, declaring the Broadcastreceiver in the manifest and it works perfectly.
However, when I try to run that receiver within a Service and dynamically declare it, my onReceive never gets called. This is my Service code:
public class UpdateService extends Service {
private static String mPackage = "com.my.package";
private static String mActivityName = "myActivity";
private BroadcastReceiver mUpdateReceiver;
#Override
public void onCreate() {
super.onCreate();
mUpdateReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("mTag","In the BroadcastReceiver onReceive()");
if (intent.getAction().equalsIgnoreCase(Intent.ACTION_PACKAGE_REPLACED)) {
// Log that a new update is has been found
Log.d("mTag","New version of the app has been installed.");
Log.d("mTag", "Intent data: " + intent.getDataString());
Log.d("mTag","My package: " + mPackage);
}
}
};
Log.d("mTag","In the service onCreate() method.");
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
filter.addAction(Intent.ACTION_PACKAGE_ADDED);
registerReceiver(mUpdateReceiver,filter);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("mTag","UpdateService started");
return Service.START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(mUpdateReceiver);
Log.d("mTag","Service destroyed");
}
#Override
public IBinder onBind(Intent arg0) {
return null;
}
}
The Log in the Service onCreate() gets called, which tells me that the service is up and running. However, after installing and replacing some apps through the adb, none of the logs in the BroadcastReceiver the method onReceive() get called.
This is my MainActivity:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startService(new Intent(this, UpdateService.class));
}
}
Do you guys have any ideas why the onReceive() does not get called?
Thank you.
I based my code in these two references:
BroadcastReceiver within a Service
How to know Android app upgraded?
you should add the data schema to your IntentFilter.
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
filter.addAction(Intent.ACTION_PACKAGE_ADDED);
filter.addDataScheme("package");
registerReceiver(mUpdateReceiver,filter);
If you are trying to listen to the ACTION_PACKAGE_REPLACED broadcast, this cannot be done from service. Most probably, the replacement will happen when your application is closed. That`s why you will not listen to it.
You should register from the Manifest to let your OS know that you want to listen to this Intent then Create a class that extentsBroadcastReceiver` as the following:
Manifest:
<receiver android:name="PackageChangeReceiver" >
<intent-filter>
<action android:name="android.intent.action.PACKAGE_REPLACED" />
<data android:scheme="package" />
</intent-filter>
</receiver>
Receiver:
public class PackageChangeReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_PACKAGE_REPLACED) && intent.getDataString().contains(context.getPackageName())) {
Log.d("Tag", "Package has been replaced");
Log.d("Tag", "Intent data: " + intent.getDataString());
Log.d("Tag", "Action: " + intent.getAction());
}
}
}
I have checked if intent.getDataString().contains(context.getPackageName()) to make sure that the replacement of the package is mine not any other application.
i want to make my app to be run in background and listens for
contact,sms deletion events.
for that i created a service in my app but i dnt how to start without activity
my code is like this
public class DeleteService extends Service {
ContentResolver cr;
MyContentObserver observer=new MyContentObserver();
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return mBinder;
}
#Override
public void onCreate() {
cpath=ContactsContract.Contacts.CONTENT_URI;
// some action
}
#Override
public void onDestroy() {
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Launch a background thread to do processing.
super.onStartCommand(intent, flags, startId);
cpath=ContactsContract.Contacts.CONTENT_URI;
cr=getContentResolver();
cur=cr.query(cpath, null, null, null, null);
this.getApplicationContext().getContentResolver().registerContentObserver(cpath, true, observer);
return Service.START_STICKY;
}
private class MyContentObserver extends ContentObserver {
public MyContentObserver() {
super(null);
}
#Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
nfm=(NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
int NOTIFICATION_ID = 1;
Intent intent1 = new Intent();
PendingIntent pi = PendingIntent.getActivity(DeleteService.this, 1, intent1, 0);
nf=new Notification(R.drawable.ic_launcher,"Contact Database changed",System.currentTimeMillis());
nf.setLatestEventInfo(getApplicationContext(), "Delete Event", "contact name", pi);
nf.flags = nf.flags |
Notification.FLAG_ONGOING_EVENT;
}
#Override
public boolean deliverSelfNotifications()
{
super.deliverSelfNotifications();
return true;
}
}
public class LocalBinder extends Binder {
DeleteService getService() {
return DeleteService.this;
}
}
}
register ACTION_SCREEN_ON or ACTION_USER_PRESENT broadcast recivers for your Appliction in Service and start Service when screen is on or user is present. you can register ACTION_SCREEN_OFF broadcast reciver for stoping Service when phone screen is off to avoid battery drain by your app.as:
In manifest.xml:
<receiver android:name="com.my.AppStart">
<intent-filter>
<action android:name="android.intent.action.SCREEN_ON" />
<action android:name="android.intent.action.SCREEN_OFF" />
<action android:name="android.intent.action.USER_PRESENT" />
</intent-filter>
</receiver>
BroadcastReceiver :
public class AppStart extends BroadcastReceiver {
public static final String present = "android.intent.action.USER_PRESENT";
public static final String screenon = "android.intent.action.SCREEN_ON";
public static final String screenoff = "android.intent.action.SCREEN_OFF";
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(present) || intent.getAction().equals(screenon) )
{
Intent i=new Intent(context,DeleteService.class);
context.startService(i);
}
if (intent.getAction().equals(screenoff))
{
//STOP YOUR SERVICE HERE
}
}
}
A service can only by started by an Activity, or a BroadCast receiver, or a service which is already started. It can't be stand-alone(It can't start by itself). So, you would need one of the two components to start it. you can make an activity which starts the service which is the preferred way. But if you don't want to provide a user interface, implement a broadcast receiver which fires up when the phone is switched on and the boot up is completed, Inside that br, start your service. This will also help you run the service as soon as a phone starts.
for example in your manifest:
<receiver android:name="com.my.MyBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
and in the br:
public class MyBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent i=new Intent(context,DeleteService.class);
context.startService(i);
}
}
In your activity .. put this code in oncreate
Intent svc=new Intent(youractivity.this,DeleteService.class);
startService(svc);