first compiled APK build
This commit is contained in:
parent
beffbef0d1
commit
ed6ced7a30
12 changed files with 330 additions and 40 deletions
123
.idea/codeStyles/Project.xml
Normal file
123
.idea/codeStyles/Project.xml
Normal 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>
|
5
.idea/codeStyles/codeStyleConfig.xml
Normal file
5
.idea/codeStyles/codeStyleConfig.xml
Normal 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
6
.idea/compiler.xml
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<bytecodeTargetLevel target="21" />
|
||||
</component>
|
||||
</project>
|
10
.idea/deploymentTargetSelector.xml
Normal file
10
.idea/deploymentTargetSelector.xml
Normal 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
6
.idea/kotlinc.xml
Normal 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
6
.idea/vcs.xml
Normal 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>
|
|
@ -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)
|
||||
|
|
|
@ -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" />
|
||||
|
|
|
@ -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)
|
||||
|
||||
@Composable
|
||||
fun Greeting(name: String, modifier: Modifier = Modifier) {
|
||||
Text(
|
||||
text = "Hello $name!",
|
||||
modifier = modifier
|
||||
)
|
||||
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()
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
fun GreetingPreview() {
|
||||
MealieURLShareTheme {
|
||||
Greeting("Android")
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
}
|
30
app/src/main/res/layout/activity_main.xml
Normal file
30
app/src/main/res/layout/activity_main.xml
Normal 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>
|
||||
|
|
@ -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" }
|
||||
|
|
Loading…
Reference in a new issue