How to get Tracking State in ArCore - android

I am building an AR Android app where I want to spawn an arrow whenever the position of the user changes. However I get a NotTrackingException when I try to create an anchor. How can I know that ARCore detected a plane so that I can add my anchor?
The only thing I found is this, but there is not much I could get out of it.
fun onLocationChanged(location: Location) {
val session = arFragment.arSceneView.session
var arrowViewRenderable:ViewRenderable
val pos = floatArrayOf(0f,0f,-1f)
val rotation = floatArrayOf(0f,0f,0f,1f)
val anchor = session!!.createAnchor(Pose(pos,rotation))
val anchorNode = AnchorNode(anchor)
anchorNode.setParent(arFragment.arSceneView.scene)
ViewRenderable.builder()
.setView(this, R.layout.arrow)
.setSizer(DpToMetersViewSizer(400 ))
.build()
.thenAccept { renderable -> arrowViewRenderable = renderable
anchorNode.renderable = arrowViewRenderable
}
}
status.cc:156 ArStatusErrorSpace::AR_ERROR_NOT_TRACKING: Cannot create anchors while the camera is not tracking.
2019-06-12 14:58:37.369 29685-29685/com.carmeq.carfind E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.carmeq.carfind, PID: 29685
com.google.ar.core.exceptions.NotTrackingException
at java.lang.reflect.Constructor.newInstance0(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
at com.google.ar.core.Session.throwExceptionFromArStatus(Session.java:134)
at com.google.ar.core.Session.nativeCreateAnchor(Native Method)
at com.google.ar.core.Session.createAnchor(Session.java:93)
at com.carmeq.carfind.MainActivity.onLocationChanged(MainActivity.kt:282)
at com.carmeq.carfind.MainActivity$mLocationCallback$1.onLocationResult(MainActivity.kt:223)
at com.google.android.gms.internal.zzbzq.zzq(Unknown Source:4)
at com.google.android.gms.common.api.internal.zzcj.zzb(Unknown Source:8)
at com.google.android.gms.common.api.internal.zzck.handleMessage(Unknown Source:16)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:6981)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1445)

You can retrieve the TrackingState from the Camera of the current Frame.
val frame = session.update()
if (frame.camera.trackingState == TrackingState.tracking) {
// place anchor
}

Related

Android Studio getPixel of CameraX Bitmap error (Kotlin)

I made an android app (Android Studio + Kotlin) that uses CameraX. So this is my code to start the camera:
private fun startCamera() {
val cameraProviderFuture = ProcessCameraProvider.getInstance(this)
cameraProviderFuture.addListener(Runnable {
// Used to bind the lifecycle of cameras to the lifecycle owner
val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()
// Preview
val preview = Preview.Builder()
.build()
.also {
it.setSurfaceProvider(viewFinder.surfaceProvider)
}
// Select back camera as a default
val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
try {
// Unbind use cases before rebinding
cameraProvider.unbindAll()
// Bind use cases to camera
cameraProvider.bindToLifecycle(
this, cameraSelector, preview
)
} catch (exc: Exception) {
Log.e(TAG, "Use case binding failed", exc)
}
}, ContextCompat.getMainExecutor(this))
}
Now I wanted to get a bitmap of the viewFinder so that I can determine the color of the pixel in the center:
val bitmap = viewFinder.bitmap
val pixel = bitmap?.getPixel(width / 2, height / 2 - 30)
val pixel2 = if (pixel != null) pixel else -1
bitmap is Bitmap? and pixel is Int?
When I run the app everything works completely fine but then sometimes it crashes and shoots out this message:
at com.example.colorblind.MainActivity$onCreate$r$1.run(MainActivity.kt:116)
Line 116 is the line with val pixel = bitmap?.getPixel(width / 2, height / 2 - 30). If I then add a line before the code so that it hops to line 117 everything works perfectly fine again until the same error occurs. Then I need to change the line again. How can I fix this problem because I can't publish the app like this if it sometimes randomly crashes while opening.
I hope I was able to explain the problem properly.
EDIT
This is the only message I get when it crashes:
2022-02-16 20:43:53.123 7337-7337/com.example.colorblind E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.colorblind, PID: 7337
java.lang.IllegalArgumentException: y must be < bitmap.height()
at android.graphics.Bitmap.checkPixelAccess(Bitmap.java:1958)
at android.graphics.Bitmap.getPixel(Bitmap.java:1863)
at com.example.colorblind.MainActivity$onCreate$r$1.run(MainActivity.kt:116)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)

