#StackBounty: #android #kotlin #google-vision #google-mlkit Reduce tracking window using google mlkit vision samples

Bounty: 500

I would like to reduce the reduce bar code tracking window when using the google vision api. There are some answers here but they feel a bit outdated.

I’m using google’s sample: https://github.com/googlesamples/mlkit/tree/master/android/vision-quickstart

Currently, I try to figure out if a barcode is inside my overlay box inside BarcodeScannerProcessor onSuccess callback:

override fun onSuccess(barcodes: List<Barcode>, graphicOverlay: GraphicOverlay) {
    if(barcodes.isEmpty())
      return;

    for(barcode in barcodes) {
      val center = Point(graphicOverlay.imageWidth / 2, graphicOverlay.imageHeight / 2)
      val rectWidth = graphicOverlay.imageWidth * Settings.OverlayWidthFactor
      val rectHeight = graphicOverlay.imageHeight * Settings.OverlayHeightFactor

      val left = center.x - rectWidth / 2
      val top = center.y - rectHeight / 2
      val right = center.x + rectWidth / 2
      val bottom = center.y + rectHeight / 2

      val rect = Rect(left.toInt(), top.toInt(), right.toInt(), bottom.toInt())

      val contains = rect.contains(barcode.boundingBox!!)
      val color = if(contains) Color.GREEN else Color.RED

      graphicOverlay.add(BarcodeGraphic(graphicOverlay, barcode, "left: ${barcode.boundingBox!!.left}", color))
    }
}

Y-wise it works perfectly, but the X values from barcode.boundingBox e.g. barcode.boundingBox.left seems to have an offset. Is it based on what’s being calculated in GraphicOverlay?

I’m expecting the value below to be close to 0, but the offset is about 90 here:

enter image description here

Or perhaps it’s more efficient to crop the image according to the box?


Get this bounty!!!

#StackBounty: #android #kotlin #android-camera2 How to take a picture where all settings are set manually including the flash without m…

Bounty: 100

I used the latest Camera2Basic sample program as a source for my trials:

https://github.com/android/camera-samples.git

Basically I configured the CaptureRequest before I call the capture() function in the takePhoto() function like this:

    private fun prepareCaptureRequest(captureRequest: CaptureRequest.Builder) {
    //set all needed camera settings here
    captureRequest.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_OFF)

    captureRequest.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_OFF);
    //captureRequest.set(CaptureRequest.CONTROL_AF_TRIGGER, CaptureRequest.CONTROL_AF_TRIGGER_CANCEL);
    //captureRequest.set(CaptureRequest.CONTROL_AWB_LOCK, true);
    captureRequest.set(CaptureRequest.CONTROL_AWB_MODE, CaptureRequest.CONTROL_AWB_MODE_OFF);
    captureRequest.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_OFF);
    //captureRequest.set(CaptureRequest.CONTROL_AE_LOCK, true);
    //captureRequest.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL);
    //captureRequest.set(CaptureRequest.NOISE_REDUCTION_MODE, CaptureRequest.NOISE_REDUCTION_MODE_FAST);

    //flash
    if (mState == CaptureState.PRECAPTURE){
        //captureRequest.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_OFF);
        captureRequest.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF)
    }
    if (mState == CaptureState.TAKEPICTURE) {
        //captureRequest.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_SINGLE)
        //captureRequest.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_ALWAYS_FLASH);
        captureRequest.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_SINGLE)
    }

    val iso = 100
    captureRequest.set(CaptureRequest.SENSOR_SENSITIVITY, iso)

    val fractionOfASecond = 750.toLong()
    captureRequest.set(CaptureRequest.SENSOR_EXPOSURE_TIME, 1000.toLong() * 1000.toLong() * 1000.toLong() / fractionOfASecond)
    //val exposureTime = 133333.toLong()
    //captureRequest.set(CaptureRequest.SENSOR_EXPOSURE_TIME, exposureTime)

    //val characteristics = cameraManager.getCameraCharacteristics(cameraId)
    //val configs: StreamConfigurationMap? = characteristics[CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP]
    //val frameDuration = 33333333.toLong()
    //captureRequest.set(CaptureRequest.SENSOR_FRAME_DURATION, frameDuration)

    val focusDistanceCm = 20.0.toFloat()    //20cm 
    captureRequest.set(CaptureRequest.LENS_FOCUS_DISTANCE, 100.0f / focusDistanceCm)

    //captureRequest.set(CaptureRequest.COLOR_CORRECTION_MODE, CameraMetadata.COLOR_CORRECTION_MODE_FAST)
    captureRequest.set(CaptureRequest.COLOR_CORRECTION_MODE, CaptureRequest.COLOR_CORRECTION_MODE_TRANSFORM_MATRIX)
    val colorTemp = 8000.toFloat();
    val rggb = colorTemperature(colorTemp)
    //captureRequest.set(CaptureRequest.COLOR_CORRECTION_TRANSFORM, colorTransform);
    captureRequest.set(CaptureRequest.COLOR_CORRECTION_GAINS, rggb);
}

