Debugging a service - android

I have written a service with a remote interface and installed it on my PC's Eclipse AVD. I have a client test harness which starts and invokes methods in the service. Initially I had the service installed by a control class and activity, which I have now removed, so that the manifest for the service looks like:
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.myname.gridservice"
android:versionCode="1"
android:versionName="1.0">
<application
android:icon="#drawable/icon"
android:label="#string/app_name"
android:debuggable="true">
<service
android:enabled="true"
android:debuggable="true"
android:name="OverlayService">
<intent-filter>
<action android:name="com.myname.OverlayService.SERVICE"/>
<action android:name="com.myname.gridservice.IRemoteInterface" />
</intent-filter>
</service>
</application>
</manifest>
so there's no activity tag.
When I launch it from the debug icon in Eclipse, the console tells me that it's installing the apk (which it is), but it does not appear as a debug thread and breakpoints aren't triggered, although the service's behaviour is OK as far as the client sees it. If I wrap the service tag in an activity tag which has an associated class and launch that, then I can debug it.
Is it possible to debug the service without wrapping it in an activity?

Here's what you can do in four steps:
First: In the first interesting method of your service (I used on create):
/* (non-Javadoc)
* #see android.app.Service#onCreate()
*/
#Override
public void onCreate() {
super.onCreate();
//whatever else you have to to here...
android.os.Debug.waitForDebugger(); // this line is key
}
Second: Set break points anywhere after the waitForDebugger command.
Third: Launch app via debug button in your IDE (Eclipse/Android Studio/...). (You should probably have removed the main launch activity from the manifest by now)
Last: Launch adb and run the command to start a service:
cd $PLATFORM_TOOLS
adb shell
am startservice -n com.google.android.apps.gtalkservice/com.google.android.gtalkservice.service.GTalkService

just make sure you don't forget this line of code in your code and release your apk. if you try running your app without the debugger the line below will get stuck.
android.os.Debug.waitForDebugger();
also you can use the following to determine if the debugger is connected:
android.os.Debug.isDebuggerConnected(); //Determine if a debugger is currently attached.

Edit 2018 button icon changed
This is pretty simple, you can connect to your application service. Assuming that running the debugger doesn't work, you can press the choose process option by pressing the debug with an arrow icon pictured above. Select your service and you should now be able to debug your service.

I think it should be done programmatically with android.os.Debug.waitForDebugger();

This works in Android Studio. There might be a similar way in Eclipse I suppose.
run your project in debug mode
attach debugger to your service process

Some of the answers correctly mention that you'd want to insert
android.os.Debug.waitForDebugger();
into the first interesting method of the service. However, it's not clear from those answers, that the Android Studio debugger will not start automatically when the service is started.
Instead, you also need to wait till the service has started, then press the button to attach to process (see screenshot for Android Studio 3.6.1 .. it is the 3rd button to the right from the debug button). You will be given a choice of processes to attach to, one of which would be the service's separate process. You can then select it to complete the process of attaching the debugger to the service.
Edit, Aug 2020: the button icon is the same in Android Studio 4.0

Related

Android app crashes without stacktrace on logcat

I run my app in Android Studio debugger and get "[AppName] keeps stopping", although it doesn't actually stop. It's just an android.app.Service that appears to be crashing, yet on LogCat I see no stack trace and putting breakpoints in the Service constructor, for example, it doesn't stop there either.
Android Services are running in their own processes. When you configure in your Manifest your service
<service
android:name=".service.SomethingService"
android:enabled="true"
android:exported="false"
android:process=":Something" />
Check logcat for :Something. You should find a process called yourappname:Something. There you find your stacktrace.
For the debugging part of the question you probably need to add this line:
android.os.Debug.waitForDebugger();
where appropriate in your Service' onCreate or so. Then you have time to connect to the process once the server is stuck on that line. Don't forget to remove the line before publishing.

Add Debugger in Android Studio after app is closed?

