Skip to content
31 changes: 27 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,19 @@ when (val result = ShortioSdk.shortenUrl(apiKey, params)) {
}
}
```

### 🔐 Secure Short Link

If you want to encrypt the original URL, the SDK provides a `createSecure` function that uses AES-GCM encryption.

```kotlin
val originalURL = "your_original_URL"
val result = ShortioSdk.createSecure(originalURL)
Log.d("SecureURL", "RESULT: ${result}")
Log.d("securedOriginalURL", "URL: ${result.securedOriginalURL}")
Log.d("securedShortUrl", "URL: ${result.securedShortUrl}")
```

## 🤖 Deep Linking Setup
To handle deep links via Short.io on Android, you'll need to set up Android App Links properly using your domain's Digital Asset Links and intent filters.

Expand Down Expand Up @@ -158,20 +171,30 @@ keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -sto
2. Override the onNewIntent() method to receive new intents when the activity is already running:

```kotlin
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.launch

override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
val result = ShortioSdk.handleIntent(intent)
Log.d("New Intent", "Host: ${result?.host}, Path: ${result?.path}")
lifecycleScope.launch {
val result = ShortioSdk.handleIntent(intent)
Log.d("New Intent", "Host: ${result?.host}, Path: ${result?.path}")
}
}
```
3. In the same activity, you can also handle the initial intent inside the `onCreate()` method:

```kotlin
// Optional
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.launch

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val result = ShortioSdk.handleIntent(intent)
Log.d("New Intent", "Host: ${result?.host}, Path: ${result?.path}")
lifecycleScope.launch {
val result = ShortioSdk.handleIntent(intent)
Log.d("New Intent", "Host: ${result?.host}, Path: ${result?.path}")
}
}
```

Expand Down
2 changes: 1 addition & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ dependencies {
implementation(libs.androidx.ui.graphics)
implementation(libs.androidx.ui.tooling.preview)
implementation(libs.androidx.material3)
implementation("com.github.Short-io:android-sdk:v1.0.5")
implementation("com.github.Short-io:android-sdk:v1.0.6")
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
Expand Down
90 changes: 88 additions & 2 deletions app/src/main/java/com/github/shortioapp/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.widget.Toast
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.launch


class MainActivity : ComponentActivity() {
Expand All @@ -59,6 +61,9 @@ class MainActivity : ComponentActivity() {

Spacer(modifier = Modifier.height(16.dp))
LinkShorteningButton(apiKey = apiKey)

Spacer(modifier = Modifier.height(16.dp))
CreateSecureUrlButton()
}
}
}
Expand All @@ -67,8 +72,10 @@ class MainActivity : ComponentActivity() {

override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
val response = ShortioSdk.handleIntent(intent)
Log.d("New Intent", "Host: ${response?.host}, Path: ${response?.path}")
lifecycleScope.launch {
val result = ShortioSdk.handleIntent(intent)
Log.d("New Intent", "Host: ${result?.host}, Path: ${result?.path}")
}
}
}

Expand Down Expand Up @@ -171,6 +178,85 @@ fun LinkShorteningButton(apiKey: String) {
}
}

@Composable
fun CreateSecureUrlButton() {
var resultMessage by remember { mutableStateOf<String?>(null) }
var isLoading by remember { mutableStateOf(false) }
val context = LocalContext.current

Column(horizontalAlignment = Alignment.CenterHorizontally) {
Button(
onClick = {
isLoading = true
thread {
try {
val originalUrl = "https://{your_domain}"
val result = ShortioSdk.createSecure(originalUrl)

Log.d("SecureURL", "RESULT: $result")
Log.d("SecureURL", "URL: ${result.securedOriginalURL}")
Log.d("SecureURL", "KEY: ${result.securedShortUrl}")

(context as ComponentActivity).runOnUiThread {
isLoading = false
resultMessage = "Secure URL: ${result.securedShortUrl}"
}
} catch (e: Exception) {
Log.e("SecureURL", "Exception: ${e.message}", e)
(context as ComponentActivity).runOnUiThread {
isLoading = false
resultMessage = "Error: ${e.message}"
}
}
}
},
enabled = !isLoading
) {
Text(text = if (isLoading) "Generating..." else "Create Secure Short Link")
}

if (isLoading) {
Spacer(modifier = Modifier.height(16.dp))
CircularProgressIndicator()
}

resultMessage?.let {
Spacer(modifier = Modifier.height(16.dp))
if (it.startsWith("Error")) {
Text(
text = it,
fontSize = 16.sp,
color = Color.Red,
modifier = Modifier.padding(horizontal = 8.dp)
)
} else {
val secureUrl = it.substringAfter("Secure URL:").trim()

Text(
text = secureUrl,
fontSize = 16.sp,
color = Color(0xFF4CAF50),
modifier = Modifier.padding(horizontal = 8.dp)
)

Spacer(modifier = Modifier.height(8.dp))

Button(
onClick = {
val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
val clip = ClipData.newPlainText("secureURL", secureUrl)
clipboard.setPrimaryClip(clip)
Toast.makeText(context, "Secure URL copied to clipboard", Toast.LENGTH_SHORT).show()
}
) {
Text("Copy Secure URL")
}
}
}
}
}



@Composable
fun LinkShortnerTitle() {
Expand Down