package com.example.jarvis
import android.Manifest
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Bundle
import android.speech.RecognizerIntent
import android.speech.tts.TextToSpeech
import android.widget.Button
import android.widget.TextView
import androidx.activity.ComponentActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
class MainActivity : ComponentActivity(), TextToSpeech.OnInitListener {
private lateinit var tts: TextToSpeech
private lateinit var status: TextView
private lateinit var answer: TextView
companion object {
private const val VOICE_REQUEST = 100
private const val MIC_PERMISSION = 101
/*
* IMPORTANT:
* Put your SECURE backend URL here.
*
* Example:
* https://your-server.example.com/ask
*
* Do NOT put an OpenAI/Gemini secret API key in this APK.
*/
private const val AI_BASE_URL =
"https://YOUR-BACKEND.example.com/ask"
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
status = findViewById(R.id.status)
answer = findViewById(R.id.answer)
val talkButton: Button =
findViewById(R.id.talkButton)
tts = TextToSpeech(this, this)
status.text = "JARVIS SYSTEM READY"
talkButton.setOnClickListener {
checkMicrophone()
}
}
private fun checkMicrophone() {
if (
ContextCompat.checkSelfPermission(
this,
Manifest.permission.RECORD_AUDIO
) != PackageManager.PERMISSION_GRANTED
) {
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.RECORD_AUDIO),
MIC_PERMISSION
)
} else {
startListening()
}
}
private fun startListening() {
try {
val intent =
Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH)
intent.putExtra(
RecognizerIntent.EXTRA_LANGUAGE_MODEL,
RecognizerIntent.LANGUAGE_MODEL_FREE_FORM
)
intent.putExtra(
RecognizerIntent.EXTRA_LANGUAGE,
Locale.getDefault()
)
intent.putExtra(
RecognizerIntent.EXTRA_PROMPT,
"Speak to Jarvis"
)
status.text = "🎙 LISTENING..."
startActivityForResult(
intent,
VOICE_REQUEST
)
} catch (e: Exception) {
status.text = "Voice recognition unavailable"
}
}
override fun onActivityResult(
requestCode: Int,
resultCode: Int,
data: Intent?
) {
super.onActivityResult(
requestCode,
resultCode,
data
)
if (
requestCode == VOICE_REQUEST &&
resultCode == RESULT_OK
) {
val results =
data?.getStringArrayListExtra(
RecognizerIntent.EXTRA_RESULTS
)
val command =
results?.firstOrNull()
if (!command.isNullOrBlank()) {
status.text = "YOU: $command"
processCommand(command.lowercase())
}
}
}
private fun processCommand(command: String) {
when {
// -------------------------
// GREETING
// -------------------------
command.contains("hello") ||
command.contains("hi") ||
command.contains("hey") ||
command.contains("jarvis") -> {
jarvisSpeak(
"Hello. I am Jarvis. How can I help you?"
)
}
// -------------------------
// TIME
// -------------------------
command.contains("time") ||
command.contains("samay") -> {
val time =
SimpleDateFormat(
"hh:mm a",
Locale.getDefault()
).format(Date())
jarvisSpeak(
"The current time is $time"
)
}
// -------------------------
// YOUTUBE
// -------------------------
command.contains("open youtube") ||
command.contains("youtube kholo") ||
command == "youtube" -> {
jarvisSpeak(
"Opening YouTube."
)
openUrl(
"https://www.youtube.com"
)
}
// -------------------------
// GOOGLE
// -------------------------
command.contains("open google") ||
command.contains("google kholo") ||
command == "google" -> {
jarvisSpeak(
"Opening Google."
)
openUrl(
"https://www.google.com"
)
}
// -------------------------
// SEARCH
// -------------------------
command.startsWith("search ") -> {
val query =
command.removePrefix("search ")
.trim()
googleSearch(query)
}
command.startsWith("search for ") -> {
val query =
command.removePrefix("search for ")
.trim()
googleSearch(query)
}
command.startsWith("google ") -> {
val query =
command.removePrefix("google ")
.trim()
googleSearch(query)
}
// -------------------------
// WEB
// -------------------------
command.contains("open browser") ||
command.contains("browser kholo") -> {
jarvisSpeak(
"Opening browser."
)
openUrl(
"https://www.google.com"
)
}
// -------------------------
// AI BRAIN
// -------------------------
else -> {
askAI(command)
}
}
}
private fun googleSearch(query: String) {
if (query.isBlank()) {
jarvisSpeak(
"What should I search for?"
)
return
}
jarvisSpeak(
"Searching for $query"
)
val url =
"https://www.google.com/search?q=" +
Uri.encode(query)
openUrl(url)
}
private fun openUrl(url: String) {
try {
val intent =
Intent(
Intent.ACTION_VIEW,
Uri.parse(url)
)
startActivity(intent)
} catch (e: Exception) {
jarvisSpeak(
"I could not open that."
)
}
}
/*
* AI BRAIN
*
* This is where your backend API will be called.
*
* For now we keep it disabled until your backend
* URL is added.
*/
private fun askAI(command: String) {
if (
AI_BASE_URL.contains("YOUR-BACKEND")
) {
jarvisSpeak(
"My AI brain is ready to connect. " +
"Please connect the secure AI backend first."
)
return
}
/*
* Backend integration goes here.
*
* Recommended request:
*
* POST /ask
*
* {
* "message": "user command"
* }
*
* Response:
*
* {
* "reply": "Jarvis response"
* }
*
* Do not put your secret AI key inside this app.
*/
}
private fun jarvisSpeak(text: String) {
status.text = "🤖 JARVIS"
answer.text = text
if (::tts.isInitialized) {
tts.speak(
text,
TextToSpeech.QUEUE_FLUSH,
null,
"JARVIS_RESPONSE"
)
}
}
override fun onInit(result: Int) {
if (result == TextToSpeech.SUCCESS) {
val languageResult =
tts.setLanguage(Locale.US)
if (
languageResult ==
TextToSpeech.LANG_MISSING_DATA ||
languageResult ==
TextToSpeech.LANG_NOT_SUPPORTED
) {
status.text =
"TTS language unavailable"
} else {
status.text =
"JARVIS SYSTEM READY"
}
}
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array