๐Ÿค– Android AI and Generative AI

Add AI-Powered Text Summarization to an Android App

Long articles, chat threads and meeting notes are where users most want a quick summary. This guide shows how to add summarization to an Android app: on-device for short private text, cloud for long documents, chunking strategies, streaming UI and accuracy safeguards.

โœ๏ธ Yunok Tech ๐Ÿ“… Updated โฑ 3 min read ๐ŸŽฏ Intermediate
On this page
  1. Choose the engine by input size and sensitivity
  2. On-device summarization
  3. Cloud summarization with a structured prompt
  4. Chunking long text (map-reduce)
  5. Streaming UI and trust
  6. Caching and cost
  7. Use cases
  8. Accuracy pitfalls
  9. Frequently asked questions
  10. Conclusion

A good summary saves time. A bad one misleads, which is worse than no summary. Summarization quality depends on three things: choosing the right model for the input length, structuring long inputs sensibly, and making it easy for users to check the source.

Choose the engine by input size and sensitivity

InputEngineWhy
Short, private text (notes, chats) in a supported languageML Kit Summarization (Gemini Nano)On-device, free per request, offline
Long documents (reports, PDFs)Cloud Gemini (long context)Large context windows, better reasoning
Very long or many documentsChunk + map-reduce, or a backend pipelineBounded cost and latency per call
Map-reduce summarization of a long document A long document is split into chunks at paragraph boundaries. Each chunk is summarized in parallel in the map step. The partial summaries are combined and summarized again in the reduce step to produce the final summary. Document40 pages chunk 1chunk 2chunk n summary 1summary 2summary n Final summaryreduce step
Map-reduce keeps each request small. With long-context models you may not need it, but it's the fallback when inputs exceed limits or budgets.

On-device summarization

For short text, the ML Kit Summarization API is the simplest option. See the full lifecycle (status check, download, streaming) in Gemini Nano and ML Kit GenAI. Remember its documented constraints: input under roughly 4,000 tokens, a few supported languages, foreground-only use and supported devices.

Cloud summarization with a structured prompt

CloudSummarizer.ktKotlin
class CloudSummarizer {
    private val model = Firebase.ai(backend = GenerativeBackend.googleAI()).generativeModel(
        modelName = "gemini-3.8-flash",             // check current model names
        generationConfig = generationConfig { temperature = 0.2f; maxOutputTokens = 600 },
        systemInstruction = content {
            text(
                "Summarize the provided document faithfully. Use only information in the document. " +
                "If something is unclear, say so. Output 3-5 bullet points, then one line 'Action items:' if any."
            )
        },
    )

    fun summarizeStream(document: String): Flow<String> =
        model.generateContentStream("<document>\n$document\n</document>").mapNotNull { it.text }

    suspend fun summarize(text: String): String = model.generateContent("<document>\n$text\n</document>").text.orEmpty()
}

Chunking long text (map-reduce)

MapReduceSummarizer.ktKotlin
class MapReduceSummarizer(private val summarizer: CloudSummarizer) {

    /** Split at paragraph boundaries into chunks of at most [maxChars]. */
    fun chunk(text: String, maxChars: Int = 12_000): List<String> {
        val chunks = mutableListOf<String>()
        val current = StringBuilder()
        text.split("\n\n").forEach { paragraph ->
            if (current.length + paragraph.length > maxChars && current.isNotEmpty()) {
                chunks += current.toString(); current.clear()
            }
            current.append(paragraph).append("\n\n")
        }
        if (current.isNotBlank()) chunks += current.toString()
        return chunks
    }

    suspend fun summarize(text: String): String = coroutineScope {
        val parts = chunk(text)
        if (parts.size == 1) return@coroutineScope summarizer.summarize(parts.single())
        val partials = parts
            .chunked(4)                                          // limit parallelism (rate limits)
            .flatMap { batch -> batch.map { async { summarizer.summarize(it) } }.awaitAll() }
        summarizer.summarize(partials.joinToString("\n\n"))      // reduce step
    }
}

Character counts are only a rough proxy for tokens. If you need exact limits, use the SDK's token-counting API. Very large paragraphs may also need splitting.

Streaming UI and trust

SummaryPanel.ktKotlin
@Composable
fun SummaryPanel(summary: String, isStreaming: Boolean, onViewSource: () -> Unit) {
    Card(Modifier.fillMaxWidth()) {
        Column(Modifier.padding(16.dp)) {
            Text("AI summary", style = MaterialTheme.typography.titleSmall)
            Text(summary, Modifier.padding(vertical = 8.dp))
            if (isStreaming) LinearProgressIndicator(Modifier.fillMaxWidth())
            Text("Summaries can miss or misstate details.", style = MaterialTheme.typography.labelSmall)
            TextButton(onClick = onViewSource) { Text("Read the full text") }
        }
    }
}

Caching and cost

  • Cache summaries keyed by a content hash plus prompt version, so the same document isn't summarized twice.
  • Summarize on demand (button), not automatically for every item.
  • Limit output length and choose a fast model tier for short inputs. See Tokens, Latency and Cost.

Use cases

Chat catch-up

"Summarise the last 200 messages" on-device for privacy, where supported.

Long reports

Cloud summarization with action items, streamed as it generates.

Reading list

Cached TL;DRs for saved articles, generated when the user taps "Summarise".

Accuracy pitfalls

  • Summaries can omit critical caveats. Offer "read full text" and avoid summaries for legal or medical decisions.
  • Models may add plausible but absent facts. Instruct "use only the document", keep temperature low, and evaluate with real samples.
  • Map-reduce can lose cross-chunk context. Use overlap, or long-context models when possible.

Frequently asked questions

Can I summarize PDFs?

Extract text first (on-device PDF text extraction or a backend), or send the PDF to a multimodal cloud model that accepts documents. See AI Document Summarizer.

How do I support Hindi and other languages?

Check language support per engine. Cloud models generally support more languages than current on-device summarization.

Should I store summaries?

Caching improves cost and speed, but treat summaries as derived personal data, and delete them with the source.

Conclusion

Route summarization by length and sensitivity: on-device for short private text, cloud long-context models for big documents, and map-reduce when inputs exceed limits. Stream results, label them as AI-generated, link back to the source, and cache to control cost.

Next step: summarize images instead of text with Image Understanding and Description.

Official references

๐Ÿ“ฑ Apps built by Yunok Tech

Real Android apps on Google Play, free to download.

See all our apps โ†’

Ready to build real Android applications?

Every AI feature still runs inside an Android app that has to be fast, reliable and well structured. Strengthen the Kotlin, Jetpack Compose and architecture skills that AI integrations depend on, then apply these AI concepts with confidence.

Move beyond theory and strengthen your Android development skills with Yunoktech's Android course. Learn core concepts, practical implementation, modern Android development techniques, and the reasoning behind building maintainable applications.

Explore the Android course and take your next step as an Android developer.

Share: LinkedIn X / Twitter WhatsApp