In my application I want to establish a TCP connection with a service and bind this service to every activity where it is needed. It gets started in my Login activity and everything is working like it should. Here is the code:
private TCPService mService;
private boolean mBound = false;
#Override
protected void onStart() {
super.onStart();
Intent intent = new Intent(this, TCPService.class);
startService(intent);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
#Override
protected void onStop() {
super.onStop();
if (mBound) {
unbindService(mConnection);
mBound = false;
}
}
/** Defines callbacks for service binding, passed to bindService() */
private ServiceConnection mConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName className, IBinder service) {
// We've bound to LocalService, cast the IBinder and get LocalService instance
TCPService.LocalBinder binder = (TCPService.LocalBinder)service;
mService = binder.getService();
mBound = true;
}
#Override
public void onServiceDisconnected(ComponentName arg0) {
mBound = false;
}
};
Now I want to bind the service in another activity by using almost the same code just without startService(intent); But the mBound is never set to true and I can't access the service functions like it is intented.
Here is the implementation of the service:
public class TCPService extends Service {
private final IBinder myBinder = new LocalBinder();
public class LocalBinder extends Binder {
public TCPService getService() {
return TCPService.this;
}
}
#Override
public IBinder onBind(Intent intent) {
return myBinder;
}
}
What am I missing out? Is there anything I should check that may cause this behaviour?
Thanks in advance
Related
I want to start 2 services at the start of an activity but only the first one starts and the second fails at bindService(). There is no error just when I want to do something with the service it gives me a nullpointer. I also tried to wait to do something but the service never starts.
The 2 services are pretty similar and I just want to know what is wrong with the implementation. I tried to debug and bindservice() function at startSoundmanagerService return 0, what is maybe the root of the problem but I don't know why.
public class SimulationActivity extends AppCompatActivity {
BluetoothService BService;
boolean mBound = false;
SoundManager SService;
boolean sBound = false;
#Override
protected void onStart() {
super.onStart();
if (bluetoothAdapter.isEnabled()) {
setStatusText("Bluetooth on");
}
else {
setStatusText("Bluetooth off");
}
if(!mBound) {
startServer();
}
conStatImageView.setImageResource(R.drawable.connection_off);
if(!sBound){
startSoundManagerService();
}
#Override
protected void onStop() {
super.onStop();
if(mBound) {
unbindService(bConnection);
mBound = false;
}
if(sBound){
unbindService(sConnection);
sBound = false;
}
}
private ServiceConnection bConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName className,
IBinder service) {
BluetoothService.LocalBinder binder =
(BluetoothService.LocalBinder) service;
BService = binder.getService();
mBound = true;
}
#Override
public void onServiceDisconnected(ComponentName arg0) {
mBound = false;
}
};
private ServiceConnection sConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName className,
IBinder service) {
SoundManager.LocalBinder binder = (SoundManager.LocalBinder) service;
SService = binder.getService();
sBound = true;
}
#Override
public void onServiceDisconnected(ComponentName arg0) {
sBound = false;
}
public void startServer(){
if (bluetoothAdapter == null) {
Log.d("tag","Device doesn't support Bluetooth") ;
}
if (!bluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
if(bluetoothAdapter.isEnabled()){
startBluetoothservice();
}
}
private void startBluetoothservice(){
Intent intent = new Intent (this,BluetoothService.class);
bindService(intent, bConnection, Context.BIND_AUTO_CREATE);
Log.i(TAG,"Trying to start bluetoothservice");
}
private void startSoundManagerService(){
Intent intent = new Intent (this,SoundManager.class);
bindService(intent, sConnection, Context.BIND_AUTO_CREATE);
Log.i(TAG,"Trying to start soundservice");
}
So how can I implement 2 different services in 1 activity?
Edit Solution: I forgot to register the service in the manifestfile. ;)
I found the solution: I forgot to register the 2nd Service in the manifest. Thats all ;)
How can I have something like this java code in Kotlin?
Even the IDE does not convert it to Kotlin perfectly!
/** Defines callbacks for service binding, passed to bindService() */
private ServiceConnection mConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName className,
IBinder service) {
// We've bound to LocalService, cast the IBinder and get LocalService instance
LocalBinder binder = (LocalBinder) service;
mService = binder.getService();
mBound = true;
}
#Override
public void onServiceDisconnected(ComponentName arg0) {
mBound = false;
}
};
I tried using inner class but then I was not able to use it like this:
#Override
protected void onStart() {
super.onStart();
// Bind to LocalService
Intent intent = new Intent(this, LocalService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
You're creating an anonymous class here. In Kotlin, these are object expressions:
val connection = object: ServiceConnection {
override fun onServiceConnected(className: ComponentName, service: IBinder) {
//Something to do
}
override fun onServiceDisconnected(arg0: ComponentName) {
//Something to do
}
}
I have some programm, where I want to save the instance of service and use it in another activities. But service doesn't create.
Just see the code, please.
MainActivity.java:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MainService.get(this);
}
}
MainService.java:
public class MainService extends Service {
public static Object sWait = new Object();
public static MainService instance;
#Override
public IBinder onBind(Intent intent) {
return null;
}
public static MainService get(Context mContext) {
if (instance == null) {
Intent intent = new Intent(mContext, MainService.class);
mContext.startService(intent);
}
while (true) {
if (instance != null) {
Log.v("myLogs", "all is good!");
break;
}
synchronized (sWait) {
try {
sWait.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
return instance;
}
#Override
public void onCreate() {
Log.v("myLogs", "created!");
instance = this;
synchronized (sWait) {
sWait.notify();
}
}
}
When I don't use while in MainService.get(), service creates. I added this service to manifest file. I don't know where is there error. I need your help.
That's just not the way you should use Service in Android.
What you probably need is to use bindService() call from your Activity.
See more about bound service here http://developer.android.com/guide/components/bound-services.html
If you need the service to be the same instance each time you bind to it, call startService once when your application start.
Example code:
public class LocalBinder<T> extends Binder {
private WeakReference<T> mService;
public LocalBinder(T service) {
mService = new WeakReference<T>(service);
}
public T getService() {
return mService.get();
}
}
public class MyService extends Service {
private final LocalBinder<MyService> binder;
public MyService() {
binder = new LocalBinder<MyService>(this);
}
#Override
public IBinder onBind(Intent intent) {
return binder;
}
}
public class MyActivity extends Activity implements ServiceConnection {
#Override
protected void onStart() {
super.onStart();
bindService(new Intent(this, MyService.class), this, Context.BIND_AUTO_CREATE);
}
#Override
protected void onStop() {
super.onStop();
unbindService(this);
}
#SuppressWarnings("unchecked")
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
MyService serv = ((LocalBinder<MyService>) service).getService();
// serv is your service instance now
}
#Override
public void onServiceDisconnected(ComponentName name) {
}
}
To start your service use (call this from your activity!):
Intent serviceIntent = new Intent(this, MainService.class);
startService(serviceIntent);
see docs: https://developer.android.com/training/run-background-service/send-request.html
That is definitely not the way you are supposed to use services in android.
I would suggest you revisit the offical android docs.
To get a quick introduction visit this tutorial here.
i'm trying to write an android program where there are 2 service, one for bluetooth connection and another to call the method in bluetooth connection service. I'd like to know if i could bind these 2 services together, i tried but stuck
this code is from 2nd service when i tried to bind it to the bluetooth service
public class ActionHandler extends Service {
BTservice btService;
boolean mBound = false;
private final IBinder mBinder = new LocalBinder();
public class LocalBinder extends Binder {
ActionHandler getService() {
// Return this instance of LocalService so clients can call public methods
return ActionHandler.this;
}
}
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return mBinder;
}
#Override
public int onStartCommand(Intent in, int flags, int startId) {
// TODO Auto-generated method stub
//Bind to Service
Intent intent = new Intent(this,BTservice.class);
bindService(intent,mConnection,Context.BIND_AUTO_CREATE);
return START_STICKY;
}
/** Defines callbacks for service binding, passed to bindService() */
private ServiceConnection mConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName className,
IBinder service) {
// We've bound to LocalService, cast the IBinder and get LocalService instance
LocalBinder binder = (LocalBinder) service;
btService = binder.getService();
mBound = true;
}
#Override
public void onServiceDisconnected(ComponentName arg0) {
mBound = false;
}
};
}
eclipse said that btService type mismatch, what should i do?
How to pass handler from an activity to service? I am trying to update the activity UI on the state of Bluetooth connection by using Handler as shown below from service class.
mHandler.obtainMessage(MenuActivity.MESSAGE_STATE_CHANGE, state, -1).sendToTarget();
In the activity, I implemented this:
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_STATE_CHANGE:
if (true)
Log.i(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1);
switch(msg.arg1){
case BluetoothService.STATE_CONNECTED:
showToast("Connected to " + mConnectedDeviceName, Toast.LENGTH_SHORT);
break;
I tried to use a constructor to pass the handler from the activity to service like this:
public BluetoothService(Handler handler, BluetoothAdapter mBluetoothAdapter) {
mAdapter = mBluetoothAdapter;
mState = STATE_NONE;
mHandler = handler;
}
But there was an error which shows Unable to instantiate service and found that the service needs to have a public no-args constructor. But after removing the constructor, the handler did not get passed into the service.
How to solve this problem?
You have to bind to the service from activity and establish a ServiceConnection and then get the instance of service and set your handler.
Here is the activity and service class which i use for one of my media player application.....
public class MainActivity extends Activity
{
private CustomService mService = null;
private boolean mIsBound;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
startService(new Intent(this.getBaseContext(), CustomService.class));
doBindService();
}
private ServiceConnection mConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder)
{
mService = ((CustomService.LocalBinder)iBinder).getInstance();
mService.setHandler(yourHandler);
}
#Override
public void onServiceDisconnected(ComponentName componentName)
{
mService = null;
}
};
private void doBindService()
{
// Establish a connection with the service. We use an explicit
// class name because we want a specific service implementation that
// we know will be running in our own process (and thus won't be
// supporting component replacement by other applications).
bindService(new Intent(this,
CustomService.class), mConnection, Context.BIND_AUTO_CREATE);
mIsBound = true;
}
private void doUnbindService()
{
if (mIsBound)
{
// Detach our existing connection.
unbindService(mConnection);
mIsBound = false;
}
}
#Override
protected void onDestroy()
{
super.onDestroy();
doUnbindService();
}
}
CustomService Code ....
public class CustomService extends Service
{
private final IBinder mIBinder = new LocalBinder();
private Handler mHandler = null;
#Override
public void onCreate()
{
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flag, int startId)
{
return START_STICKY;
}
#Override
public void onDestroy()
{
if(mHandler != null)
{
mHandler = null;
}
}
#Override
public IBinder onBind(Intent intent)
{
return mIBinder;
}
public class LocalBinder extends Binder
{
public CustomService getInstance()
{
return CustomService.this;
}
}
public void setHandler(Handler handler)
{
mHandler = handler;
}
}