unable to convert Edittext to int

class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
var X: EditText = findViewById(R.id.num12)
var Y: EditText = findViewById(R.id.num2)
var B: Button = findViewById(R.id.btn1)
var vir: TextView = findViewById(R.id.virw)
var X1: Int = X.text.toString().toInt()
var Y1: Int = Y.text.toString().toInt()
B.setOnClickListener() {
vir.text = "add new ${addtwonumber(X1, Y1)}"
}
}
private fun addtwonumber(a:Int,b:Int):Int{
return a+b
}
}
Error 2021-11-20 20:29:39.940 29733-29733/com.example.calibrate
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.calibrate, PID: 29733
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.calibrate/com.example.calibrate.MainActivity}:
java.lang.NumberFormatException: For input string: ""
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3528)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3703)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2152)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:250)
at android.app.ActivityThread.main(ActivityThread.java:7886)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:970)
Caused by: java.lang.NumberFormatException: For input string: ""
at java.lang.Integer.parseInt(Integer.java:627)
at java.lang.Integer.parseInt(Integer.java:650)
at com.example.calibrate.MainActivity.onCreate(MainActivity.kt:23)
at android.app.Activity.performCreate(Activity.java:8108)
at android.app.Activity.performCreate(Activity.java:8092)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3501)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3703) 
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85) 
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2152) 
at android.os.Handler.dispatchMessage(Handler.java:106) 
at android.os.Looper.loop(Looper.java:250) 
at android.app.ActivityThread.main(ActivityThread.java:7886) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:970) 
2021-11-20 20:29:39.957 29733-29733/com.example.calibrate I/Process:
Sending signal. PID: 29733 SIG: 9
Looks at this line of the error:
java.lang.NumberFormatException: For input string: ""
You have an empty string (because your EditText is empty initially) which your are trying to convert to an Int. That's why you are getting the NumberFormatException.
You can fix the error by using String.toIntOrNull(). This function returns null instead of throwing an exception if the string cannot be converted to an Int. Then you can maybe use the elvis operator(?:) to use a default value for the null Int.
val X1: Int = X.text.toString().toIntOrNull() ?: 0 // Use zero if string does not represent an Int
On a side note, please use vals instead of vars for properties that are not going to change and also give better names to them (X, Y, X1, Y2 don't look good)
At the beginning your EditTexts are empty, so the error is because it can't convert empty "" to integer, so you can check first if it is not empty or use toIntOrNull() function, but you also want to get the x and y when the user clicks on the button not at the beginning so the right way is to move your code from onCreate to onClickListener body
B.setOnClickListener() {
val X1: Int = X.text.toString().toInt()
val Y1: Int = Y.text.toString().toInt()
vir.text = "add new ${addtwonumber(X1, Y1)}"
}

Software rendering doesn't support hardware bitmaps

I'm trying to overlay two bitmaps.
This code works fine on below android 9. On android 9 and above the application crash.
private fun overlay(base: Bitmap, blend: Bitmap): Bitmap {
return try {
val result: Bitmap =
base.copy(Bitmap.Config.ARGB_8888, true)
val p = Paint()
p.xfermode = PorterDuffXfermode(PorterDuff.Mode.ADD)
p.shader = BitmapShader(blend, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP)
val c = Canvas()
c.setBitmap(result)
c.drawBitmap(base, 0f, 0f, null)
c.drawRect(0f, 0f, base.width.toFloat(), base.height.toFloat(), p)
result
} catch (e: Exception) {
println(e.message.toString())
base
}
}
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.ex.image, PID: 26562
java.lang.IllegalArgumentException: Software rendering doesn't support hardware bitmaps
at android.graphics.BaseCanvas.onHwBitmapInSwMode(BaseCanvas.java:632)
at android.graphics.BaseCanvas.throwIfHwBitmapInSwMode(BaseCanvas.java:639)
at android.graphics.BaseCanvas.throwIfCannotDraw(BaseCanvas.java:73)
at android.graphics.MiuiCanvas.throwIfCannotDraw(MiuiCanvas.java:329)
at android.graphics.BaseCanvas.drawBitmap(BaseCanvas.java:113)
at android.graphics.MiuiCanvas.drawBitmap(MiuiCanvas.java:98)
at android.graphics.Canvas.drawBitmap(Canvas.java:1613)
at com.ex.image.fragments.FiltersFragment.overlay(FiltersFragment.kt:103)
at com.ex.image.fragments.FiltersFragment.applyFilter(FiltersFragment.kt:86)
at com.ex.image.adapters.FilterRecyclerAdapter.onBindViewHolder$lambda-0(FilterRecyclerAdapter.kt:39)
at com.ex.image.adapters.FilterRecyclerAdapter.$r8$lambda$KexXVg24JaLUI6vIkMTUBOYKnlY(Unknown
Source:0)
at com.ex.image.adapters.FilterRecyclerAdapter$$ExternalSyntheticLambda0.onClick(Unknown
Source:4)
at android.view.View.performClick(View.java:7509)
at android.view.View.performClickInternal(View.java:7486)
at android.view.View.access$3600(View.java:841)
at android.view.View$PerformClick.run(View.java:28710)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:236)
at android.app.ActivityThread.main(ActivityThread.java:8056)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:656)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:967)
Note:
I have already turn off the HARDWARE_ACCELERATED for android 9 above.

