first compiled APK build

This commit is contained in:
Sean 2024-12-19 08:03:03 -05:00
parent beffbef0d1
commit ed6ced7a30
12 changed files with 330 additions and 40 deletions

View file

@ -0,0 +1,123 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<JetCodeStyleSettings>
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</JetCodeStyleSettings>
<codeStyleSettings language="XML">
<option name="FORCE_REARRANGE_MODE" value="1" />
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
</indentOptions>
<arrangement>
<rules>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:android</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:id</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>style</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>ANDROID_ATTRIBUTE_ORDER</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>.*</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
</rules>
</arrangement>
</codeStyleSettings>
<codeStyleSettings language="kotlin">
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</codeStyleSettings>
</code_scheme>
</component>

View file

@ -0,0 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</state>
</component>

6
.idea/compiler.xml Normal file
View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="21" />
</component>
</project>

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="deploymentTargetSelector">
<selectionStates>
<SelectionState runConfigName="app">
<option name="selectionMode" value="DROPDOWN" />
</SelectionState>
</selectionStates>
</component>
</project>

6
.idea/kotlinc.xml Normal file
View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="KotlinJpsPluginSettings">
<option name="version" value="2.0.0" />
</component>
</project>

6
.idea/vcs.xml Normal file
View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View file

@ -36,11 +36,14 @@ android {
}
buildFeatures {
compose = true
viewBinding = true
}
}
dependencies {
implementation("com.squareup.okhttp3:okhttp:4.9.3")
implementation(libs.okhttp)
implementation(libs.kotlin.stdlib)
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.lifecycle.runtime.ktx)
implementation(libs.androidx.activity.compose)
@ -49,6 +52,7 @@ dependencies {
implementation(libs.androidx.ui.graphics)
implementation(libs.androidx.ui.tooling.preview)
implementation(libs.androidx.material3)
implementation(libs.androidx.appcompat)
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)

View file

@ -2,6 +2,10 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
@ -15,7 +19,6 @@
<activity
android:name=".MainActivity"
android:exported="true"
android:label="@string/app_name"
android:theme="@style/Theme.MealieURLShare">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
@ -23,7 +26,7 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".ShareActivity">
<activity android:name=".ShareActivity" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />

View file

@ -1,47 +1,31 @@
package org.seanandroid.mealieurlshare
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import org.seanandroid.mealieurlshare.ui.theme.MealieURLShareTheme
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import org.seanandroid.mealieurlshare.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
MealieURLShareTheme {
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
Greeting(
name = "Android",
modifier = Modifier.padding(innerPadding)
)
}
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.saveButton.setOnClickListener {
val url = binding.urlEditText.text.toString()
val token = binding.tokenEditText.text.toString()
// Save URL and TOKEN in SharedPreferences
val sharedPreferences = getSharedPreferences("app_prefs", MODE_PRIVATE)
with(sharedPreferences.edit()) {
putString("url", url)
putString("token", token)
apply()
}
// Show a Toast message to confirm saving
Toast.makeText(this, "URL and TOKEN saved", Toast.LENGTH_SHORT).show()
}
}
}
@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
Text(
text = "Hello $name!",
modifier = modifier
)
}
@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
MealieURLShareTheme {
Greeting("Android")
}
}

View file

@ -0,0 +1,109 @@
package org.seanandroid.mealieurlshare
import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Intent
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.NotificationCompat
import okhttp3.Call
import okhttp3.Callback
import okhttp3.FormBody
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import java.io.IOException
class ShareActivity : AppCompatActivity() {
private val client = OkHttpClient()
private lateinit var handler: Handler
private var isRequestRunning = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Get the shared preferences
val sharedPreferences = getSharedPreferences("app_prefs", MODE_PRIVATE)
val url = sharedPreferences.getString("url", null)
val token = sharedPreferences.getString("token", null)
// Get the shared text
val sharedText = intent.getStringExtra(Intent.EXTRA_TEXT)
if (url != null && token != null && sharedText != null) {
sendPostRequest(url, token, sharedText)
} else {
Toast.makeText(this, "URL or TOKEN not set", Toast.LENGTH_SHORT).show()
finish()
}
}
private fun sendPostRequest(url: String, token: String, sharedText: String) {
isRequestRunning = true
val fullUrl = "$url/api/recipe/create/url"
val requestBody = FormBody.Builder()
.add("data", sharedText)
.build()
val request = Request.Builder()
.url(fullUrl)
.addHeader("Authorization", "Bearer $token")
.post(requestBody)
.build()
handler = Handler(Looper.getMainLooper())
handler.postDelayed({
if (isRequestRunning) {
isRequestRunning = false
sendNotification("Request timed out")
finish()
}
}, 30000) // 30 seconds timeout
client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
isRequestRunning = false
sendNotification("Request failed: ${e.message}")
finish()
}
override fun onResponse(call: Call, response: Response) {
isRequestRunning = false
if (response.isSuccessful) {
sendNotification("Request successful!")
} else {
sendNotification("Request failed: ${response.message}")
}
finish()
}
})
}
private fun sendNotification(message: String) {
val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
val channelId = "mealie_url_share_channel"
// Create the notification channel for Android O and above
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
val channel = NotificationChannel(
channelId,
"Mealie URL Share Notifications",
NotificationManager.IMPORTANCE_DEFAULT
)
notificationManager.createNotificationChannel(channel)
}
val notification = NotificationCompat.Builder(this, channelId)
.setContentTitle("Mealie URL Share")
.setContentText(message)
//.setSmallIcon(R.drawable.ic_notification) // Replace with your notification icon
.setAutoCancel(true)
.build()
notificationManager.notify(1, notification)
}
}

View file

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<EditText
android:id="@+id/urlEditText"
android:layout_width="337dp"
android:layout_height="85dp"
android:autofillHints="0"
android:baselineAligned="false"
android:hint="Enter URL"
android:inputType="textUri" />
<EditText
android:id="@+id/tokenEditText"
android:layout_width="337dp"
android:layout_height="80dp"
android:hint="Enter TOKEN"
android:inputType="textPassword" />
<Button
android:id="@+id/saveButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Save" />
</LinearLayout>

View file

@ -8,6 +8,7 @@ espressoCore = "3.5.1"
lifecycleRuntimeKtx = "2.6.1"
activityCompose = "1.8.0"
composeBom = "2024.04.01"
appcompat = "1.7.0"
[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
@ -24,6 +25,9 @@ androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-toolin
androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
androidx-material3 = { group = "androidx.compose.material3", name = "material3" }
androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
kotlin-stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib" }
okhttp = { module = "com.squareup.okhttp3:okhttp" }
[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }