I have a BroadcastReceiver named StartService which start when the phone boots which in turn starts a service but when I am going to the service from this BroadcastReceiver I get exception:
android.content.ReceiverCallNotAllowedException: IntentReceiver components are not allowed to bind to services
my code is below:
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.util.Log;
public class StartService extends BroadcastReceiver {
private RemoteServiceConnection conn = null;
private IMyRemoteService remoteService;
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Intent startServiceIntent = new Intent(context, RemoteServiceClient.class);
context.startService(startServiceIntent);
conn = new RemoteServiceConnection();
Intent i = new Intent();
i.setClassName("com.collabera.labs.sai", "com.collabera.labs.sai.RemoteService");
context.bindService(i, conn, Context.BIND_AUTO_CREATE);
}
class RemoteServiceConnection implements ServiceConnection {
public void onServiceConnected(ComponentName className,
IBinder boundService ) {
remoteService = IMyRemoteService.Stub.asInterface((IBinder)boundService);
Log.d( getClass().getSimpleName(), "onServiceConnected()" );
}
public void onServiceDisconnected(ComponentName className) {
remoteService = null;
Log.d( getClass().getSimpleName(), "onServiceDisconnected" );
}
};
}
some of the step follow.
Step 1:
public class StartService extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent) {
Intent startServiceIntent = new Intent(context, myServices.class);
context.startService(startServiceIntent);
}
}
Step 2:
// make all service related task
Step 3:
<service
android:name=".myServices"
android:enabled="true" />
<receiver android:name="com.yourpackage.StartService " >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
I am always used BroadcastReceiver and services this way.
May be helpful for you.If helpful then accept answer.
Related
My target was Restarting the Service when app is in background or even killed from home page by sweeping. App & Service is working nice while app is in foreground and background but while I killed the app by force(sweeping out from home page), the Service stopped working. That's okay but I implemented a Broadcast Receiver to restart the Service but it seems like its (Broadcast Receiver) not even called itself or the Service while app was killed forcefully / sweeping from home page.
My device is : Xiaomi Redmi Note 4
I included my codes here :
MainActivity.java
package com.turzo.servicetest;
import android.app.ActivityManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends AppCompatActivity {
private String TAG = "ServiceTest";
Intent mServiceIntent;
private SensorService mSensorService;
Context ctx;
public Context getCtx() {
return ctx;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ctx = this;
registerRec();
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 (TAG, true+"");
return true;
}
}
Log.i (TAG, false+"");
return false;
}
#Override
protected void onDestroy() {
stopService(mServiceIntent);
Log.i(TAG, "onDestroy!");
super.onDestroy();
}
public void registerRec(){
SensorRestarterBroadcastReceiver myreceiver = new SensorRestarterBroadcastReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver((BroadcastReceiver) myreceiver, intentFilter);
}
}
SensorService.java
package com.turzo.servicetest;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;
import java.util.Timer;
import java.util.TimerTask;
public class SensorService extends Service {
public int counter=0;
private String TAG = "ServiceTest";
public SensorService(Context applicationContext) {
super();
Log.i(TAG , "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(TAG , "ondestroy!");
Intent broadcastIntent = new Intent("com.turzo.servicetest.ActivityRecognition.RestartSensor");
sendBroadcast(broadcastIntent);
stoptimertask();
}
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(TAG , "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;
}
}
SensorRestarterBroadcastReceiver.java
package com.turzo.servicetest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class SensorRestarterBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.i(SensorRestarterBroadcastReceiver.class.getSimpleName(), "Service Stops! Oooooooooooooppppssssss!!!!");
context.startService(new Intent(context, SensorService.class));
}
}
AndroidManifext.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.turzo.servicetest">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name="com.turzo.servicetest.SensorService"
android:enabled="true" >
</service>
<receiver
android:name="com.turzo.servicetest.SensorRestarterBroadcastReceiver"
android:enabled="true"
android:exported="true"
android:label="RestartServiceWhenStopped">
<intent-filter>
<action android:name="com.turzo.servicetest.ActivityRecognition.RestartSensor"/>
</intent-filter>
</receiver>
</application>
</manifest>
You should restart Service in onTaskRemoved().
#Override
public void onTaskRemoved(Intent rootIntent) {
Intent restartService = new Intent(getApplicationContext(),
this.getClass());
restartService.setPackage(getPackageName());
PendingIntent restartServicePI = PendingIntent.getService(
getApplicationContext(), 1, restartService,
PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmService = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
alarmService.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + 1000, restartServicePI);
}
NOTE:- Starting from android O . You can not call startService.
The startService() method now throws an IllegalStateException if an app targeting Android 8.0 tries to use that method in a situation when it isn't permitted to create background services.
This does not apply to foreground services, which are noticeable to the user. It can run in background with a notification on top. By default, these restrictions only apply to apps that target Android 8.0 (API level 26) or higher. However, users can enable most of these restrictions for any app from the Settings screen, even if the app targets an API level lower than 26. So in case if user enables the restrictions for below API 26 your Service will not work.
Read Background Execution Limits.
So Try to avoid using Service if you can . Make use of WorkManager if it fits the requirements.
i am running my app on android version 2.2.1 and i am using broadcastreceiver to to start an activity as soon as my screen unlocks.this this is not happening...can anyone help me
here is my code
import com.example.app.MainActivity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
import android.app.Activity;
public class ScreenReceiver extends BroadcastReceiver {
Activity ac = new Activity();#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
//Toast.makeText(context, "action received", Toast.LENGTH_LONG).show();
Intent i = new Intent();
i.setClass(context, MainActivity.class);
ac.startActivity(i);
}
}
}
and
<receiver android:name="ScreenReceiver">
<intent-filter>
<action android:name="android.intent.action.SCREEN_ON"/>
</intent-filter>
</receiver>
You should NEVER instantiate Activity with new. Here is correction of how you should have done it. Just use the method parameter context.
public class ScreenReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
Intent i = new Intent(context, MainActivity.class);
context.startActivity(i);
}
}
}
I made a service that every 5 second he put on the screen a TAG (I think this is the name of this). When I make a boot it needs to put the TAG on the screen but he says that the app crashed. Why?
The code:
Android Manifest:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<receiver android:name="com.YuvalFatal.MyBroadcastReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<service android:enabled="true" android:name="com.YuvalFatal.MyService"/>
BroadcastReceiver:
package com.YuvalFatal.ineedhelp;
import java.util.Timer;
import java.util.TimerTask;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class MyBroadcastreceiver extends BroadcastReceiver {
#Override
public void onReceive(final Context arg0, Intent arg1) {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
Intent startServiceIntent = new Intent(arg0, MyService.class);
arg0.startService(startServiceIntent);
}
}, 0, 5000);
}
}
IntentService:
package com.YuvalFatal.ineedhelp;
import android.app.IntentService;
import android.content.Intent;
import android.util.Log;
public class MyService extends IntentService {
private static final String TAG = "com.YuvalFatal.ineedhelp";
public MyService(String name) {
super(name);
// TODO Auto-generated constructor stub
}
#Override
protected void onHandleIntent(Intent intent) {
// TODO Auto-generated method stub
Log.i(TAG, "Intent Service started");
}
}
I think (yep, I am magician and have great intuition :) your Service constructor should be default:
public class MyService extends IntentService {
...
public MyService() { // Default constructor! Without params!
super("MyService"); // Or another string
}
...
}
Other code looks normal
I am building a piece of code that imitates an activity when the phone receives an active Bluetooth connection. This is to run as a service so it can be picked up on in the moment.
Here is the code I am working with. Right now its not launching the intent but its not failing either. How do I get this to run properly?
import android.app.Service;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
public class detectService extends Service{
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
private BroadcastReceiver ConnectListener = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent)
{
String action = intent.getAction();
if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action))
{
intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
//Start Second Activity
Intent secondIntent = new Intent(detectService.this, otherClass.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(secondIntent);
}
}
};
}
You need to register the receiver you created using
registerReceiever(ConnectListener, intentFilter);
the intent filter in your case will be the bluetooth connnect filter, something like
IntentFilter intentFilter = new IntentFilter(BluetoothDevice.ACTION_ACL_CONNECTED);
For a more complete example look at this other post
I'm having trouble getting the onServiceConnected() method to run, which means that it's not binding my activity to the service.
It's probably something simple that I've missed out - but I've tried quite a few times - starting from scratch.
Here we go...
My Service Class
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
public class QuickService extends Service {
private final IBinder mBinder = new QuickBinder(this);
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
}
My Binder Class
import android.os.Binder;
public class QuickBinder extends Binder {
private final QuickService service;
public QuickBinder(QuickService service){
this.service = service;
}
public QuickService getService(){
return service;
}
}
And... The Activity trying to bind to the service.
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
public class QuickActivity extends Activity {
QuickService mService;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_connecting);
}
#Override
protected void onStart() {
super.onStart();
Intent intent = new Intent(this, QuickService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
#Override
protected void onStop() {
super.onStop();
// Unbind from the service
unbindService(mConnection);
}
/** Defines callbacks for service binding, passed to bindService() */
private ServiceConnection mConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName className,
IBinder service) {
Logger.d("Connected!!! :D");
// We've bound to LocalService, cast the IBinder and get LocalService instance
QuickBinder binder = (QuickBinder) service;
mService = binder.getService();
}
#Override
public void onServiceDisconnected(ComponentName arg0) {
}
};
}
Also, the Service defined in the manifest file - in case you thought that was the problem.
<service android:name=".QuickService"></service>
So, What am I doing wrong here? Why isn't the onServiceConnected() method being called?
Update it with following
<service android:name=".QuickService">
<intent-filter>
<action android:name=".QuickService .BIND" />
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</service>
Instead of writing:
Intent intent = new Intent(this, QuickService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
You can write:
startService(new Intent(QuickActivity.this, QuickService.class));
where you want to start service.
Hope this will help you.