Early return in Jetpack Compose view will crash with `java.lang.IllegalStateException: Start/end imbalance`?

I have a simple Composable as below
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Testing()
}
}
}
#Composable
fun Testing(modifier: Modifier = Modifier) {
var height = 0f
Column(modifier = modifier.onGloballyPositioned {
height = it.size.height.toFloat()
}) {
if (height == 0f) return
// Do something
}
}
It will crash with
2021-04-06 20:09:14.132 8383-8383/com.example.jetpackcomposeanimationspec E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.jetpackcomposeanimationspec, PID: 8383
java.lang.IllegalStateException: Start/end imbalance
at androidx.compose.runtime.ComposerImpl.finalizeCompose(Composer.kt:2890)
at androidx.compose.runtime.ComposerImpl.endRoot(Composer.kt:1149)
at androidx.compose.runtime.ComposerImpl.composeContent$runtime_release(Composer.kt:2602)
at androidx.compose.runtime.CompositionImpl.composeContent(Composition.kt:348)
at androidx.compose.runtime.Recomposer.composeInitial$runtime_release(Recomposer.kt:693)
at androidx.compose.runtime.CompositionImpl.setContent(Composition.kt:304)
But if I change Testing to
#Composable
fun Testing(modifier: Modifier = Modifier) {
var height = 0f
Column(modifier = modifier.onGloballyPositioned {
height = it.size.height.toFloat()
}) {
if (height != 0f) {
// Do something
}
}
}
It no longer crash. Why?
I have this issue on Compose version 1.1.1. But if I type for example return#Column instead of return there will not be a crash.
Column {
return // will crash
}
Column {
return#Column // works for me
}
UPD! This works stable only in debug mode. If I build release it may crash with ArrayIndexOutOfBoundsException in ComposerImpl:
java.lang.ArrayIndexOutOfBoundsException: length=163; index=-1
at java.util.ArrayList.remove(ArrayList.java:506)
at androidx.compose.runtime.Stack.pop(Stack.kt:26)
at androidx.compose.runtime.ComposerImpl.exitGroup(Composer.kt:2131)
at androidx.compose.runtime.ComposerImpl.end(Composer.kt:2293)
at androidx.compose.runtime.ComposerImpl.endGroup(Composer.kt:1494)
at androidx.compose.runtime.ComposerImpl.endRoot(Composer.kt:1387)
at androidx.compose.runtime.ComposerImpl.doCompose(Composer.kt:3199)
at androidx.compose.runtime.ComposerImpl.recompose$runtime_release(Composer.kt:3140)
at androidx.compose.runtime.CompositionImpl.recompose(Composition.kt:722)
at androidx.compose.runtime.Recomposer.performRecompose(Recomposer.kt:876)
at androidx.compose.runtime.Recomposer.access$performRecompose(Recomposer.kt:107)
at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke(Recomposer.kt:485)
at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke(Recomposer.kt:454)
at androidx.compose.ui.platform.AndroidUiFrameClock$withFrameNanos$2$callback$1.doFrame(AndroidUiFrameClock.android.kt:34)
at androidx.compose.ui.platform.AndroidUiDispatcher.performFrameDispatch(AndroidUiDispatcher.android.kt:109)
at androidx.compose.ui.platform.AndroidUiDispatcher.access$performFrameDispatch(AndroidUiDispatcher.android.kt:41)
at androidx.compose.ui.platform.AndroidUiDispatcher$dispatchCallback$1.doFrame(AndroidUiDispatcher.android.kt:69)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1035)
at android.view.Choreographer.doCallbacks(Choreographer.java:845)
at android.view.Choreographer.doFrame(Choreographer.java:775)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1022)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7839)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
In compose version '1.2.0-beta01' this issue still exists
I also had this exception and my code had no return statement. So what I did to fix it is downgrading kotlinCompilerExtensionVersion from 1.3.2 to 1.1.1

