Use custom system service in app (Android Studio) - android

First of all, thank you for your help.
Here is my problem.
I have made a custom system service (it does connect through the binder, and hooks into the system server, then into the HAL, etc). One of the main commands is isBacklightOn(). I also ran the make update-api to include it in my ROM build.
I am now ready to test the functionality using an app. I am using the following code:
import android.os.BacklightManager; //My service manager name
...
BacklightManager bm = (BacklightManager) getSystemService(BACKLIGHT_SERVICE);
...
if(!bm.isBacklightOn()) {
//Turn it on.
} else {
//Other Things...
}
My problem occurs because Android Studio will not build the application due to not knowing what the BacklightManager is. How can I build this application to test my code? (import something into Android Manager, force a build ignoring errors, etc.)

It looks like the solution is to build a custom SDK within the AOSP build environment. And then import that into Android Studio

Related

KMM - Unresolved reference: platform for IOS application

Hellow.
I have a trouble with template KMM application. It got an error after I created new KMM application - in shared IOS app module it cannot find package platform. It's on kotlin. Adroid app works well.
Need to say, that I works on window by Android studio. I know there are troubles to start IOS app on window, but I do not want to start or build app - I want to just it find the reference platform.
I tried to find some dicisions. There are the same questions, but nobody can answer them.
Code with trouble:
import platform.UIKit.UIDevice // here there is the error
actual class Platform actual constructor() {
actual val platform: String = UIDevice.currentDevice.systemName() + " " + UIDevice.currentDevice.systemVersion
}
This question is a bit strange: how do you think iOS application will compile and work on a Windows computer?
To make KMM work on both OS you need a Mac. This is the reason why you are not able to find "platform.UIKit.UIDevice" on your machine.

Breakpoints is not hitting while debugging a .NET MAUI android application

I have been working on a MAUI android application and when debugging, the breakpoints is not hitting and the application enter in a break state. But for windows app it works well.
I think this is an issue with the .NET 6 Android Tooling in visual studio 2022. Is there any solutions for this problem ?
Here is a few steps I did to make things work with debugging MAUI Android apps. I was able to debug and get my regular exceptions and hit breakpoints after this.
Add this code to Android platform main activity OnCreate method
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
Then this hander method in the same class
private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{ System.Diagnostics.Debug.WriteLine(e.ToString());}
Reset Your Exceptions for CLR. Shortcut is (Ctrl+Alt+E).
Just double-click on the CLR Exceptions checkbox to reset.
Disable Debug Your Code Only in Options
I was also having problems debugging some projects. (Preview 17.1.0) The ones that were failing had the following project settings.
<PropertyGroup>
<TargetFrameworks>net6.0-ios;net6.0-android;net6.0-maccatalyst</TargetFrameworks> ...
Moving Android first fixed my problem
<PropertyGroup>
<TargetFrameworks>net6.0-android;net6.0-ios;net6.0-maccatalyst</TargetFrameworks> ...
I had the same problem and it is now working, try this:
Windows -> Settings -> Update & Security -> For Developers -> Developer Mode - On
Solution Properties -> Deploy - On
Visual Studio -> Tools -> Options -> Xml Hot Reaload -> Disable all
The you can just set your project has startup and run it.

Android: after Gradle update to 6.7.1 ClassLoader in JUnit test no longer lists all resources

I need to iterate over specific classes from main package in my android unit test, to check some of their properties.
For this I use standard approach, using ClassLoader:
val classLoader = Thread.currentThread().contextClassLoader
val resources: Enumeration<URL> = classLoader.getResources("com/models/package")
assert(resources.hasMoreElements()) // Fails from CL, works in AS
Before the Gradle update (had Gradle 5.6.4) that worked. Now the behaviour is as follows: it works when test is run from Android Studio, but fails (returns empty enumeration) when run from command line with gradlew.
I wonder what might be the difference in this respect between the two Gradle versions? And why it still works when run from Studio?
Some considerations and things I have tried:
Referencing these classes in unit test works ok, and also classLoader.findClass("com.models.package.MyModel") and
classLoader.loadClass("com.models.package.MyModel") from unit test is working. But even after that classLoader.getResources("com/models/package") returns empty enumeration.
Using other references to ClassLoader, like MyModel::class.java.classLoader and ClassLoader.getSystemClassLoader() didn't make any difference.
Gradle build from command line contains the warning "OpenJDK 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended", but as far as I can tell it's not connected to my issue.
If I put some of the classes from 'com/models/package' to the unit test /test folder, they are getting returned in enumeration.
This might be connected with some new optimisation setting that makes ClassLoaders omit registering some of the classes, in different root directories, but as it still works in AS there might be some setting to turn this optimisation off in a command line build also?
Thank you for any suggestions on this.
In Gradle 6.7.1 I had to include the directory with the code to the test sourceSets. Afterwards the classloader from junit started to see the classes and return them in Enumeration.
sourceSets {
test {
java.srcDirs += ['src/main']
}
}

Android ANR in MyFirebaseInstanceIDService just in one product flavor

