I've created a ServiceConnection object called connection.
However, the onServiceConnected method is never called.
Any ideas on how to get it to work? Thanks
Heres my code:
public static boolean print(String message){
if(printerInitialized != true){
Log.e(TAG,"Unitialized printer. Can't print");
return false;
}
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra("MAC", printerUuid);
sendIntent.putExtra("DATA", message);
sendIntent.setComponent(new ComponentName("com.blueslib.android.app","com.blueslib.android.app.PrintService"));
context.getApplicationContext().bindService(sendIntent,connection, Context.BIND_AUTO_CREATE);
return true;
}
public static ServiceConnection connection = new ServiceConnection() {
#Override
public void onServiceDisconnected(ComponentName name) {
Log.e("System.out", "Service Disconnected");
}
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.e("System.out", "Service connected");
}
};
Related
I'm trying to make an audio player app, all running smoothly by utilizing activity and services. But there is a constraint when you have selected an audio and play it. Currently when the audio is playing, while selecting the same audio, I make it start from the beginning.
The question:
How to detect that the selected audio is being played. If the selected audio is different from what is being played it will be played from scratch but if it is the same it will not do anything.
In my activity :
//connect to the service
private ServiceConnection serviceConnection = new ServiceConnection(){
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
Services.MediaBinder binder = (Services.MediaBinder) service;
//get service
services = binder.getService();
mediaBound = true;
}
#Override
public void onServiceDisconnected(ComponentName name) {
mediaBound = false;
}
};
#Override
protected void onStart() {
super.onStart();
if(playIntent==null){
playIntent = new Intent(this, Services.class);
playIntent.putExtra("url", String.valueOf(urlRaw));
bindService(playIntent, serviceConnection, Context.BIND_AUTO_CREATE);
startService(playIntent);
}
}
In services :
Get variable using onBind:
#Override
public IBinder onBind(Intent intent) {
urlMedia = intent.getStringExtra("url");
return mediaBinder; // private final IBinder mediaBinder
}
I use in onStartCommand to play the selected audio.
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
try {
//An audio file is passed to the service through putExtra();
if(isPng()){
mPlayer.release();
}
mPlayer = MediaPlayer.create(getApplicationContext(), getResources().getIdentifier(String.valueOf(urlMedia),"raw",getPackageName()));
mPlayer.start();
} catch (NullPointerException e) {
stopSelf();
}
if (mPlayer != null)
initMusicPlayer();
return START_STICKY;
}
You are using bound service so you can create a method in service like
private String currentUrl;
public void playAudio(Sting url){
if(currentUrl.equals(url)) return;
this.currentUrl = url;
//Do other stuff.
}
And when service connected you can use this public method.
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
Services.MediaBinder binder = (Services.MediaBinder) service;
//get service
services = binder.getService();
services.playAudio("url");
mediaBound = true;
}
Use an another variable to keep the newly passed url in the onBind() method. Then check whether the new url is different from the old one.
// On Bind
#Override
public IBinder onBind(Intent intent) {
newUrlMedia = intent.getStringExtra("url");
return mediaBinder;
}
// On Start Command
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
try {
if (newUrlMedia.equals(urlMedia)) {
// Same url is passes
return START_STICKY;
} else {
// Different url
urlMedia = newUrlMedia;
if(isPng()){
mPlayer.release();
}
mPlayer = MediaPlayer.create(getApplicationContext(), getResources().getIdentifier(String.valueOf(urlMedia),"raw",getPackageName()));
mPlayer.start();
}
} catch (NullPointerException e) {
stopSelf();
}
if (mPlayer != null)
initMusicPlayer();
return START_STICKY;
}
When i try to bind service from UI thread , my BluetoothLeService becomes null after sometime. mBlutoothLeService is set properly but after executing multiple gattUpdateReceiver it becomes null.
private BluetoothAdapter.LeScanCallback mLeScanCallback =
new BluetoothAdapter.LeScanCallback() {
#Override
public void onLeScan(final BluetoothDevice device, int rssi,
byte[] scanRecord) {
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
if (device != null && device.getName() != null) {
Intent gattServiceIntent = new Intent(getActivity(), BluetoothLeService.class);
getActivity().bindService(gattServiceIntent, mServiceConnection, Context.BIND_AUTO_CREATE);
}
});
}
};
private final ServiceConnection mServiceConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName componentName,
IBinder service) {
Log.e(TAG, "service connected");
mBluetoothLeService = ((BluetoothLeService.LocalBinder) service)
.getService();
mBluetoothLeService.connect(mDeviceAddress);
}
#Override
public void onServiceDisconnected(ComponentName componentName) {
Log.e(TAG, "service disconnected");
mBluetoothLeService = null;
}
};
I tried binding service using handler (new Handler(getActivity().getMainLooper())) but still mBluetoothLeService becomes null.
But when I start bind service in OnCreate() of new fragment it works without any issue. Is it something to do with UI thread?
You may not get your current activity using getActivity() with this code in a Runnable ---
#Override
public void run() {
if (device != null && device.getName() != null) {
Intent gattServiceIntent = new Intent(getActivity(), BluetoothLeService.class);
getActivity().bindService(gattServiceIntent,
mServiceConnection, Context.BIND_AUTO_CREATE);
}
});
So idea is to use the bind service at onCreate().
However, you can get the activity in asyntask with ---
class MyClass extends AsyncTask<String, String, String> {
private Activity currentActivity;
public MyClass(Activity activity) {
currentActivity = activity;
}
#Override
public void run() {
if (device != null && device.getName() != null) {
Intent gattServiceIntent = new Intent(currentActivity, BluetoothLeService.class);
getActivity().bindService(gattServiceIntent,
mServiceConnection, Context.BIND_AUTO_CREATE);
}
});
}
Service class:
private IBinder mBinder ;
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
}
#Override
public void onDestroy() {
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("service","started");
new Connect().execute("");
return Service.START_STICKY;
}
private class Connect extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
ConnectionConfiguration connConfig = new ConnectionConfiguration(
HOST, PORT, SERVICE);
final XMPPConnection connection = new XMPPConnection(connConfig);
Thread t= new Thread(new Runnable() {
#Override
public void run() {
try {
connection.connect();
// SASLAuthentication.supportSASLMechanism("PLAIN", 0);
connection.login(USERNAME, PASSWORD);
Log.i("NetWorkConnection",
"Logged in as " + connection.getUser());
System.out.println(connection);
setConnection(connection);
} catch (XMPPException ex) {
Log.e("NetWorkConnection", "Failed to log in as "
+ USERNAME);
Log.e("NetWorkConnection", ex.toString());
setConnection(null);
}
}});
t.start();
return null;
}
}
public void setConnection(XMPPConnection connection) {
NetworkConnection.connection = connection;
}
public class MyBinder extends Binder
{
NetworkConnection getService() {
return NetworkConnection.this;
}
}
public XMPPConnection getconnection()
{
if (connection != null) {
Log.d("NetworkConnection","connection send");
return connection;
}
else
{
Log.d("NetworkConnection","connection null");
return null;
}
}
}
Activity Class:
private NetworkConnection service;
XMPPConnection connection=NetworkConnection.connection;
Button next;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.sign_in);
next=(Button)findViewById(R.id.bRetry);
if(!isMyServiceRunning())
{
Intent i=new Intent(this,NetworkConnection.class);
startService(i);
}
next.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
System.out.println(connection);
if(connection!=null)
{
Intent i = new Intent (getApplicationContext(),UserIndex.class);
startActivity(i);
}else{
Intent i = new Intent(SignIn.this,SignIn.class);
startActivity(i);
}
}
});
}
#Override
protected void onResume() {
bindService(new Intent(this, NetworkConnection.class), mConnection,
Context.BIND_AUTO_CREATE);
super.onResume();
}
#Override
protected void onPause() {
unbindService(mConnection);
super.onPause();
}
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder binder) {
service = ((NetworkConnection.MyBinder) binder).getService();
Log.d("Service","Connected");
System.out.println("service connection methoddd");
connection=service.getconnection();
}
public void onServiceDisconnected(ComponentName className) {
connection=null;
service = null;
}
};
private boolean isMyServiceRunning() {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (NetworkConnection.class.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
}
I am creating a chat application using XMPP and asmack, So i used service. But the problem is that when i start the service onServiceConnected method never execute.That is why when i retrieve the connection object from service it always give null value. I have not much idea about it . please guide me.
I'm using a USSDInterceptor service to get the USSD responce in my application. Here is the service:
package com.codedemigod.services;
import com.android.internal.telephony.IExtendedNetworkService;
public class CDUSSDService extends Service{
private String TAG = CDUSSDService.class.getSimpleName();
private boolean mActive = false; //we will only activate this "USSD listener" when we want it
BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(Intent.ACTION_INSERT)){
//activity wishes to listen to USSD returns, so activate this
mActive = true;
Log.d(TAG, "activate ussd listener");
}
else if(intent.getAction().equals(Intent.ACTION_DELETE)){
mActive = false;
Log.d(TAG, "deactivate ussd listener");
}
}
};
private final IExtendedNetworkService.Stub mBinder = new IExtendedNetworkService.Stub () {
public void clearMmiString() throws RemoteException {
Log.d(TAG, "called clear");
}
public void setMmiString(String number) throws RemoteException {
Log.d (TAG, "setMmiString:" + number);
}
public CharSequence getMmiRunningText() throws RemoteException {
if(mActive == true){
return null;
}
return "USSD Running";
}
public CharSequence getUserMessage(CharSequence text)
throws RemoteException {
Log.d(TAG, "get user message " + text);
//getApplicationContext().sendBroadcast(new Intent("ussdMsg"));
if(mActive == false){
//listener is still inactive, so return whatever we got
Log.d(TAG, "inactive " + text);
return text;
}
//listener is active, so broadcast data and suppress it from default behavior
//build data to send with intent for activity, format URI as per RFC 2396
Uri ussdDataUri = new Uri.Builder()
.scheme(getBaseContext().getString(R.string.uri_scheme))
.authority(getBaseContext().getString(R.string.uri_authority))
.path(getBaseContext().getString(R.string.uri_path))
.appendQueryParameter(getBaseContext().getString(R.string.uri_param_name), text.toString())
.build();
getApplicationContext().sendBroadcast(new Intent(Intent.ACTION_GET_CONTENT, ussdDataUri));
mActive = false;
return null;
}
};
#Override
public IBinder onBind(Intent intent) {
Log.i(TAG, "called onbind");
//the insert/delete intents will be fired by activity to activate/deactivate listener since service cannot be stopped
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_INSERT);
filter.addAction(Intent.ACTION_DELETE);
filter.addDataScheme(getBaseContext().getString(R.string.uri_scheme));
filter.addDataAuthority(getBaseContext().getString(R.string.uri_authority), null);
filter.addDataPath(getBaseContext().getString(R.string.uri_path), PatternMatcher.PATTERN_LITERAL);
registerReceiver(receiver, filter);
return mBinder;
}
}
I dont know how to communicate with this service from my activity. I have used BroadcastReceiver in my activity like this:
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
updateUI(intent);
}
};
#Override
public void onResume() {
super.onResume();
registerReceiver(broadcastReceiver, new IntentFilter(Intent.ACTION_GET_CONTENT));
}
But I couldn't get the broadcast. Am I doing something wrong? I dont know I should use BroadcastReceiver or I should communicate with my service by bindService.
Whould you please help me in this problem?
I solved the problem by myself. The problem was in the place of calling 'unregisterReceiver'. I had called unregisterReceiver() on onPause() and it seemed that during getting USSD result, the BroadcastReceiver was unregistered. so I put it on onDestroy() method and finally I managed to get the broadcast message. Here is my onDestroy method:
#Override
public void onDestroy() {
Log.i(TAG, "unregister");
unregisterReceiver(broadcastReceiver);
super.onDestroy();
}
Good Morning All,
I am currently buidling a media player for Android, and I am having trouble binding my player service to an Activity and pulling data from it. Bear with me...a lot of code follows.
My code---
Interface:
interface MyInterface{
void playFile( in String file);
void shuffle ();
String getPlayingData();
}
Service:
public class MyService extends Service {
public Context context;
public static String nowPlayingData = null;
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
private final MyInterface.Stub mBinder = new MyInterface.Stub() {
public void playFile(String file) throws DeadObjectException {
//Song playing method working great!
}
public void shuffle()throws DeadObjectException {
//This method picks a random song and passes it to nowPlayingData string
}
public String getPlayingData() throws RemoteException {
return nowPlayingData;
}
};
#Override
public void onCreate() {
//Toast.makeText(this, "My Service Created", Toast.LENGTH_LONG).show();
Log.d(TAG, "onCreate");
mp.setLooping(false); // Set looping
}
#Override
public void onDestroy() {
//Toast.makeText(this, "My Service Stopped", Toast.LENGTH_LONG).show();
Log.d(TAG, "onDestroy");
mp.stop();
}
#Override
public void onStart(Intent intent, int startid) {
//Toast.makeText(this, "My Service Started", Toast.LENGTH_LONG).show();
Log.d(TAG, "onStart");
}
}
Main Screen Activity, Shuffle Button:
Service is started in onCreate. When I click on the shuffle button it uses a method in the service to play a random song, thus setting the nowPlayingData string.
public class mainMenu extends Activity {
private MyInterface mInterface;
private ServiceToken mToken;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Intent startedSvc = new Intent(mainMenu.this, MyService.class);
boolean success = this.bindService(
startedSvc, svcConn, Context.BIND_AUTO_CREATE);
this.startService(startedSvc);
findViewById(R.id.shuffle).setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
try {
sInterface.shuffle();
} catch (RemoteException e) {
e.printStackTrace();
}
Intent play_screen = new Intent(MyPlayer.getContext(), NowPlaying.class);
startActivity(play_screen);
}
Player Activity:
I want to bind to the service, and pull nowPlayingData over using the interfaces getPlayingData method.
public class NowPlaying extends Activity implements OnClickListener {
public static String nowPlayingData = null;
MyInterface mInterface;
boolean isConnected = false;
RemoteServiceConnection conn = null;
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.now_playing);
setVolumeControlStream(AudioManager.STREAM_MUSIC);
Log.i("Log", "Player Loaded");
bindService();
getData();
fillView();
}
public void fillView(){
//This method needs the nowPlayingData string to update the view
}
class RemoteServiceConnection implements ServiceConnection {
public void onServiceConnected(ComponentName className,
IBinder boundService ) {
mInterface = MyInterface.Stub.asInterface((IBinder)boundService);
isConnected = true;
Log.d("Now Playing", "Service Connected" );
}
public void onServiceDisconnected(ComponentName className) {
sInterface = null;
// updateServiceStatus();
isConnected = false;
Log.d( getClass().getSimpleName(), "onServiceDisconnected" );
getData();
}
};
private void bindService() {
if(conn == null) {
conn = new RemoteServiceConnection();
Intent i = new Intent();
i.setClassName("com.musicplayer.MyPlayer", "com.musicplayer.MyPlayer.MyService");
bindService(i, conn, Context.BIND_AUTO_CREATE);
Log.d( getClass().getSimpleName(), "bindService()" );
} else {
Toast.makeText(NowPlaying.this, "Cannot bind - service already bound", Toast.LENGTH_SHORT).show();
}
}
private void getData() {
if(conn == null) {
Log.i("getData", "No Connection");
} else {
try {
String data = mInterface.getPlayingData();
Log.i("Data Recieved", data);
Log.d( getClass().getSimpleName(), "invokeService()" );
} catch (RemoteException re) {
Log.e( getClass().getSimpleName(), "RemoteException" );
}
}
}
}
I have been studying many examples online, and perhaps my mish-mash of attempts has caused this to not work. My code works all the way through to binding the service, but OnServiceConnected is never called, and conn remains null.
Any help you guys can provide is greatly appreciated.
Thanks,
Josh
Android will not make re-entrant event calls to your activity, so onServiceConnected can't be called until onCreate has returned