but the picture that is returned never is the picture where the flash is at its brightest. This is on a Google Pixel 2 device.
As I only take one picture I am also not sure how to check some CaptureResult states to find the correct one as there is only one.
I already looked at the other solutions to similar problems here but they were either never really solved or somehow took the picture during capture preview which I don’t want.

Other strange observations are that on different devices the images are taken (also not always at the right moment), but then the manual values I set are not observed in the JPEG metadata of the image.

If needed I can put my git fork on github.


Get this bounty!!!

#StackBounty: #android-studio #kotlin #android-jetpack Why does LiveData only effect main layout and doesn't LiveData effect child …

Bounty: 50

FragmentHome load layout_home.xml, and layout_home.xml displays a recyclerview and a button named btnMain

recyclerview include the item layout layout_voice_item.xml, it displays a button named btnChild

I use displayCheckBox : LiveData<Boolean> to control whether both btnMain and btnChild are shown or not with the code android:visibility="@{!aHomeViewModel.displayCheckBox? View.VISIBLE: View.GONE}".

I find btnMain can be shown or not when I change the value of displayCheckBox, but btnChild keep to show, why?

FragmentHome.kt

class FragmentHome : Fragment() {

    private lateinit var binding: LayoutHomeBinding

    private val mHomeViewModel by lazy {
        getViewModel {
            HomeViewModel(provideRepository(mContext))
        }
    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        binding = DataBindingUtil.inflate(
            inflater, R.layout.layout_home, container, false
        )
        binding.lifecycleOwner = this.viewLifecycleOwner
        binding.aHomeViewModel=mHomeViewModel

        val adapter = VoiceAdapters(mHomeViewModel)
        binding.mvoiceList.adapter=adapter
        mHomeViewModel.listVoiceBySort.observe(viewLifecycleOwner){
          adapter.submitList(it)
        }
        ...
        return binding.root
    }
}

HomeViewModel.kt

class HomeViewModel(private val mDBVoiceRepository: DBVoiceRepository) : ViewModel() {

    private val _displayCheckBox = MutableLiveData<Boolean>(true)
    val displayCheckBox : LiveData<Boolean> = _displayCheckBox

    fun setCheckBox(isDisplay:Boolean){
        _displayCheckBox.value = isDisplay
    }

    ...
}

VoiceAdapters.kt