In my app I have two product flavors. Both of them used to work fine. Suddenly I started to get ANR error when I try to run the application and the app freezes during start up. The error in Logcat is:
ANR in com.myapp.development
PID: 7937
Reason: executing service com.myapp.development/com.myapp.development.service.MyFirebaseInstanceIDService
The method MyFirebaseInstanceIDService.onTokenRefresh is never called. The app freezes before any of my own code is executed.
The production flavor still works fine.
Everything in the Firebase console is set up correctly. The app is in the Play Store and both flavors used to work.
productFlavors {
production {
applicationId 'com.myapp'
dimension "default"
}
development {
applicationId 'com.myapp.development'
dimension "default"
}
}
As you can see the only difference between the two flavors is the application id. And if I change the application id in the developmnet flavour it starts to work (the app does not freeze).
I tried the following tests:
I change the package id of the development flavor by adding just one letter: 'com.myapp.developmentX'. I also make the corresponding change in google-services.json file . Then the development flavor also starts. But of course Firebase services do not work, because the new application id is not configured in Firebase console.
In the manifest file I remove the MyFirebaseMessagingService and MyFirebaseMessagingService and MyFirebaseInstanceIDService. Then the app still freezes at start up, but the error in logcat changes slightly:
ANR in com.myapp.development
PID: 683
Reason: executing service com.myapp.development/com.google.firebase.iid.FirebaseInstanceIdService
I checked out an old git branch and tried to start it but the problem is still there.
I also tried: Uninstall the app and install again. Clean project. Delete the build directories. Restart the test device. Use the Android emulator. Restart the computer. Restart Android Studio. Update Android Studio to the latest 3.1.4 for Mac. But non of these helped.
It looks like the problem has something to do with the application id and Firebase, but I cannot find what.
Anyone has any ideas?
Update after comments from Shark and sebasira.
In Firebase console I have one single project and there are two applications defined for it - one for each flavour. In that case there is no need of multiple google-services.json, one for each flavour. The file is the same for all flavours and can be places in the root directory :
app/
google-services.json
The file structure is like that:
{
"project_info": {...},
"client": [...],
}
As you see, there is an array of clients. All application IDs (all flavours) are defined in that array. That's why if I download from Firebase the google-services.json file for each application, they are all the same.
Anyway, I tried to put a different google-services.json file for each flavor like that:
app/src/
flavor1/google-services.json
flavor2/google-services.json
But that didn't help.
I was facing exactly same issue, and my app configuration was also exactly similar as yours.
The issue was caused by the latest Facebook SDK I was using in my code, it crashes the Firebase before the app start hence the app goes to ANR.
I set my Facebook SDK version as 4.35.0 and that solved the issue.
Try it out and let me know if it was helpful.

Android Studio - test configuration starts up app

I've got a couple of AndroidTestCase subclasses in separate packages of my project:
However, whenever I run Android Tests configuration from Android Studio, I see that my regular app is starting as well. I see that the onCreate method is fired up inside my Application class (which is really bad since I am loading some additional resources there).
Why is Android Studio/gradle running my app as well? Can I programatically detect if I am inside test or regular configuration? Can I stop my regular app from being booted before running tests?
In addition, when I am running tests in debug mode it doesn't stop on breakpoints placed inside the application's onCreate method. Why is this happening?
Edit:
Body of test class doesn't really matter, it can be something like:
public class SimpleTest extends AndroidTestCase {
public void testSample()
{
assertEquals(true, false);
}
}
Executing only this simple test fires up onCreate method inside application class.
Gradle console prints out:
Executing tasks: [:app:assembleDebug, :app:assembleDebugTest]
I guess that first task creates instance of my Application class - is it expected behavior?
Why is Android Studio/gradle running my app as well?
Can I stop my regular app from being booted before running tests?
AndroidTestCase is extension of JUnit TestCase which is aware of your android application. In case you don't need to test your android application and want to test plain java only you should use JUnit framework. Create regular JUnit tests, do not use android classes there and run JUnit test configuration like this:
You should treat AndroidTestCase as instrumentation tests which will build android app and run that tests on it. This is usefull with combination of Espresso and Robotium. Both are working on top of base android test classes and both will build and run your application before testing it. Real device or emulator is needed.
Use plain JUnit tests or Robolectric to test java on your desktop JVM.
Can I programatically detect if I am inside test or regular configuration?
You can use power of gradle to provide such info with autogenerated BuildConfig file.
At your build.gradle
android {
defaultConfig {
testPackageName "com.foo.test"
}
}
At your code:
BuildConfig.PACKAGE_NAME.equals("com.foo.test")
The AndroidTestCase is an unit test that unfortunately runs on the device (either virtual or real).
I think what you want to have is a UnitTestFramework that runs in the JVM (local on your machine). The TestFramework Robolectric can do this.
I have started a gitHub project to show how to setup the gradle test file and the project structure if you want to have UnitTests and InstrumentationTests side by side. If you want to look its AndroidGradleTests

Categories

Resources