Is it possible to attach the Android debugger of Android Studio again in order to check Break point after app has been closed ?
You may be able to attach a debugger if the app process is invisible but still alive. If a process is terminated or not is up to the Android OS.
However you will not be able to "check" a breakpoint as breakpoint only work if the code the breakpoint is contained is executed. Breakpoints therefore only work interactively - if you attach to a process after a breakpoint has been passed it is impossible to extract information regarding the process state (variables, ..) at the time the breakpoint was passed, because it is no longer available.
You are probably trying to open the app from a notification or service when your app is closed or has been removed from the background by the Android system.
Here is a nice workaround for that.
Make a new class named Notification.class and extend Application class to it as shown below.
package com.example.app;
import android.app.Application;
public class Notification extends Application {
#Override
public void onCreate() {
super.onCreate();
}
}
After this, in your AndroidManifest.xml file, make the following changes.
<application
android:name=".NotificationClass"
.
.
android:usesCleartextTraffic="true">
</application>
After this whenever you receive a notification for your app and your app is not in background or foreground, you will be able to attach the debugger from Android Studio before clicking on the notification.
Hope it helps. :)

Breakpoint in service not working

I am trying to add a breakpoint to a service running on a separate thread. No matter where I place the breakpoint in the service, they are always ignored.
I am sure that the service is running as I see the Log.e in the logcat. My debug mode is also correctly used as any breakpoint in the main thread of the app works.
Am I missing something? Is debug mode not supported for services in a separate thread?
I just updated Eclipse and Android SDK tools to the latest versions today.
I am testing my application on a device.
The android.os.Debug.waitForDebugger() did the trick. Add this before the line of code you want to debug.
Make sure that you declare the package name in the service tag in the manifest using android:process attribute, for example:
<service android:name=".YourCoolService"
android:process="your.package.here"/>

How to start a Service when .apk is Installed for the first time