Widget is null when Adapter is generating view and the user is on another fragment

I am using ViewPager to display 3 fragments in a main activity. I have a CardView that displays when a RecyclerView (populated by an adapter is empty. My Code works fine when on launch I am on the screen where the CardView and RecycleView appears but if I am any of the other fragments when the Adapter is loading - I get a null pointer error and the app crashed. Either bull on the CardView or on the RecycleView or both. In the code below for the fragment homeAgenda and noEvents cause the app to crash when identfied as null. There is a delay in load because the app syncs with Google Calendar and then displays in the RecyclerView at which point if I am on another fragment - the app crashes.... please refer ti runuionThread
I have used findViewByID and done a null check but the app keeps crashing - how can I avoid this scenario?
private fun getEvents(){
val noEvents = view?.findViewById<LinearLayout>(R.id.no_events)
val homeAgenda = view?.findViewById<RecyclerView>(R.id.homeAgenda)
GlobalScope.launch {
Log.d(
TAG,
"Time current: ${calendar.get(java.util.Calendar.DAY_OF_MONTH)}, ${calendar.get(java.util.Calendar.HOUR_OF_DAY)}, ${
calendar.get(java.util.Calendar.MINUTE)
}"
)
calendar.set(java.util.Calendar.HOUR_OF_DAY, 0)
calendar.set(java.util.Calendar.MINUTE, 0)
calendar.set(java.util.Calendar.SECOND, 0)
calendar.set(java.util.Calendar.MILLISECOND, 0)
val db = AppDatabase.getInstance(requireActivity())
val events = db.getEvents(calendar.timeInMillis)
val listOfEvents = ArrayList<MyEvent>()
for (event in events) {
if (event.isPrimary) {
listOfEvents.add(event)
} else {
listOfEvents.add(0, event)
}
}
Log.d(TAG, "getEvents: ${events.size}")
requireActivity().runOnUiThread {
if(listOfEvents.size != 0) {
noEvents!!.visibility = View.GONE
} else {
noEvents!!.visibility = View.VISIBLE
}
val recyclerView: RecyclerView? = homeAgenda
recyclerView!!.layoutManager = LinearLayoutManager(activity)
recyclerView.adapter = EventsAdapter(
requireContext(), listOfEvents,calendar.timeInMillis
)
}
}
}
Error Log/ Stacktrace below - error hitting on this line from the above code noEvents!!.visibility = View.VISIBLE and when I remove this then it hits on the recycleView being null...
E/AndroidRuntime: FATAL EXCEPTION: main
Process: , PID: 6492
java.lang.NullPointerException
at Fragments.Home$getEvents$1$1.run(Home.kt:294)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)

Categories

Resources