class VoiceAdapters (private val aHomeViewModel: HomeViewModel):
        ListAdapter<MVoice, VoiceAdapters.VoiceViewHolder>(MVoiceDiffCallback()) {
    ...
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VoiceViewHolder {
        return VoiceViewHolder(
            LayoutVoiceItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
        )
    }

    override fun onBindViewHolder(holder: VoiceViewHolder, position: Int) {
        val aMVoice = getItem(position)
        holder.bind(aHomeViewModel, aMVoice)
    }

    inner class VoiceViewHolder (private val binding: LayoutVoiceItemBinding):
          RecyclerView.ViewHolder(binding.root) {

        fun bind(mHomeViewModel: HomeViewModel, aMVoice: MVoice) {
            binding.aHomeViewModel = mHomeViewModel
            binding.executePendingBindings()
        }

    }

    ...
}
class MVoiceDiffCallback : DiffUtil.ItemCallback<MVoice>() {
    ...
}

layout_home.xml

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>
        <import type="android.view.View" />

        <variable name="aHomeViewModel"
            type="info.dodata.voicerecorder.viewcontrol.HomeViewModel" />
    </data>

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/mvoice_list"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
            tools:listitem="@layout/layout_voice_item"            
        />

      <Button
            android:id="@+id/btnMain"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"         
            android:visibility="@{!aHomeViewModel.displayCheckBox? View.VISIBLE: View.GONE}"            
        />

</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

layout_voice_item.xml

<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">

<data>
    <import type="android.view.View" />
    <variable name="aHomeViewModel"
        type="info.dodata.voicerecorder.viewcontrol.HomeViewModel" />
</data>

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <Button
        android:id="@+id/btnChild"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:visibility="@{!aHomeViewModel.displayCheckBox? View.VISIBLE: View.GONE}"        
    />

</LinearLayout>
</layout>


Get this bounty!!!

#StackBounty: #android #kotlin #android-livedata How to access each element of LiveData<List<MVoice>> with Kotlin?

Bounty: 50

The Code A use for (aMovice in listVoiceBySort.value!!) to access each element of LiveData<List<MVoice>>.

But I don’t think it’s a good way because it uses listVoiceBySort.value!!, it’s ugly.

Is there a good way to access each element of LiveData<List<MVoice>>?

Code A

 val listVoiceBySort: LiveData<List<MVoice>> =_listVoiceBySort

 fun selectAllIDs(){
   for (aMovice in listVoiceBySort.value!!){
            selectedIDs.add(aMovice.id)
    }
 }


Get this bounty!!!

#StackBounty: #spring-boot #kotlin #spring-security #spring-webflux Force ServerAuthenticationFailureHandler for a given path in Spring…

Bounty: 100

I have two paths /foo and /bar. For /foo I have a custom authentication mechanism that I use. On /bar I have Basic authentication.

This setup works fine except one case. When I do not pass the AUTHORIZATION header in /foo then Basic auth kicks in instead of MyAuthenticationFailureHandler

Is there a way to set MyAuthenticationFailureHandler for a given path? Or maybe I messed up something with SecurityWebFiltersOrder?

My full security config:

bean<MyReactiveUserDetailsService>()
bean<MyReactiveAuthenticationManager>()
bean {
    ref<ServerHttpSecurity>()
        .securityMatcher {
            if (it.request.path.value().contains("/bar")) {
                ServerWebExchangeMatcher.MatchResult.match()
            } else {
                ServerWebExchangeMatcher.MatchResult.notMatch()
            }
        }
        .formLogin().disable()
        .csrf().disable()
        .logout().disable()
        .httpBasic()
        .and()
        .authorizeExchange()
        .pathMatchers("/bar/**")
        .hasRole("ADMIN")
        .anyExchange().permitAll()
        .and()
        .build()
}

bean {
    ref<ServerHttpSecurity>()
        .securityMatcher {
            if (it.request.path.value().contains("/bar")) {
                ServerWebExchangeMatcher.MatchResult.notMatch()
            } else {
                ServerWebExchangeMatcher.MatchResult.match()
            }
        }
        .httpBasic().disable()
        .formLogin().disable()
        .csrf().disable()
        .logout().disable()
        .authorizeExchange()
        .pathMatchers(
            HttpMethod.POST,
            "/foo/**"
        ).hasRole(
            "ABRACADABRA"
        )
        .anyExchange().permitAll()
        .and()
        .addFilterAt(
            authenticationWebFilter(ref(), ref()),
            SecurityWebFiltersOrder.AUTHENTICATION
        )
        .build()
}
}

