Why does my app crash when helper class is instantiated? - android

I'm building a Unity game that uses a native android library with one activity. This library includes bluetooth functionality from an sdk for which i created a Helper class that i can't instantiate or reference in any way in my MainActivity without the game crashing.
I'm new to Kotlin and android studio and can't figure out how to fix this.
Building & running in android and unity works without any errors.
Running an android native app set up in the same way like the android library, works flawless.
But when running the game independantly on phone it crashes, this has been tested on multiple devices.
MainActivity snippet
import com.X.unitylib.BluetoothDeviceHelper //this import is not used for some reason
class MainActivity : UnityPlayerActivity ()/*, BluetoothDeviceHelper.Listener*/ {
private lateinit var bluetoothDeviceHelper: BluetoothDeviceHelper // App runs with this
//private var bluetoothDevices = emptyList<BluetoothDeviceHelper.BluetoothDevice>() //Doesn't run
//private var connectedBluetoothDevice: BluetoothDeviceHelper.BluetoothDevice? = null //Doesn't run
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
bluetoothDeviceHelper = BluetoothDeviceHelper(applicationContext) //App doesn't run with this uncommented
}
/* override fun onStart() {
super.onStart()
//bluetoothDeviceHelper.addListener(this)
bluetoothDeviceHelper.startScan()
}*/
**BluetoothDeviceHelper snippet**
class BluetoothDeviceHelper(context: Context) : BLEDevice.Delegate<BLEDevice>, BLEManager.Delegate<BLEObject>
Edit: was able to fix a couple issues so i updated my initial description and replaced the outdated stack trace with the latest error.
Edit2: New error, on monday i'll try the steps described in the link below and once i get it working, i'll post an answer with all the steps i took for others that end up in the same fringe situation.
Kotlin and Unity development error

Related

Logging in FlutterActivity not appearing in VS Code

I'm developing a Flutter app, using VS Code. I've added some logging to my FlutterActivity, as follows:
package com.example.package
import android.os.Bundle
import android.util.Log
import io.flutter.embedding.android.FlutterActivity
class MainActivity: FlutterActivity() {
val TAG = this.javaClass.name
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Log.d(TAG, "Hello World!")
}
//...
When I run my app, I expect to see "Hello World!" displayed in the VS Code Debug Console, along with all of the other Android logging. However, I'm not seeing anything. What am I doing wrong?
Updates:
In Android Studio, the logging appears correctly in the Logcat tab.
With VS Code, if I start debugging my app with the tablet locked, and then unlock it, the logging does appear.
If I use adb logcat, the logging does/does not appear depending on which --regex filter I use, even though the regex matches the logs I'm expecting.

How to restart Android app within Espresso test?

I am using Espresso with Kotlin for the UI test automation. I am trying to find a proper way to restart the app during the test and start it again, so the test scenario is the following:
start the app, go to login page
force close the app and open it again (basically restart it)
check some stuff etc
The way our UI tests are organized:
there is a test class where I have rules
val intent = Intent(ApplicationProvider.getApplicationContext(), MainActivity::class.java)
.putExtra(UI_TEST_INTENT, true)
#get:Rule
val rule = ActivityScenarioRule<MainActivity>(intent)
there Before/After functions and tests functions in this class
What I want is to have generic restartApp function in separated class, let's say TestUtils and to be able to call it at any point of time, when is needed.
So far I didn't find a solution. There are some similar questions on stackoverflow, but I am not sure I understand how to work with the answers I found, like this:
with(activityRule) {
finishActivity()
launchActivity(null)
}
Since ActivityTestRule is deprecated and documentation asking to use ActivityScenarioRule, I tried this:
#get:Rule
val rule = ActivityScenarioRule<MainActivity>(intent)
private fun restart() {
rule.scenario.close()
rule.scenario.recreate()
}
but it gets java.lang.NullPointerException
another option is
private fun restart() {
pressBackUnconditionally()
Intents.release()
ActivityScenario.launch<MainActivity>(intent)
}
it works, app restarts but I can not interact with the app anymore, because for some reason there are two intents running now
Would be great to get an answer I can work with (I am quite new to Espresso)
Cheers
The solution is found:
private fun restart() {
Intents.release()
rule.scenario.close()
Intents.init()
ActivityScenario.launch<MainActivity>(intent)
}
Seems like the author's answer has some excess code. The following is enough
activityScenarioRule.scenario.close()
ActivityScenario.launch(YourActivity::class.java, null)

ShortcutManager crash in instant apps

