Since the phone restarts and thus gets disconnected from the Eclipse debugger/LogCat while it's booting up, how do I see where my boot complete broadcast receiver is crashing?
I am performing some actions in the onReceive() of my
public class BootCompleteReceiver extends BroadcastReceiver {
...
}
This is crashing and popping up a force close dialog when the phone boots. How do I debug this and see where the problem is?
The question holds true for debugging any BOOT_COMPLETE broadcast receivers.
Thanks!
EDIT
Yes, we can see the system logs in LogCat as the phone is booting up but my app Log.d(TAG,"Boot completed") has to wait till it (onReceive) gets triggered but by that time the app crashes because the problem is somewhere in the receiver itself. The app crashes before I can log anything. Also, I cannot use "Run in Debug mode" for a phone that's restarting...
As i wrote on another thread:
You can emulate all broadcast actions by connecting via adb to the device and open a device shell.
Here we go:
open console/terminal and navigating to /platform-tools
type "adb shell" or on linux/mac "./adb shell"
in the shell type "am broadcast -a android.intent.action.BOOT_COMPLETED" or whatever action you want to fire.
In this way you should be able to debug.
There are a bunch of nice commands coming with adb or the adb shell. Just try it
Regards Flo
EDIT:
Using the above method will also reboot the device. To prevent the device from rebooting use am broadcast -a android.intent.action.BOOT_COMPLETED com.example.app. Note the suffix with the application package name to which the broadcast goes. This enables you to send the BOOT_COMPLETED intent to ONLY YOUR app for debugging purposes. – Roel van Uden
The receiver is only controlling when your code runs (i.e when the phone starts). Whilst debugging, run the code manually. You can resolve 99% of your issues this way and the remaining ones (if any) you can resolve by writing to LogCat so see what your code is doing.
check your Intent's actions and bundles you are recieving ,they may null and can be a null pointer exception.
Just put to your terminal in Android Studio
adb shell am broadcast -a android.intent.action.BOOT_COMPLETE
Related
I have searched this over the web, without an answer. Basically while testing a device, I observe that the display screen fires ON much earlier, while in the logcat the print
Consoleui:bootComplete follows after ~ 8 sec.
Now Device screen is displayed as part of starting Launcher application, so in the natural sequence of events, the system server will ask activitymanager to start launcher in a seperate thread and go on doing more work.
Thus it is only natural that display will come up, but still there might remain some services to be started by activitymanager/systemserver before a BOOT_COMPLETED broadcast can be made.
I have to prove this. In order to do so, I need to know which process tells the activitymanager that now it can broadcast the boot_complete message, if its the system server, please tell me the part of code where it does so. Thanks.
The activity manager service sends the boot complete intent on line 6320 of ActivityManagerService.java.
The activity manager service also starts the launcher using an intent with CATEGORY_HOME on line 3305 of ActivityManagerService.java.
It appears that your original question contains 2 sub-questions:
Q1. Where exactly in the AOSP code is system broadcast Intent BOOT_COMPLETED fired?
Q2. What are all the necessary conditions to trigger the firing of BOOT_COMPLETED?
For Q1, a broad location is in the Activity Manager. In this sense, #Alex Lockwood’s answer is correct. However, I have noticed that the exact location and the way this Intent is fired may change between Android versions. A source code search should be able to lead to the answer. Take AOSP branch “android-8.1.0_r32” as an example. First, find out where file “ActivityManagerService.java” is located using the following shell commands:
$ cd [your AOSP branch’s root directory]
$ find . -name ActivityManagerService.java
Once the file is found, go to its parent directory. For example, in our current case:
$ cd frameworks/base/services/core/java/com/android/server/am
Now perform the following search:
$ grep -rIn ACTION_BOOT_COMPLETED .
The output reveals that the exact location is not in file “ActivityManagerService.java”, but in file “UserController.java”. More exactly, it is in method “UserController.finishUserUnlockedCompleted()”.
For Q2, we can search backwards from the above method. Eventually we may reach method “ActivityManagerService.finishBooting()” where we can see that Boolean “mBootAnimationComplete” must be true. This implies that the boot animation process must be completed in order for BOOT_COMPLETED to be fired, and further implies that while the boot animation process is going on, a lot of system services are being started. For further details, you may refer to some dedicated books that explain which system services must be ready in order for the boot animation process to end.
I'm setting up a number of cellphones using adb. I have written a script which pushes the custom lockscreen and homescreen png's to the phone, specifically to the pictures folder and that works fine. I'd like to set the lockscreen and homescreen of the phone using adb if that is possible? How would I go about doing that?
This is how I would do,
Write a simple Android application with a broadcast receiver. Inside the receiver class write the methods to set the homescreen and lockscreen wallpapers. You can receive the paths for lockscreen and homescreen via the broadcast intent in onReceive() method of the receiver. Don't worry about the path for lockscreen and homescreen images. We will shortly pass it via the a broadcast intent from adb. As you already pushed the images, you will be having the path for the images.
Now from adb you can send a broadcast intent with a couple of strings for lockscreen and homescreen image path with the following command,
$ adb - s shell am broadcast - a -e lockscreen /sdcard/lockscreen.png - e homescreen /sdcard/homescreen.png
You can receive these two parameters inside onReceive via intent.getStringExtra("lockscreen") and intent.getStringExtra("homescreen")
Hope it helps. Sent from my mobile. Please let me know if something is not clear.
Setting up a broadcast receiver is unnecessary if you are okay with launching the app to set the wallpaper. I think registering the BroadcastReceiver would require you to start the app once, anyway.
You can pass a Uri to the JPEG file directly to the intent you use to start the app.
So you can set up a workflow like this.
Push the wallpaper to the device
adb push actual/path/to/wallpaper.jpg /sdcard/target-wallpaper.jpg
Start the app with an intent data Uri like follows:
adb shell am start -a android.intent.action.MAIN -n retailerservice.justbuylive.com/.MainActivity -d file:///mnt/sdcard/target-wallpaper.jpg
The file Uri can be read from the startup via getIntent() as normal from within the app.
Install and uninstall app commands are also straightforward:
adb install app-release.apk
adb shell pm uninstall package.yourcompany.com
This question already has answers here:
Listen to own application uninstall event on Android
(3 answers)
Closed 7 years ago.
Recently i've seen a funny app - Photo Wonder.
When this app is uninstalled, it shows a web survey page asking for the reason of app uninstall. Now, here is the problem.
As far as I know, after an app has been removed, the system broadcasts ACTION_PAKAGE_REMOVED intent.
But this funny app was able to show my the web page although the official doc says
"The package that is being installed does not receive this Intent."
Anyhow, I could find a process checking some kind of status of the app.
Now here is the question. Can the native app catch the broadcasted intent from android system?
If it is possible, please let me know how! :-(
I believe I've got the main idea of how they did it. Here is the pieces of the puzzle.
Any Android application can start a process by calling Runtime.exec() function.
Runtime.getRuntime().exec("chmod 755 '/data/data/my.app/files'/native_code");
After this line of code gets executed there is another process spawned. This process runs under the same linux user as the application itself.
When a user opens Settings -> Apps -> My App and presses "Force stop" button, main application process gets killed, but the process hosting native program (see above) still runs. I personally believe this is a security issue and I am going to report it back to AOSP.
Such native program can run infinitely and do nothing - just sleeping. But before going to sleep, it registers a termination signal handler which will be called when process is about to be terminated by the system.
int main(void) {
signal(SIGTERM, termination_handler);
while(1) {
sleep(10);
}
}
void termination_handler(int sig) {
// handle termination signal here
}
Now you should already know what the last piece is, right? My native termination_handler should be able to launch a browser. I didn't try this in code, but I assume this is possible, because I can do it using adb shell as following
adb shell am start -a android.intent.action.VIEW -d http://www.google.com
Now back to the question about how Dolphin Browser does it. Install the app and launch it at least once. Once started, it registers a native uninstall watcher using the principles described above. To see it, connect to the device and open adb shell. Then call ps to see list of processes. You will see two processes similar to following
u0_a109 315 ... mobi.mgeek.TunnyBrowser
u0_a109 371 ... /data/data/mobi.mgeek.TunnyBrowser/files/watch_server
As you can see it starts a watch_server native program, which is a part of its apk-file. Now open App info page of Dolphin Browser and press "Force Stop". Switch back to terminal and call ps again. You will see there is no mobi.mgeek.TunnyBrowser process anymore, but watch_server still runs.
By the way this approach will only work, if watcher server runs all the time. To
make sure it is always up, both apps require "run at startup"
permission, where they start their watchers.
Now, when you uninstall the app, Android stops all processes belonging to this application. Watcher receives termination signal and opens browser with predefined URL and then shuts down.
I might look a bit different in some details, but the main concept behind this hack must be as described.
There could be a tricky thing like that application is also having watcher service.
You can check the permission used by that app may contain INSTALL and UNINSTALL permissions.
HOW IT WORKS:
instead of single app that may have 2 app bundle.
as and when you install it, this app is also installing some service that is watching your app status
When you try to uninstall that app the system broadcast is called which is handled by that service and will check that if your package is exist in installed application or not.
as soon as this service finds that your package is not in the list it calls an intent with action view with the web url to open the brawser.
is there a simple way to stop a running application using ADB.
Szenario:
Working on App
Have a script which uploads, installs and starts App on change
Problem:
Currently running version gets killed (not shutdown), which make testing cleanup very hard. Option would be to "do cleanup in between", like after a certain time, but I would prefer to do it in the correct location (so like with the OS, as long as the App is still running, so need to save value, as soon as the OS tells me e.g. memory low or calls onDestroy, I want to save stuff)
Chris
I'm not aware of a way to do this. I was hoping there might be a way to send an intent to tell the app to exit using adb shell e.g.
adb shell am start -a [intent] -n [class]
However, I found that somebody asked this question on a Google forum but they haven't got an answer:
http://groups.google.com/group/android-platform/browse_thread/thread/3fd02d01c6c3b41a/56814e518503efd6
I have coded a BroadcastReceiver to enable the resetting of an alarm if a user has to reboot hid device. Is there any way to test this in the emulator, in other words what sequence of events are required to cause the emulator to kick off the BroadcastReceiver .
Ron
I have not tried it yet, but Dianne Hackborn wrote the following yesterday:
You can also use "adb shell am" to
send a BOOT_COMPLETED broadcast to
your app for quick testing. I can't
remember the exact syntax, but "am
help" will tell you. Be sure to
specific your explicit component name
when doing this, or you will cause all
installed apps to re-run their boot
completed receivers, which may not be
fun. :)
I believe that the only way to do it will be to close the emulation window and start it again. If you are running Eclipse, simply close the emulator and then run/debug your project to start it again.