private fun authenticationWebFilter(
    reactiveAuthenticationManager: ReactiveAuthenticationManager,
    objectMapper: ObjectMapper
) =
    AuthenticationWebFilter(reactiveAuthenticationManager).apply {
        setServerAuthenticationConverter(MyAuthenticationConverter())
        setRequiresAuthenticationMatcher(
            ServerWebExchangeMatchers.pathMatchers(
                HttpMethod.POST,
               "/foo/**"
            )
        )
        setAuthenticationFailureHandler(MyAuthenticationFailureHandler(objectMapper))
    }

class MyAuthenticationConverter : ServerAuthenticationConverter {
    override fun convert(exchange: ServerWebExchange): Mono<Authentication> {
        val authHeader: String? = exchange.request.headers.getFirst(HttpHeaders.AUTHORIZATION)
        // ... 
        return when {
            isValid(authHeader, ...) -> {
                Mono.just(
                    UsernamePasswordAuthenticationToken(principal, credentials)
                )
            }
            else -> Mono.empty()
        }
    }
}

class MyAuthenticationFailureHandler(private val objectMapper: ObjectMapper) : ServerAuthenticationFailureHandler {
    override fun onAuthenticationFailure(
        webFilterExchange: WebFilterExchange,
        exception: AuthenticationException?
    ): Mono<Void> {
        val response = webFilterExchange.exchange.response
        response.apply {
            statusCode = HttpStatus.OK
            headers.contentType = MediaType.APPLICATION_JSON
            headers.set(HttpHeaders.WARNING, """199 warning "Invalid token"""")
        }

        return response.writeWith(
            Flux.just(
                DefaultDataBufferFactory().wrap(
                    objectMapper.writeValueAsBytes(
                        MyDto(
                            // ...
                        ).toSettingResponse()
                    )
                )
            )
        )
    }
}


Get this bounty!!!

#StackBounty: #android #kotlin #gson #retrofit #retrofit2 Retrofit Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $ …

Bounty: 50

So in my app a user can take a picture of their meal and through the use of Tensorflow’s image classification, it will classify what the meal is in onActivityResult. Then, using Edamam Recipe Search API, it will return a recipe for that meal to the user.

When I run my app, everything is working fine and nothing is crashing, however when I use Retrofit Callback, the onFailure method is called and I get this error:
Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $

This is what I have in my RecipeApi interface:

@GET("search")
fun searchRecipe(
    @Query("q") query: String,
    @Query("app_id") app_id: String,
    @Query("app_key") app_key: String,
    @Query("from") from: Int,
    @Query("to") to: Int
): Call<List<Recipe>>

And this is what I have in my onActivityResult in my MainActivity:

retrofit = Retrofit.Builder()
    .baseUrl(Constants.BASE_URL)
    .addConverterFactory(GsonConverterFactory.create())
    .build()
jsonPlaceHolderApi = retrofit.create(RecipeApi::class.java)
call = jsonPlaceHolderApi.searchRecipe(text, Constants.API_ID, Constants.API_KEY, 0, 1)
call.enqueue(object : Callback<List<Recipe>> {
    override fun onResponse(
        call: Call<List<Recipe>>,
        response: Response<List<Recipe>>
    ) {
        if (!response.isSuccessful) {
            println("Code: " + response.code())
            return
        }
        recipes = response.body()!!
        for (recipe: Recipe in recipes) {
            var content: String = ""
            content += "Yield: ${recipe.yield} + n"
            content += "Calories: ${recipe.calories} + n"
            content += "TotalWeight: ${recipe.totalWeight} + n"
            content += "Ingredients: ${recipe.ingredients} + n"
            content += "TotalNutrients: ${recipe.totalNutrients} + n"
            content += "TotalDaily: ${recipe.totalDaily} + nn"
            println(content)
        }
    }

    override fun onFailure(call: Call<List<Recipe>>, t: Throwable) {
        println(t.message)
    }
})

For jsonPlaceHolderApi, call, and recipes, I created those variables at the top of my activity:

private lateinit var jsonPlaceHolderApi: RecipeApi
private lateinit var call: Call<List<Recipe>>
private lateinit var recipes: List<Recipe>

Does anyone know how to fix this issue?


Get this bounty!!!

#StackBounty: #android #kotlin #uri #mediastore #android-fileprovider Get PDF from MediaStore after receiving "content://" Ur…

Bounty: 50

I start an ACTION_GET_CONTENT intent in order to pick a PDF:

override fun routeToFilePicker() {
    val intent = Intent()
    intent.type = MediaType.PDF.toString()
    intent.action = Intent.ACTION_GET_CONTENT
    activity.startActivityForResult(
        Intent.createChooser(intent, "Select PDF"),
        REQUEST_CODE_PDF_PICKER
    )
}

Then on onActivityResult I try to create a PDF from the Uri (content//:path):

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_CODE_PDF_PICKER ) {
        data?.data?.let { pdfUri: Uri ->
            val pdfFile: File = pdfUri.toFile() <-- chrash
            ...
        }
    }
}