When I run my instant app I'm experiencing a crash due to the shortcut feature, please see the image with the stack trace, this is the only thing I can provide as I'm not able to attach the debugger, another problem :(
**GroupApplication.class**
override fun onCreate() {
...
ShortcutsHelper.init(this)
ShortcutsHelper.addSearchShortcut()
}
object ShortcutsHelper {
lateinit var appContext: Context
lateinit var shortcutManager: ShortcutManager
fun init(context: Context) {
this.appContext = context.applicationContext
this.shortcutManager = context.getSystemService(ShortcutManager::class.java)
}
fun addSearchShortcut() {
val shortcut = ShortcutInfo.Builder(appContext, SEARCH_SHORTCUT_ID)
.setShortLabel(appContext.getString(R.string.search_shortcut_short_label))
.setLongLabel(appContext.getString(R.string.search_shortcut_long_label))
.setIcon(Icon.createWithResource(appContext, R.drawable.ic_search_black))
.setIntent(GroupHomeActivity.getStartIntent(appContext, NavigationScreen.SEARCH))
.build()
shortcutManager.addDynamicShortcuts(listOf(shortcut))
}
I understand that a shortcut does not make any sense in an Instant App, is there a better solution than having all the code related to shortcuts commented when creating an IA?
I understand that a shortcut does not make any sense in an Instant App, is there a better solution than having all the code related to
shortcuts commented when creating an IA?
So yes, Instant Apps is restricted from running some APIs for security purposes. There used to be a FAQ page for it that indicated this, but I can't find it anymore.
But anyways, you don't have to comment it out. You can use:
/instantapps/PackageManagerCompat.html#isInstantApp()

API call not working inside Anko Async

I'm trying to make an http request in Android, using Kotlin, and I've come across two ways of doing so.
One is the traditional way, using AsyncTask (not really pretty) which I got to work with the following code (just the doInBackground, as the rest of the class seemed unnecessary):
override fun doInBackground(vararg params: Void?): String? {
val url = URL("myUrl")
val httpClient = url.openConnection() as HttpURLConnection
if(httpClient.getResponseCode() == HttpURLConnection.HTTP_OK){
try {
val stream = BufferedInputStream(httpClient.getInputStream())
val data: String = readStream(inputStream = stream)
return data;
} catch (e : Exception) {
e.printStackTrace()
} finally {
httpClient.disconnect()
}
}else{
println("ERROR ${httpClient.getResponseCode()}")
}
return null
}
Now, I've come across a library called Anko, which many here know, and I tried to use its DSL for asynchronous tasks. The thing is, I haven't found a lot of info here about Anko for asynchronous tasks, so I thought I would open a new topic to see if someone could walk me through what I'm doing wrong, or what they think I should do to make it work.
The code I wanted to use is the following:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
async() {
val result = URL("myUrl").readText()
textView1.setText(result)
}
}
I tried to keep it as slim as possible so to minimize any potential mistakes, but I must be doing something wrong here because the code inside the async block is not doing anything, yet the app is not crashing and I'm not getting any exceptions. I've tried debugging it using Intellij IDEA, but after the first line inside the async block it stops the debugging while saying "The application is running". My best guess is that it got hung up somewhere in that first line due to the failed connection, but I don't know.
I've also tried to use the regular URL("myUrl").openConnection() inside the async block, but that hasn't worked either.
Anyway, any help would be deeply appreciated.
The problem textView1 contents not getting updated is caused by calling setText outside of main thread.
The documentation shows a nice example how to properly use async. Take a look at the following adapted version of your code:
async() {
val result = URL("http://stackoverflow.com/").readText()
uiThread {
textView1.text = result
}
}
PS. While not directly related to the question consider using a nicer http client i.e. Retrofit, OkHttp
The problem turned out to be a lot more basic than what I was thinking. It was a problem of compatibility apparently from having an older version of Android Studio running with the new version 1.0.2 of the Kotlin plugin and, again, apparently the function readText was not working properly and therefore I wasn't getting anything from it.
Anyway, I updated Android Studio, with the latest version of Kotlin and it started working fine, although I'm going to see if I can find out what it was that was causing the problem inside readText.

Problems with running Android Activity unit-testing from Eclipse

Im having a problem starting or running any activity unit tests from within eclipse.
Even i start a clean project and make a simple test class it always prints to the console:
[2010-10-05 13:10:24 - testAndroid] Collecting test information
[2010-10-05 13:10:25 - testAndroid] Test run failed: Test run incomplete. Expected 2 tests, received 0
Any ideas ?
Just for testing, I have created a fresh Android project called Demo with a test project called DemoTest
The main activity to test is called Main and I have created a simple testclass MainTest that looks like this:
package net.demo.test;
import android.test.ActivityInstrumentationTestCase2;
import net.demo.Main;
public class MainTest extends ActivityInstrumentationTestCase2<Main>
{
public MainTest()
{
super("net.demo", Main.class);
// TODO Auto-generated constructor stub
}
}
My tests used to run fine before, but suddenly I cant run any of them, they all fail with the same error, even I create new a project. It seems like it something to do with Eclipse or and not with the Code.
Update:
Seems like extending SingleLaunchActivityTestCase<Main> is working, but still got no clue about how to make ActivityInstrumentationTestCase2<Main> working.
I had no regression problems. I just couldn't get the example to work. I finally fixed it by defining two constructors:
public MainActivityTest(String pkg, Class<MainActivity> activityClass) {
super("com.myapp", MainActivity.class);
}
public MainActivityTest() {
super("com.myapp", MainActivity.class);
}
It turned out that most emulators before 2.3.3 were silently swallowing the error generated when construction went wrong.
You must put at least 2 methods (i.e 2 test cases) into the Test class. even methods without definition inside can do the trick

Categories

Resources