Local Ai

Android app talking to your own Ollama server: the five things that break first

I publish Android apps on Google Play as Hartmann Studios, and one of them (Ollama AI Chat, open source as chartmann1590/ollama-android-client) is an Ollama client. Here is what goes wrong first when

DGX agentreddit
local-air-ollama

I publish Android apps on Google Play as Hartmann Studios, and one of them (Ollama AI Chat, open source as chartmann1590/ollama-android-client) is an Ollama client. Here is what goes wrong first when an app talks to your own server, and the fix for each. Everything is from the Ollama docs, the Android docs and that app's code, checked this month. The server only listens on localhost Ollama binds 127.0.0.1:11434 by default. Two good options. Option A, bind to the network with a systemd override: sudo systemctl edit ollama.service # [Service] # Environment="OLLAMA_HOST=0.0.0.0:11434" sudo systemctl daemon-reload sudo systemctl restart ollama Option B, keep it on localhost and put Tailscale Serve in front: tailscale serve 11434 # prints something like https://ollama-box.your-tailnet.ts.net Option B gives you HTTPS with a real certificate, reachable only from your tailnet, and Ollama never listens on the LAN at all. Note that ts.net names show up in public Certificate Transparency logs. No auth on the API The API has no key. Anyone who can reach port 11434 can use your GPU and pull or delete models. Never forward that port on your router. LAN at home, Tailscale away from home. Android blocks plain http:// by default Since Android 9, cleartext HTTP is off for apps targeting a current API level. Pick the narrowest rule that works: Best: HTTPS through Tailscale Serve. No config needed. Good: a fixed known host, allowed in res/xml/network_security_config.xml: ollama.home.arpa and android:networkSecurityConfig="@xml/network_security_config" on the application tag. Only if users type any address: cleartext in base-config. The docs call this insecure. Say so in your privacy policy and nudge people toward a Serve URL. The stream is one JSON object per line /api/chat streams by default. Each line is a complete JSON object with message.content and "done": false. The last one has "done": true plus eval_count and eval_duration (nanoseconds). If something fails after the stream started, the error arrives as an object with an "error" field in the same stream and the HTTP status stays 200. Treat it as a failure anyway. The reading loop with OkHttp (5.5.0) and org.json, inside a callbackFlow: call.execute().use { r -> if (!r.isSuccessful) throw IOException("HTTP ${r.code}") val source = r.body.source() while (true) { val line = source.readUtf8Line() ?: break if (line.isBlank()) continue val obj = JSONObject(line) if (obj.has("error")) throw IOException(obj.getString("error")) val piece = obj.optJSONObject("message")?.optString("content").orEmpty() if (piece.isNotEmpty()) send(piece) if (obj.optBoolean("done")) break } } // awaitClose { call.cancel() } so Stop actually stops the server generating /api/chat is stateless, so the whole messages array goes with every request. The first token is slow and the client gives up Loading a model into GPU memory before the first token can take a while. OkHttp's default read timeout is too short. Build a per-request client with a user-settable timeout: val client = okHttpClient.newBuilder() .connectTimeout(timeoutSecs, TimeUnit.SECONDS) .readTimeout(timeoutSecs, TimeUnit.SECONDS) .writeTimeout(timeoutSecs, TimeUnit.SECONDS) .build() keep_alive defaults to five minutes, so the next message starts fast. Change it per request with the keep_alive field or server-wide with OLLAMA_KEEP_ALIVE. Bonus: normalize what users type. People enter 192.168.1.5:11434, http://box:11434/, or paste http://box:11434/api/tags from a tutorial. Add http:// when the scheme is missing, strip a pasted /api/... path back to the root, and end with a slash. Otherwise the client ends up requesting /api/api/tags. Prove the server works with curl http://host:11434/api/tags before writing any Kotlin. If that fails, no Android code will succeed. submitted by /u/Objective-Art-3268 [link] [comments]

Related

Source: r/ollama | 2026-10-17

Loading related sources…