pdfUri.toFile() causes a fatal Exception:

java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1003, result=-1, data=Intent { dat=content://com.android.providers.downloads.documents/document/3569 flg=0x1 }} to activity {my.package.name.activity}: java.lang.IllegalArgumentException: Uri lacks 'file' scheme: content://com.android.providers.downloads.documents/document/3569

Caused by: java.lang.IllegalArgumentException: Uri lacks 'file' scheme: content://com.android.providers.downloads.documents/document/3569

I need a File in order to convert the pages into Images.
How can I get the PDF as a File from the Uri returned by MediaStore?


Get this bounty!!!

#StackBounty: #android #kotlin #kotlin-coroutines Abstract coroutines structure

Bounty: 50

With RxJava we can do something like this:

BaseViewModel

protected void subscribe(Completable completable, MutableLiveData<Response> response) {
    mDisposable.add(
            completable.observeOn(AndroidSchedulers.mainThread())
                    .subscribeOn(Schedulers.io())
                    .doOnSubscribe(disposable -> response.setValue(Response.loading()))
                    .doFinally(() -> response.setValue(Response.idle()))
                    .subscribe(
                            () -> response.setValue(Response.success(true)),
                            e -> response.setValue(Response.error(e))
                    )
    );
}

protected <T> void subscribe(Single<T> single, MutableLiveData<Response> response) {
    mDisposable.add(
            single.observeOn(AndroidSchedulers.mainThread())
                    .subscribeOn(Schedulers.io())
                    .doOnSubscribe(disposable -> response.setValue(Response.loading()))
                    .doFinally(() -> response.setValue(Response.idle()))
                    .subscribe(
                            result -> response.setValue(Response.success(result)),
                            e -> response.setValue(Response.error(e))
                    )
    );
}

Then, from repository we getting Single/Complete and pass it to our custom subscribe(), then we cat generic Result with data(optional), very easy way to work with asynchronous requests.

How we can abstract coroutines with similar structure, instead of write Launch in every method in ViewModel and try/catch error manually?


Get this bounty!!!

#StackBounty: #java #android #android-studio #kotlin Unable to add library to Android Studio project

Bounty: 150

I’m trying to add this library to Android Studio locally using this tutorial on YouTube.

However, I get errors that I can’t post here because they’re too many (99+).

Can someone tell me step by step (in detail) how to succesfully add this library to my project and be able to edit it afterwards?

This is the main error I get when I try to import this library: Unable to determine constructor argument #1: missing parameter of type Factory, or no service of type Factory<LoggingManagerInternal>.


Get this bounty!!!