I build a simple remote service with aidl file. The service and the activity are in two diferent virtual device. The service isn't reachable with an activity. I think the service doesn't start.
In DDMS view my service doen't appear and LogCat launch an error : unable to start service Intent { cmp = com.michelService.BIND pkg=com.michelService}: not found
THANKS for your help!
My AndroidManifest.xml :
*<?xml *version*="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.michelService"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="13" />
<application android:icon="#drawable/icon" android:label="#string/app_name">
<service android:name=".ServiceHello" android:exported="true" >
<intent-filter>
<action android:name="com.michelService.BIND"></action>
</intent-filter>
</service>
</application>
</manifest>*
My activity : CallServiceActivity.java :
public class CallServiceActivity extends Activity {
/** Called when the activity is first created. */
IServiceHello service;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout layout = new LinearLayout(this);
TextView tv1 = new TextView(this);
Intent intent = new Intent();
intent.setAction("com.michelService.BIND");
intent.setPackage("com.michelService");
startService(intent);
ServiceConnection con = new ServiceConnection(){
#Override
public void onServiceConnected(ComponentName arg0, IBinder binder) {
service = IServiceHello.Stub.asInterface(binder);
}
#Override
public void onServiceDisconnected(ComponentName arg0) {
service= null;
}
};
bindService(intent, con, Context.BIND_AUTO_CREATE);
try {
tv1.setText(service.sayHello("Michel"));
} catch (RemoteException e) {
// TODO Auto-generated catch block
tv1.setText("" + e);
}
layout.addView(tv1);
setContentView(layout);
}
}
The service and the activity are in two diferent virtual device.
It does not work then. You can use services only on the same device. If you want to communicate with a different device then you have to do that via network.
You probably want to start both on the same.
Remote service means "in a different Process" here. You use AIDL to access the other process. Different Processes are a bit like different devices since they don't share a common environment and the communication between them is also a bit like network communication.
Related
I referred to all the other StackOverflow posts about this problem and I can't get it to work properly.
My goal is to write an app with no main activity, just a service. You should be able to bind to it from a seperate app and interact with it using AIDL.
I previously had both the service and the activity calling it in the same app and it worked flawlessly. But I need to get it working between two seperate apps.
The onBind() of the service looks like this:
#Nullable
#Override
public IBinder onBind(Intent intent) {
// This binds the bluetooth service itself to the logger service, do this when the logger service itself is bound
Intent serviceIntent = new Intent(this, BluetoothService.class);
intent.setPackage(this.getPackageName());
Log.d(getClass().getName(), "started");
if(bluetoothService == null) {
if (this.bindService(serviceIntent, bluetoothServiceConnection, BIND_AUTO_CREATE)) {
Log.d(getClass().getName(), "returned the service");
return mBinder;
} else {
Log.d(getClass().getName(), "returned null");
return null;
}
} else {
Log.d(getClass().getName(), "returned the service");
return mBinder;
}
}
The service itself binds to another service, but all of the bluetooth stuff works already.
The Manifest of the app with the service looks like this:
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<application
android:label="#string/app_name">
<service
android:label="LoggerService"
android:name="io.modum.ble.LoggerService"
android:exported="true">
<intent-filter>
<action android:name="io.modum.ble.LoggerService" />
</intent-filter>
</service>
<service android:name="io.modum.ble.service.BluetoothService" />
</application>
In my activity, I bind to it like this:
Intent intent = new Intent();
ComponentName componentName = new ComponentName("io.modum.modum_ble_service", "io.modum.ble.LoggerService");
intent.setComponent(componentName);
boolean success = getApplicationContext().bindService(intent, new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.d(getClass().getName(), "Service connected");
}
#Override
public void onServiceDisconnected(ComponentName name) {
}
}, BIND_AUTO_CREATE);
Log.d(getClass().getName(), String.valueOf(success));
The AIDL files have the exact same package name in both applications.
No exception is called, everything works except onServiceConnected is not called.
bindService() returns true, the service receives the intent and is correctly started, "returned the service" is logged, but onServiceConnected() is never called.
I got it running, what was missing was
intent.setPackage("io.modum.modum_ble_service)
Note that the package name is the name of the app, not the package the service is in. Use the package name displayed in LogCat.
I trying to write simple basic application that will start my service when the phone is start.
i add all the permission i need.
I install the application on my android ( android 6.01 ).
And when i reboot my phone - i can't see that the service is up or did any action.
why this is not working ?
how can i debug a service on android ?
The code:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAG" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/Theme.AppCompat.NoActionBar">
<service android:name=".MyService" android:enabled="true" android:exported="true"/>
<receiver android:name=".MainBroadcastReceiver" android:enabled="true" android:exported="true" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
</application>
public class MainBroadcastReceiver extends BroadcastReceiver {
public MainBroadcastReceiver(){
}
#Override
public void onReceive(Context context, Intent intent) {
context.startService(new Intent(context, MyService.class));
}
}
public class MyService extends Service {
private File _file;
private Timer _timer;
private FileOutputStream _fileOutputStream;
public MyService() throws IOException {
_file = new File("/sdcard/" + "myServiceText.txt");
_file.createNewFile();
_fileOutputStream = openFileOutput(_file.getName(), Context.MODE_APPEND);
_fileOutputStream.write("Ctor called".getBytes());
}
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
_timer = new Timer("timer");
_timer.schedule(new TimerTask()
{
#Override
public void run()
{
try {
_fileOutputStream.write("onCreate Called".getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
}, 0, 5000);
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
try {
_fileOutputStream.write("onStartCommand".getBytes());
} catch (IOException e) {
e.printStackTrace();
}
return START_STICKY;
}
Your code is fine, the reason your service is not running it's because your app is in Stopped State.
1. Stopped state is a security procedure that allows your app to "wake itself up" only after user first manually launches it from the home screen.(Unless you are a system)
By doing so android prevents malicious apps to be installed and run in your phone background without you knowing.
2. How to debug a background process?
When working with background processes there are two great tools you need in your belt -
First is the adb broadcast command -
adb shell am broadcast -a android.intent.action.BOOT_COMPLETED
Second is attach remote debugger (Android Studio):
Run | Attach debugger to android process (last option in the menu) | choose your app's process.
I have an application that I would like to have automatically start following boot completion. The following code seems overly complicated and I get erratic application starts when swiping to a neighbouring workspace.
What am I missing here? I have an activity class, a service class, as well as a broadcast receiver. Below is my code (in that order) followed by the manifest.
public class BlueDoor extends Activity implements OnClickListener{
Button btnExit;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
setContentView(R.layout.main);
btnExit = (Button) this.findViewById(R.id.ExitButton);
btnExit.setOnClickListener(this);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.ExitButton:
System.exit(0);
break;
}
}
}
service.class
public class BlueDoorStartService extends Service {
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
callIntent.setClass(this, BlueDoor.class);
startActivity(callIntent);
// do something when the service is created
}
}
broadcast receiver
public class StartBlueDoorAtBootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
Intent serviceIntent = new Intent(context, BlueDoorStartService.class);
context.startService(serviceIntent);
}
}
}
Manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.bluedoor"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="21" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<receiver
android:name=".StartBlueDoorAtBootReceiver"
android:enabled="true"
android:exported="false" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<service android:name=".BlueDoorStartService" >
</service>
<activity
android:name=".BlueDoor"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
UPDATE Solution(s), 10/22/2015:
Changing the service to:
public class BlueDoorStartService extends Service {
#Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
}
and the receiver to:
public class StartBlueDoorAtBootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// Start Service On Boot Start Up
Intent serviceIntent = new Intent(context, BlueDoorStartService.class);
context.startService(serviceIntent);
//Start App On Boot Start Up
Intent App = new Intent(context, BlueDoor.class);
App.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(App);
}
}
resulted in a working configuration using a service w/no misbehaving. However deleting the service all together and modifying the receiver thus:
public class StartBlueDoorAtBootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent App = new Intent(context, BlueDoor.class);
App.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(App);
}
}
also resulted in a functional as well as a more concise configuration that starts the application following boot completion.
Your BroadcastReceiver calls
context.startService(serviceIntent)
so the service will be created if it doesn't exist yet (which will be the case shortly after booting) and thus start the activity from its onCreate() method. So the app works, to a certain extent.
BUT when you call startService(), the system always calls the service's onStartCommand() method. You did not override that method, so the system uses the standard implementation from class android.app.Service.
As you can read on grepcode.com, the method will return a value like START_STICKY by default. This tells the system to keep the service alive until it is explicitly stopped.
In your case, I suppose the system reacted to the swiping by temporarily killing and then reanimating (= creating) the service, which in turn started your activity.
Some information on the service lifecycle can be found here.
What you can do:
Override onStartCommand() to start the activity from there instead of from onCreate(). Then use stopSelf(int) like described here
One last thing: when exiting from the activity, don't use System.exit(0) but call finish() instead, see this SO answer for "why".
Hi i have developed an service application using activity and that works great in 2.2 and 2.3 android version and it starts on boot and runs my app for once in 30 mins and sending location to server but in 4.0 the app is not running on services on boot can anybody say me why?
my code:
BroadcastReceiver.java:
public class autostart extends BroadcastReceiver {
public void onReceive(Context arg0, Intent arg1) {
if ("android.intent.action.BOOT_COMPLETED".equals(arg1.getAction())) {
Intent intent = new Intent(arg0, gps_back_process.class);
arg0.startService(intent);
Log.i("Autostart", "started");
}
}
}
service.java:
public class gps_back_process extends Service
{
private static final String TAG = "MyService";
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
Log.d("Testing", "Service got created");
Toast.makeText(this, "gps_back_process,onCreate();", Toast.LENGTH_LONG).show();
}
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
}
#Override
public void onStart(Intent intent, int startid)
{
Intent intents = new Intent(getBaseContext(),MainActivity.class);
intents.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intents);
Toast.makeText(this, "gps_back_process.onCreate();", Toast.LENGTH_LONG).show();
Log.d(TAG, "onStart");
}
}
Manifest:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.BROADCAST_STICKY" />
<receiver android:name=".autostart" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<activity android:name=".MainActivity" >
</activity>
<service
android:name=".gps_back_process"
android:enabled="true" />
</application>
thank you.
Once the user runs the app for the first time (and does not force stop it), everything behaves as before — a reboot will cause BOOT_COMPLETED broadcasts to be received and so on. However, if the user installs the app, until and unless they run the app manually, no broadcasts will be received. And if the user force-stops the app, until and unless they run the app manually, no broadcasts will be received.
Check this for more detail.
This happens because from Android 3.1+ you Service will not run on Boot unless you start(launch) your Application atleast once after installation. So, when you install your Application and restart the device prior of launching the Applications MainActivity your BroadCastReceiver won't be fired. For that you have to launch your MainActivity once and then restart the device. That works!
For reference you can check my question here.
You should add add android.permission.RECEIVE_BOOT_COMPLETED,
If you don't have this permission your app won't receive the boot completed intent.
I have an application with a TabActivity and one tab inside called LiveActivity. The application also has a service that regularly updates the GPS coordinates of the handset and some other information. Here is the manifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="fr.eyquem.example"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-sdk android:minSdkVersion="8" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:name=".TabActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".LiveActivity"></activity>
<service android:name=".SensorService"></service>
</application>
</manifest>
My service is supposed to send updates to all registered activities every time there is an update of the GPS coordinates. To test it, I first implemented the communication between the service and the TabActivity, by changing the application title when TabActivity receives the message. This works well.
Step 1. The service sends a message through the following method:
private void sendMsgToUI(int what, String[] values) {
Log.i("SensorService->sendMsgToUI()", " YYYYYYYYYYYYYYYYYYYYYY ");
for (int i=mClients.size()-1; i>=0; i--) {
Log.i("SensorService->sendMsgToUI()", " ZZZZZZZZZZZZZZZZZ ");
try {
String key="";
switch(what){
case MSG_COORDINATES:
key="Coordinates";
break;
default:
key="";
}
Log.i("SensorService->sendMsgToUI()", String.valueOf(what) +" "+key);
Bundle b = new Bundle();
b.putStringArray(key, values);
Message msg = Message.obtain(null, what);
msg.setData(b);
mClients.get(i).send(msg);
} catch (RemoteException e) {
// The client is dead. Remove it from the list; we are going through the list from back to front so this is safe to do inside the loop.
mClients.remove(i);
}
}
}
Step 2. The Activity receives the message through:
class IncomingHandler extends Handler {
#Override
public void handleMessage(Message msg) {
String[] values;
Log.i("TabActivity->IncomingHandler()", String.valueOf(msg.what));
switch (msg.what) {
case SensorService.MSG_COORDINATES:
values = msg.getData().getStringArray("Coordinates");
setTitle("MobScanR: " + values[0]);
break;
default:
super.handleMessage(msg);
}
}
}
This works well for TabActivity but not for the LiveActivity. It actually seems that the LiveActivity is not registered by the service (i put a lot of log messages and see for instance only one time the "ZZZZZZZ" log while there should be 2), although I checked that the method is called properly:
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
Log.i("LiveActivity->onServiceConnected()", " AAAAAAAA " + service.toString());
mService = new Messenger(service);
//textStatus.setText("Attached.");
try {
Message msg = Message.obtain(null, SensorService.MSG_REGISTER_CLIENT2);
msg.replyTo = mMessenger;
mService.send(msg);
} catch (RemoteException e) {
Log.e("LiveActivity->onServiceConnected()", " HHHHHHHHH ERROR " + service.toString(), e);
// In this case the service has crashed before we could even do anything with it
}
}
public void onServiceDisconnected(ComponentName className) {
// This is called when the connection with the service has been unexpectedly disconnected - process crashed.
mService = null;
//textStatus.setText("Disconnected.");
Log.i("LiveActivity->onServiceDisconnected()", "Service Disconnected");
}
};
I dont want to post the whole code there as I don't ask for extensive debugging, but anyone has an idea about where to look and what could explain this different behavior between 2 activities and the service?
Thanks for the help!