ai-chat-android-auto / commit
Rename project to AI Chat for Android Auto
README.md | 13 ++++++-------
app/build.gradle.kts | 4 ++--
app/src/main/AndroidManifest.xml | 4 ++--
.../ClaudeMediaService.kt => aichat/AiChatMediaService.kt} | 12 ++++++------
.../net/fuzzyworld/{claudeauto => aichat}/AiProvider.kt | 2 +-
.../fuzzyworld/{claudeauto => aichat}/AnthropicProvider.kt | 2 +-
.../net/fuzzyworld/{claudeauto => aichat}/GeminiProvider.kt | 2 +-
.../{claudeauto => aichat}/OpenAiCompatibleProvider.kt | 2 +-
.../java/net/fuzzyworld/{claudeauto => aichat}/Prefs.kt | 2 +-
.../fuzzyworld/{claudeauto => aichat}/ProviderRegistry.kt | 2 +-
.../net/fuzzyworld/{claudeauto => aichat}/SetupActivity.kt | 2 +-
app/src/main/res/layout/activity_setup.xml | 2 +-
app/src/main/res/values/strings.xml | 2 +-
app/src/main/res/values/themes.xml | 2 +-
settings.gradle.kts | 2 +-
15 files changed, 27 insertions(+), 28 deletions(-)
diff --git a/README.md b/README.md
index d1a8e27..db76544 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# AI Auto
+# AI Chat for Android Auto
An Android Auto voice assistant that sends your spoken questions to an AI provider and reads the responses back through the car's speakers.
@@ -8,7 +8,7 @@ You choose the provider — Anthropic, OpenAI, Groq, Mistral, Google Gemini, or
## How it works
-1. Open the **AI Auto** app on your phone and configure a provider + API key.
+1. Open the **AI Chat for Android Auto** app on your phone and configure a provider + API key.
2. Connect your phone to the car. The app appears in the Android Auto launcher.
3. Tap **Ask AI** (or press Play on the steering wheel) and speak your question.
4. The app sends your question to the provider's API and reads the answer aloud.
@@ -24,7 +24,7 @@ You choose the provider — Anthropic, OpenAI, Groq, Mistral, Google Gemini, or
### Phone setup
1. Install the APK (sideload or Play Store release).
-2. Open **AI Auto** on your phone.
+2. Open **AI Chat for Android Auto** on your phone.
3. Select a provider, enter your API key, and tap **Save Key**.
4. Tap **↻** to fetch available models and select one.
5. Grant microphone permission when prompted.
@@ -56,7 +56,7 @@ adb shell settings put global android_auto_unknown_sources 1
### OpenAI-compatible API (5 lines)
-Add an object to [OpenAiCompatibleProvider.kt](app/src/main/java/net/fuzzyworld/claudeauto/OpenAiCompatibleProvider.kt):
+Add an object to [OpenAiCompatibleProvider.kt](app/src/main/java/net/fuzzyworld/aichat/OpenAiCompatibleProvider.kt):
```kotlin
object MyProvider : OpenAiCompatibleProvider() {
@@ -68,11 +68,11 @@ object MyProvider : OpenAiCompatibleProvider() {
}
```
-Then add `MyProvider` to the list in [ProviderRegistry.kt](app/src/main/java/net/fuzzyworld/claudeauto/ProviderRegistry.kt).
+Then add `MyProvider` to the list in [ProviderRegistry.kt](app/src/main/java/net/fuzzyworld/aichat/ProviderRegistry.kt).
### Unique API format
-Implement the `AiProvider` interface directly (see [GeminiProvider.kt](app/src/main/java/net/fuzzyworld/claudeauto/GeminiProvider.kt) as an example), then register it in `ProviderRegistry`.
+Implement the `AiProvider` interface directly (see [GeminiProvider.kt](app/src/main/java/net/fuzzyworld/aichat/GeminiProvider.kt) as an example), then register it in `ProviderRegistry`.
The interface requires two methods:
- `ask(apiKey, baseUrl, model, question, onResult)` — call the API and return the text response
@@ -93,7 +93,6 @@ Signing credentials go in `local.properties` (gitignored). See `local.properties
## Upcoming work
-- **App rename / rebrand** — the app is currently labelled "Claude Auto" in places; needs a provider-neutral name for the open-source release
- **Persist conversation history across sessions** — current history is in-memory only and lost when the service stops
- **Per-provider system prompt customization** — let users adjust the assistant's persona and instructions
- **Streaming response support** — start speaking the first sentence while the rest of the response is still arriving, reducing perceived latency
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 84ec9b4..a21e8d7 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -11,11 +11,11 @@ val localProps = Properties().apply {
}
android {
- namespace = "net.fuzzyworld.claudeauto"
+ namespace = "net.fuzzyworld.aichat"
compileSdk = 34
defaultConfig {
- applicationId = "net.fuzzyworld.claudeauto"
+ applicationId = "net.fuzzyworld.aichat"
minSdk = 23
targetSdk = 34
versionCode = 2
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index aacde4a..5bb18c8 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -18,7 +18,7 @@
android:resource="@xml/automotive_app_desc" />
<service
- android:name=".ClaudeMediaService"
+ android:name=".AiChatMediaService"
android:exported="true"
android:foregroundServiceType="mediaPlayback">
<intent-filter>
@@ -30,7 +30,7 @@
android:name=".SetupActivity"
android:exported="true"
android:label="@string/app_name"
- android:theme="@style/Theme.ClaudeAuto">
+ android:theme="@style/Theme.AiChat">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
diff --git a/app/src/main/java/net/fuzzyworld/claudeauto/ClaudeMediaService.kt b/app/src/main/java/net/fuzzyworld/aichat/AiChatMediaService.kt
similarity index 97%
rename from app/src/main/java/net/fuzzyworld/claudeauto/ClaudeMediaService.kt
rename to app/src/main/java/net/fuzzyworld/aichat/AiChatMediaService.kt
index 12d82dc..7eaba2d 100644
--- a/app/src/main/java/net/fuzzyworld/claudeauto/ClaudeMediaService.kt
+++ b/app/src/main/java/net/fuzzyworld/aichat/AiChatMediaService.kt
@@ -1,4 +1,4 @@
-package net.fuzzyworld.claudeauto
+package net.fuzzyworld.aichat
import android.content.Intent
import android.media.AudioAttributes
@@ -21,7 +21,7 @@ import android.support.v4.media.session.PlaybackStateCompat
import androidx.media.MediaBrowserServiceCompat
import java.util.Locale
-class ClaudeMediaService : MediaBrowserServiceCompat(), TextToSpeech.OnInitListener {
+class AiChatMediaService : MediaBrowserServiceCompat(), TextToSpeech.OnInitListener {
data class HistoryEntry(val question: String, val answer: String)
@@ -52,7 +52,7 @@ class ClaudeMediaService : MediaBrowserServiceCompat(), TextToSpeech.OnInitListe
super.onCreate()
audioManager = getSystemService(AUDIO_SERVICE) as AudioManager
tts = TextToSpeech(this, this)
- mediaSession = MediaSessionCompat(this, "ClaudeAuto").apply {
+ mediaSession = MediaSessionCompat(this, "AiChat").apply {
setCallback(sessionCallback)
setFlags(
MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS or
@@ -213,7 +213,7 @@ class ClaudeMediaService : MediaBrowserServiceCompat(), TextToSpeech.OnInitListe
pushState(State.LISTENING)
mainHandler.post {
recognizer?.destroy()
- recognizer = SpeechRecognizer.createSpeechRecognizer(this@ClaudeMediaService).apply {
+ recognizer = SpeechRecognizer.createSpeechRecognizer(this@AiChatMediaService).apply {
setRecognitionListener(recognitionListener)
startListening(Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH).apply {
putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM)
@@ -236,7 +236,7 @@ class ClaudeMediaService : MediaBrowserServiceCompat(), TextToSpeech.OnInitListe
SpeechRecognizer.ERROR_NETWORK,
SpeechRecognizer.ERROR_NETWORK_TIMEOUT -> "Network error. Check your connection."
SpeechRecognizer.ERROR_INSUFFICIENT_PERMISSIONS ->
- "Microphone permission required. Open Claude Auto on your phone."
+ "Microphone permission required. Open AI Chat for Android Auto on your phone."
else -> "Couldn't hear you — please try again."
}
mainHandler.post { releaseAudioFocus(); speak(msg) }
@@ -307,7 +307,7 @@ class ClaudeMediaService : MediaBrowserServiceCompat(), TextToSpeech.OnInitListe
MediaMetadataCompat.Builder()
.putString(MediaMetadataCompat.METADATA_KEY_TITLE, title)
.putString(MediaMetadataCompat.METADATA_KEY_ARTIST, subtitle)
- .putString(MediaMetadataCompat.METADATA_KEY_ALBUM, "AI Auto")
+ .putString(MediaMetadataCompat.METADATA_KEY_ALBUM, "AI Chat for Android Auto")
.putString(MediaMetadataCompat.METADATA_KEY_DISPLAY_DESCRIPTION, subtitle)
.build()
)
diff --git a/app/src/main/java/net/fuzzyworld/claudeauto/AiProvider.kt b/app/src/main/java/net/fuzzyworld/aichat/AiProvider.kt
similarity index 96%
rename from app/src/main/java/net/fuzzyworld/claudeauto/AiProvider.kt
rename to app/src/main/java/net/fuzzyworld/aichat/AiProvider.kt
index 33befd8..7f861dc 100644
--- a/app/src/main/java/net/fuzzyworld/claudeauto/AiProvider.kt
+++ b/app/src/main/java/net/fuzzyworld/aichat/AiProvider.kt
@@ -1,4 +1,4 @@
-package net.fuzzyworld.claudeauto
+package net.fuzzyworld.aichat
import okhttp3.OkHttpClient
import java.util.concurrent.TimeUnit
diff --git a/app/src/main/java/net/fuzzyworld/claudeauto/AnthropicProvider.kt b/app/src/main/java/net/fuzzyworld/aichat/AnthropicProvider.kt
similarity index 99%
rename from app/src/main/java/net/fuzzyworld/claudeauto/AnthropicProvider.kt
rename to app/src/main/java/net/fuzzyworld/aichat/AnthropicProvider.kt
index 9ce2be2..50599a4 100644
--- a/app/src/main/java/net/fuzzyworld/claudeauto/AnthropicProvider.kt
+++ b/app/src/main/java/net/fuzzyworld/aichat/AnthropicProvider.kt
@@ -1,4 +1,4 @@
-package net.fuzzyworld.claudeauto
+package net.fuzzyworld.aichat
import okhttp3.Call
import okhttp3.Callback
diff --git a/app/src/main/java/net/fuzzyworld/claudeauto/GeminiProvider.kt b/app/src/main/java/net/fuzzyworld/aichat/GeminiProvider.kt
similarity index 99%
rename from app/src/main/java/net/fuzzyworld/claudeauto/GeminiProvider.kt
rename to app/src/main/java/net/fuzzyworld/aichat/GeminiProvider.kt
index b33c0a1..24931d1 100644
--- a/app/src/main/java/net/fuzzyworld/claudeauto/GeminiProvider.kt
+++ b/app/src/main/java/net/fuzzyworld/aichat/GeminiProvider.kt
@@ -1,4 +1,4 @@
-package net.fuzzyworld.claudeauto
+package net.fuzzyworld.aichat
import okhttp3.Call
import okhttp3.Callback
diff --git a/app/src/main/java/net/fuzzyworld/claudeauto/OpenAiCompatibleProvider.kt b/app/src/main/java/net/fuzzyworld/aichat/OpenAiCompatibleProvider.kt
similarity index 99%
rename from app/src/main/java/net/fuzzyworld/claudeauto/OpenAiCompatibleProvider.kt
rename to app/src/main/java/net/fuzzyworld/aichat/OpenAiCompatibleProvider.kt
index 2ee0eb5..805cfe9 100644
--- a/app/src/main/java/net/fuzzyworld/claudeauto/OpenAiCompatibleProvider.kt
+++ b/app/src/main/java/net/fuzzyworld/aichat/OpenAiCompatibleProvider.kt
@@ -1,4 +1,4 @@
-package net.fuzzyworld.claudeauto
+package net.fuzzyworld.aichat
import okhttp3.Call
import okhttp3.Callback
diff --git a/app/src/main/java/net/fuzzyworld/claudeauto/Prefs.kt b/app/src/main/java/net/fuzzyworld/aichat/Prefs.kt
similarity index 99%
rename from app/src/main/java/net/fuzzyworld/claudeauto/Prefs.kt
rename to app/src/main/java/net/fuzzyworld/aichat/Prefs.kt
index 8b9fc09..e3fe60e 100644
--- a/app/src/main/java/net/fuzzyworld/claudeauto/Prefs.kt
+++ b/app/src/main/java/net/fuzzyworld/aichat/Prefs.kt
@@ -1,4 +1,4 @@
-package net.fuzzyworld.claudeauto
+package net.fuzzyworld.aichat
import android.content.Context
import android.content.SharedPreferences
diff --git a/app/src/main/java/net/fuzzyworld/claudeauto/ProviderRegistry.kt b/app/src/main/java/net/fuzzyworld/aichat/ProviderRegistry.kt
similarity index 95%
rename from app/src/main/java/net/fuzzyworld/claudeauto/ProviderRegistry.kt
rename to app/src/main/java/net/fuzzyworld/aichat/ProviderRegistry.kt
index 25cb31e..f8cd651 100644
--- a/app/src/main/java/net/fuzzyworld/claudeauto/ProviderRegistry.kt
+++ b/app/src/main/java/net/fuzzyworld/aichat/ProviderRegistry.kt
@@ -1,4 +1,4 @@
-package net.fuzzyworld.claudeauto
+package net.fuzzyworld.aichat
internal const val SYSTEM_PROMPT =
"You are a voice assistant in a car. Be concise and conversational — " +
diff --git a/app/src/main/java/net/fuzzyworld/claudeauto/SetupActivity.kt b/app/src/main/java/net/fuzzyworld/aichat/SetupActivity.kt
similarity index 99%
rename from app/src/main/java/net/fuzzyworld/claudeauto/SetupActivity.kt
rename to app/src/main/java/net/fuzzyworld/aichat/SetupActivity.kt
index eadcc8b..0b408ac 100644
--- a/app/src/main/java/net/fuzzyworld/claudeauto/SetupActivity.kt
+++ b/app/src/main/java/net/fuzzyworld/aichat/SetupActivity.kt
@@ -1,4 +1,4 @@
-package net.fuzzyworld.claudeauto
+package net.fuzzyworld.aichat
import android.Manifest
import android.content.pm.PackageManager
diff --git a/app/src/main/res/layout/activity_setup.xml b/app/src/main/res/layout/activity_setup.xml
index 30eb390..4e514d0 100644
--- a/app/src/main/res/layout/activity_setup.xml
+++ b/app/src/main/res/layout/activity_setup.xml
@@ -12,7 +12,7 @@
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:text="AI Auto"
+ android:text="AI Chat for Android Auto"
android:textSize="26sp"
android:textStyle="bold"
android:layout_marginBottom="4dp" />
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index dfdf895..0a82d57 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
- <string name="app_name">Claude Auto</string>
+ <string name="app_name">AI Chat for Android Auto</string>
</resources>
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
index 9bac402..e45df9f 100644
--- a/app/src/main/res/values/themes.xml
+++ b/app/src/main/res/values/themes.xml
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
- <style name="Theme.ClaudeAuto" parent="Theme.AppCompat.Light.NoActionBar" />
+ <style name="Theme.AiChat" parent="Theme.AppCompat.Light.NoActionBar" />
</resources>
diff --git a/settings.gradle.kts b/settings.gradle.kts
index e42f235..7ab4ccb 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -13,5 +13,5 @@ dependencyResolutionManagement {
}
}
-rootProject.name = "ClaudeAuto"
+rootProject.name = "AiChatAndroidAuto"
include(":app")