In my Application I am not having any UI part, so I need to start a Service as soon as the Applicaton gets installed on the Device. I saw many links from which the answer was that its not possible but I guess it is surely possible. Just have a look at PlanB Application on the Android Market that does fulfil my requirement. Below is my Manifest file how I tried, but the Service was not called at all. So, let me know what is the best possible way to start a Service when the Application gets Installed.
UPDATE
I also tried using android.intent.action.PACKAGE_ADDED it works fine for detecting the Package for the other Applications but not for itself.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.auto.start"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="8" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application
android:icon="#drawable/ic_launcher" >
<service android:name=".MyService">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</service>
<receiver android:name=".BootUpReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<category android:name="android.intent.category.DEFAULT"/>
<action android:name="android.intent.action.PACKAGE_INSTALL" />
<action android:name="android.intent.action.PACKAGE_ADDED" />
<data android:scheme="package"/>
</intent-filter>
</receiver>
</application>
</manifest>
Fortunately, Plan B does not work on Android 3.1+, as tested on a XOOM and a Galaxy Nexus.
What Plan B does is exploit a security hole that could be used by drive-by malware, which is specifically why Android prevents it from happening anymore.
UPDATE
To clarify: As inazaruk posted and I put into comments on other answers, all applications, upon installation, are placed in a "stopped" state. This is the same state that the application winds up in after the user force-stops the app from the Settings application. While in this "stopped" state, the application will not run for any reason, except by a manual launch of an activity. Notably, no BroadcastReceviers will be invoked, regardless of the event for which they have registered, until the user runs the app manually.
This block covers the Plan B scenario of remote-install-and-run, which they were taking advantage of previously. After all, with that, anyone with a hacked Google account would be at risk of having their device infected, hands-free as it were.
So, when the OP says:
I need to start a Service as soon as the Applicaton gets installed on the Device
the OP will be unsuccessful and will need to redesign the application to avoid this purported "need".
Applications installed on the /system partition are not subject to being placed into the "stopped" state after installation. If you have root, you can do,
$ adb root
$ adb remount
$ adb push your.apk /system/app
And it can immediately receive broadcast intents. This certainly doesn't provide a general purpose solution, but i wanted to mention it for completeness.
EDIT: Keep in mind that different versions of Android locate system APKs in different places. For example, Android 8 puts them under /system/app//.apk. Shell into your device and poke around and follow the same scheme used for other system APKs.
I agree with CommonsWare's answer to question: How to start android service on installation. In other words, you can't automatically start your service after you've just been installed.
One more thing about newer Android platforms: if you don't have UI at all, you'll have trouble starting your service even when using BOOT_COMPLETE intent on Android 3.1+.
That's because all installed applications are in stopped state. In this state applications will not receive ANY broadcast notifications.
In order to activate your application some other application (or user) needs to start your service or activity, or content provider. The usual workflow is when user clicks on your application's icon.
I've written a detailed explanations about this in my blog post.
Plan B does this launch by listening to the events which happen in the system. It uses a receiver which literally listenes to hundreds of events hoping that some of them will eventually fire up. So this is how you can do it. Otherwise, there are no built-in means to launch the application as soon as it gets installed.
I'm not sure what your constraints/purpose is, but if you can install another application that has an activity you can have it send an intent with the flag FLAG_INCLUDE_STOPPED_PACKAGES.
This will use your application for the intent resolution, even though it's in a stopped state. If the action of the intent matches one of your filters, it will also bring the package out of the stopped state.
I don't think so You can start service immediately after installed your application on device,
The application must first be invoked by the user through some sort of Activity.The only things you have to register some Broadcast Receiver with appropriate intents in manifest which invoke you service when something is happening on device but this remaing to Android 3.1 version.
EDIT:
After Android 3.1+ onwards you can not use any Broadcast for starting your application, because all application remains in inactive state after completion of device boot and to launch the application the user have to invoke it.(By touching the app icon).
As stated by CommonsWare in the answer to this question (which I suppose you have all ready seen, but chose to ignore) starting a Service on install is not possible - it is simply not a thing that is implemented into the platform.
Starting it automaticly at the next boot is however possible.
As stated in the Technical Details for PlanB:
Plan B will attempt to launch as soon as it downloads, but in some cases you will need to send an SMS to get it started.
My guess is that on a rooted phone you might be able to start the Service on install - but there's no guarantee that the phone is rooted, which is why PlanB will require recieving a text in some cases because that can be registered by the IntentFilter of the app and then used to start the Service.
there is an app on google play Android Lost which invoke the registration service for google push messages via an incoming sms without launching the app even once for version 3.0+.
Perhaps the best way to accomplish this (and now I'm speaking to the specific intent of the OP, a program that gets installed in order to retrieve a stolen phone, not the general question) is social engineering, not software engineering.
So, an icon with text like "Password List" or "My Bank Accounts" which suddenly appeared on the home screen would undoubtedly be clicked on. Look at the success of all sorts of other phishing, and here you would be targeting a thief, who's already motivated to continue nefarious activity. Let the thief start it for you. :)
HEY I think using a BroadcastRecivier to automatically start the app on restart of device hence it will automatically start on device start.Hope this will help

Attaching debugger - android problem

I am new to android application development. Whenever I run a new app, after it gets installed and the activity launches, it displays a message saying "application is waiting for the debugger to attach" on the emulator. After that, application runs properly. But I am not getting what that message is and how I can stop it from getting displayed. Could anyone help me...?
its normal... when debugging it takes some time to connect to device or emulator. Its not a error message and u need not worry about it.
Some applications(I assume not yours) needs to have permissions to debug, then u need to have this code
<manifest>
<uses-permission android:name="android.permission.SET_DEBUG_APP"></uses-permission>
</manifest>
In your manifest file .
or else have this
android:debuggable="true"
in the application tag in the AndroidManifest.xml
thanks
It means you run the application in debug mode to solve problems using the button shown on the screenshot.
Try the button at the right beside the debug button instead.

Categories

Resources