I am trying to bind to a service, but the bind service method always returns false. I believe the problem is in my connection. When I import the location of the LocalBinder class (in the service) I dont get any compile errors but the bindService call is still false.
Service information:
//binder for client
private final IBinder mBinder = new LocalBinder();
//client class binder
public class LocalBinder extends Binder {
ServiceA getService() {
// Return this instance of LocalService so clients can call public methods
return ServiceA.this;
}
}
#Override
public IBinder onBind(Intent arg0) {
return mBinder;
}
//called when service is created
public void onCreate(){
super.onCreate();
Toast.makeText(this,"ServiceA is started",Toast.LENGTH_SHORT).show();
}
Connection:
private ServiceConnection connect2A = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName className,
IBinder service) {
// We've bound to LocalService, cast the IBinder and get LocalService instance
LocalBinder newBinder = (LocalBinder) service;
mainService = newBinder.getService();
bound = true;
}
#Override
public void onServiceDisconnected(ComponentName arg0) {
bound = false;
}
};
Initial calls:
#Override
protected void onStart(){
super.onStart();
Intent intent = new Intent(this, ServiceA.class);
startService(intent);
boolean check = bindService(intent,connect2A,0);
Toast.makeText(this, "Return from check is: " + check, Toast.LENGTH_LONG).show();
//program does get to this point, but binding fails
}
the AndroidManifest.XML file:
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name=".ServiceTest2Activity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:enabled="true" android:name=".serviceA" />
</application>
Some ideas:
-What class is the onStart() method in? I bind to my services in onCreate().
-Do you perhaps need to pass Context.BIND_AUTO_CREATE to the bindService call? e.g.
boolean check = bindService(intent, connect2A, Context.BIND_AUTO_CREATE);
-As the other commenter suggests, you should post the relevant snippets from your AndroidManifest.xml.
-You should put some trace/toast in the onServiceConnected method so you know if it is getting called.
Related
I have implemented Service in Application but need to stop service after killing App. But I got an issue in Android O. There is one Method onTaskRemoved which in not call in Orio. I am also trying to JobScheduler But getting the same issue. ANy suggestion or solution will be appreciated. :)
Start Service:
ServiceConnection mConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName className,
IBinder service) {
// We've bound to LocalService, cast the IBinder and get LocalService instance
}
#Override
public void onServiceDisconnected(ComponentName arg0) {
}
};
Intent intentService = new Intent(this, ServiceClass.class);
bindService(intentService, mConnection, Context.BIND_AUTO_CREATE);
Service Class:
public class ServiceClass extends Service {
private final IBinder mBinder = new LocalBinder();
#Nullable
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
#Override
public void onTaskRemoved(Intent rootIntent) {
stopSelf();
super.onTaskRemoved(rootIntent);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_NOT_STICKY;
}
public class LocalBinder extends Binder {
public ServiceClass getService() {
// Return this instance of LocalService so clients can call public methods
return ServiceClass.this;
}
}
}
AndroidManfiest.xml
<service android:name="Service"
android:stopWithTask="false"/>
I Hope this will work for you
android:stopWithTask="false"
Add this attribute in your service tag in manifest file.
I have an android device with an integrated barcode scanner. I'm setting up the service as follows:
public class BarcodeService extends Service {
private final LocalBinder binder = new LocalBinder();
public class LocalBinder extends Binder {
public BarcodeService getService() {
return BarcodeService.this;
}
}
#Override
public IBinder onBind(Intent arg0) {
return binder;
}
#Override
public void onCreate() {
super.onCreate();
HandlerThread thread = new HandlerThread("ServiceStartArguments");
thread.start();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//Get scanner
}
}
The service is also in the AndroidManifest.xml. The class that makes use of this service is:
public class BarcodeReader extends Activity {
private BarcodeService barcodeService;
private boolean isBound = false;
private ServiceConnection barcodeServiceConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
barcodeService = ((BarcodeService.LocalBinder)service).getService();
isBound = true;
}
#Override
public void onServiceDisconnected(ComponentName name) {
barcodeService = null;
isBound = false;
}
};
#Override
protected void onStart() {
super.onStart();
if (!isBound) {
Intent intent = new Intent(this, BarcodeService.class);
startService(intent);
bindService(intent, barcodeServiceConnection, Context.BIND_AUTO_CREATE);
}
}
#Override
protected void onStop() {
super.onStop();
if (isBound) {
unbindService(barcodeServiceConnection);
}
}
}
However the service is not binding, ie. barcodeService is always null. The code never reaches onServiceConnected.
What am I missing? And is it necessary to use a class that extends Activity?
Common Android Service troubleshooting
Just some general remarks and stuff to check if your service is not starting.
Service class defined in Manifest
Common mistake is not to have the service in manifest (android doesn't warn you about that) or have it there but misspelled the class name.
<manifest ... >
...
<application ... >
<service android:name=".ExampleService" />
...
</application>
</manifest>
Or you might have it in the manifest (or one of the manifests) but the final manifest after merging that is used within the apk doesn't have the service definition. For that check:
project_folder/app_folder/build/intermediates/manifests/full/...
A project clean and rebuild might help.
Check bindService return value
When debugging check the boolean return value on the bindService call to see if service was started successfully or not.
Debug Activity and Service implementation
Also the service might be running but not bind or might not execute anything hence have no visual effect that it's running in the background. For that use the debugger on both the bound Activity and the Service itself.
Check onBind, onStartCommand in Service class or even the onCreate there.
In Activity check bindService, ServiceConnection and so.
Resources
also check https://developer.android.com/guide/components/services.html
I have an Android project that starts a Service. Then i turned that into an Android library and added it to another Android Project.
Now i am trying to automatically start that service from my Main Android project but i am lost.
This is my code from manifest(i have added all my classed from library):
<service
android:name="com.test.mqttclientserver.MQTTService"
android:enabled="true"
android:exported="false"
android:label="Service" >
<intent-filter>
<action android:name="com.test.mqttclientserver.MQTTService" />
</intent-filter>
</service>
<activity
android:name="com.test.mqttclientserver.MQTTClient"
android:label="#string/app_name" >
</activity>
<activity
android:name="com.test.mqttclientserver.MQTTNotifier"
android:label="#string/app_name" >
</activity>
In an Activity of the main project:
private boolean mBounded;
private MQTTService mService;
private MQTTConnectionStatus connectionStatus = MQTTConnectionStatus.INITIAL; ..... public IBinder onBind(Intent intent) {
return mBinder;
}
public MQTTConnectionStatus getConnectionStatus() {
return connectionStatus;
}
ServiceConnection mConnection = new ServiceConnection() {
public void onServiceDisconnected(ComponentName name) {
Toast.makeText(SplashScreen.this, "Service is disconnected", 1000)
.show();
mBounded = false;
mService = null;
}
public void onServiceConnected(ComponentName name, IBinder service) {
Toast.makeText(SplashScreen.this, "Service is connected", 1000).show();
mBounded = true;
LocalBinder mLocalBinder = (LocalBinder) service;
mService = (MQTTService) mLocalBinder.getService();
}
};
public void onStart(final Intent intent, final int startId) {
System.out.println("onStart loading...");
Intent mIntent = new Intent(this, MQTTService.class);
bindService(mIntent, mConnection, BIND_AUTO_CREATE);
System.out.println("onStart ending...");
}
protected void onStop() {
super.onStop();
if (mBounded) {
unbindService(mConnection);
mBounded = false;
}
}
Isn't this enough? Just a hint would suffice. Thank you for your time.
I'm trying to start a service on android in order to performe some network-related tasks in background. I have written a basic network-manager for my app, which is a service. I basically used the tutorial from the android documentation. The basic structure goes as following:
public class MyNetworkManager extends Service {
// some code
private final IBinder mBinder = (IBinder) new MyBinder();
#Override
public IBinder onBind(Intent arg0) {
return mBinder;
}
public class MyBinder extends Binder {
MyNetworkManager getService() {
return MyNetworkManager.this;
}
}
public void onCreate() {
// some network related stuff like setting up sockets etc.
}
public void onStart(Intent intent, int startid) {
while(true) {
// receive new connections etc
}
}
The calling app/activity is then:
public class AndroidNetworkManagerClient extends Activity {
private Button buttonSend;
private EditText inputText;
private TextView outputText;
private MyNetworkManager networkManager;
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder binder) {
networkManager = ((MyNetworkManager.MyBinder) binder).getService();
}
public void onServiceDisconnected(ComponentName className) {
networkManager = null;
}
};
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
inputText = (EditText) findViewById(R.id.textInput);
outputText = (TextView) findViewById(R.id.textOutput);
buttonSend = (Button)this.findViewById(R.id.buttonSend);
buttonSend.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if (inputText.getText().length() != 0) {
outputText.append("Out: " + inputText.getText() + "\n");
networkManager.sendData("localhost", inputText.getText().toString());
}
}
});
bindService(new Intent(this, MyNetworkManager.class), mConnection, Context.BIND_AUTO_CREATE);
doSomeAppRelatedStuff();
}
bindService() seems to be called without any problems, but the variable "networkManager" is always null! I already tried to debug into the onCreate() method or onServiceConnected() but it seems, that these parts are not reached at all (at least no breakpoint was triggered).
The service is already registered in the AndroidManifest.xml:
package="some.random.name"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="8" />
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:name=".AndroidNetworkManagerClient"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".MyNetworkManager"></service>
</application>
Anyone an idea?
Chances are, your Activity is getting into doSomeAppRelatedStuff() and trying to use networkManager before the binding is complete.
If doSomeAppRelatedStuff() absolutely must have the network manager to function, move your call to doSomeAppRelatedStuff() into onServiceConnected() so it won't actually start until the binding is complete. Note that if you do that, your onStart() and onResume() calls will probably (but not guaranteed!) happen before the binding is complete, so program accordingly.
can you give me a simple example of an application with background service which uses bind/unbind methods to start and stop it? I was googling for it for a half-hour, but those examples use startService/stopService methods or are very difficult for me. thank you.
You can try using this code:
protected ServiceConnection mServerConn = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName name, IBinder binder) {
Log.d(LOG_TAG, "onServiceConnected");
}
#Override
public void onServiceDisconnected(ComponentName name) {
Log.d(LOG_TAG, "onServiceDisconnected");
}
}
public void start() {
// mContext is defined upper in code, I think it is not necessary to explain what is it
mContext.bindService(intent, mServerConn, Context.BIND_AUTO_CREATE);
mContext.startService(intent);
}
public void stop() {
mContext.stopService(new Intent(mContext, ServiceRemote.class));
mContext.unbindService(mServerConn);
}
Add these methods to your Activity:
private MyService myServiceBinder;
public ServiceConnection myConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder binder) {
myServiceBinder = ((MyService.MyBinder) binder).getService();
Log.d("ServiceConnection","connected");
showServiceData();
}
public void onServiceDisconnected(ComponentName className) {
Log.d("ServiceConnection","disconnected");
myService = null;
}
};
public Handler myHandler = new Handler() {
public void handleMessage(Message message) {
Bundle data = message.getData();
}
};
public void doBindService() {
Intent intent = null;
intent = new Intent(this, BTService.class);
// Create a new Messenger for the communication back
// From the Service to the Activity
Messenger messenger = new Messenger(myHandler);
intent.putExtra("MESSENGER", messenger);
bindService(intent, myConnection, Context.BIND_AUTO_CREATE);
}
And you can bind to service by ovverriding onResume(), and onPause() at your Activity class.
#Override
protected void onResume() {
Log.d("activity", "onResume");
if (myService == null) {
doBindService();
}
super.onResume();
}
#Override
protected void onPause() {
//FIXME put back
Log.d("activity", "onPause");
if (myService != null) {
unbindService(myConnection);
myService = null;
}
super.onPause();
}
Note, that when binding to a service only the onCreate() method is called in the service class.
In your Service class you need to define the myBinder method:
private final IBinder mBinder = new MyBinder();
private Messenger outMessenger;
#Override
public IBinder onBind(Intent arg0) {
Bundle extras = arg0.getExtras();
Log.d("service","onBind");
// Get messager from the Activity
if (extras != null) {
Log.d("service","onBind with extra");
outMessenger = (Messenger) extras.get("MESSENGER");
}
return mBinder;
}
public class MyBinder extends Binder {
MyService getService() {
return MyService.this;
}
}
After you defined these methods you can reach the methods of your service at your Activity:
private void showServiceData() {
myServiceBinder.myMethod();
}
and finally you can start your service when some event occurs like _BOOT_COMPLETED_
public class MyReciever extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals("android.intent.action.BOOT_COMPLETED")) {
Intent service = new Intent(context, myService.class);
context.startService(service);
}
}
}
note that when starting a service the onCreate() and onStartCommand() is called in service class
and you can stop your service when another event occurs by stopService()
note that your event listener should be registerd in your Android manifest file:
<receiver android:name="MyReciever" android:enabled="true" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
First of all, two things that we need to understand,
Client
It makes request to a specific server
bindService(new Intent("com.android.vending.billing.InAppBillingService.BIND"),
mServiceConn, Context.BIND_AUTO_CREATE);
here mServiceConn is instance of ServiceConnection class(inbuilt) it is actually interface
that we need to implement with two (1st for network connected and 2nd network not connected) method to monitor network connection state.
Server
It handles the request of the client and makes replica of its own which is private to client only who send request and this raplica of server runs on different thread.
Now at client side, how to access all the methods of server?
Server sends response with IBinder Object. So, IBinder object is our handler which accesses all the methods of Service by using (.) operator.
.
MyService myService;
public ServiceConnection myConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder binder) {
Log.d("ServiceConnection","connected");
myService = binder;
}
//binder comes from server to communicate with method's of
public void onServiceDisconnected(ComponentName className) {
Log.d("ServiceConnection","disconnected");
myService = null;
}
}
Now how to call method which lies in service
myservice.serviceMethod();
Here myService is object and serviceMethod is method in service.
and by this way communication is established between client and server.