Kotlin Android Barcode Nutrition API Example
Published June 7, 2026
Barcode scanning is the feature users expect on Android calorie trackers. This Kotlin Android barcode nutrition API example shows CameraX capture, Retrofit networking, and UPC lookup through Calorie API without exposing your key in the APK.
What You Will Build
- Scan UPC/EAN with CameraX
- Call your backend barcode endpoint
- Display calories and macros
- Log a portion in grams
Dependencies
// build.gradle.kts (app)
implementation("androidx.camera:camera-camera2:1.3.1")
implementation("androidx.camera:camera-view:1.3.1")
implementation("com.google.mlkit:barcode-scanning:17.2.0")
implementation("com.squareup.retrofit2:retrofit:2.9.0")
implementation("com.squareup.retrofit2:converter-gson:2.9.0")
Retrofit Interface (Backend Proxy)
interface NutritionApi {
@GET("api/foods/barcode/{upc}")
suspend fun lookupBarcode(@Path("upc") upc: String): FoodDetailResponse
@GET("api/foods/search")
suspend fun searchFoods(
@Query("q") query: String,
@Query("limit") limit: Int = 15
): FoodSearchResponse
}
data class FoodDetailResponse(
val id: Int,
val name: String,
val brand: String?,
val calories: Double?,
val protein_g: Double?,
val carbohydrates_g: Double?,
val fat_g: Double?
)
val api = Retrofit.Builder()
.baseUrl("https://your-backend.example.com/")
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(NutritionApi::class.java)
Base URL points at Firebase or Next.js proxy, not Calorie API directly.
Barcode Analyzer
@OptIn(ExperimentalGetImage::class)
class BarcodeAnalyzer(
private val onBarcode: (String) -> Unit
) : ImageAnalysis.Analyzer {
private val scanner = BarcodeScanning.getClient()
override fun analyze(imageProxy: ImageProxy) {
val mediaImage = imageProxy.image ?: return
val input = InputImage.fromMediaImage(mediaImage, imageProxy.imageInfo.rotationDegrees)
scanner.process(input)
.addOnSuccessListener { barcodes ->
barcodes.firstOrNull()?.rawValue?.let(onBarcode)
}
.addOnCompleteListener { imageProxy.close() }
}
}
Lookup and Display
class BarcodeViewModel(private val api: NutritionApi) : ViewModel() {
private val _food = MutableStateFlow<FoodDetailResponse?>(null)
val food = _food.asStateFlow()
fun onBarcodeScanned(upc: String) {
if (!upc.matches(Regex("^\\d{8,14}$"))) return
viewModelScope.launch {
try {
_food.value = api.lookupBarcode(upc)
} catch (e: Exception) {
_food.value = null
}
}
}
}
Validate UPC format before calling upstream.
Scale Portion
fun scale(per100g: Double, grams: Double) = (grams / 100.0) * per100g
Handle Scan Failures
| Case | UX |
|---|---|
| Unknown barcode | Offer manual search |
| Network error | Retry + offline message |
| Invalid UPC | Ignore and keep scanning |
Open Food Facts barcodes may be missing branded data. Calorie API indexes packaged foods with verified macros. See Open Food Facts rate limits for production tradeoffs.
Related Guides
Frequently Asked Questions
How do I look up nutrition from a barcode in Kotlin Android?
Scan UPC with CameraX and ML Kit, validate the barcode format, call your backend proxy barcode endpoint, and parse JSON macros from Calorie API.
Can I call Calorie API directly from Android?
Not in production. Decompiled APKs expose embedded keys. Proxy through Firebase Cloud Functions or your own backend.
What barcode formats does Calorie API support?
Calorie API supports standard UPC and EAN barcodes for packaged food lookup via GET /search/barcode/{upc}.
Retrofit or Ktor for Android nutrition API?
Both work. Retrofit with Gson is widely documented. Ktor is lighter if you already use Kotlin coroutines throughout.
What if the barcode is not found?
Fall back to text search via the same nutrition API. Many user-generated barcodes fail on open databases but succeed on commercial food APIs like Calorie API.
