Blog Infos
Author
Published
Topics
Published
Topics

 

If you think your app is doing some useful work that might be useful to other apps. Then other apps can ask for results or open your app activity which does useful stuff for that particular app.

I will explain this by taking an example.

I have developed an app that can set reminders based on time, date, and reminder type and at that time you will get a notification with a title and description. So, this functionality might help other apps to set reminders on their behalf.

Here is the GitHub link for RemindMe app and switch to feature-other-apps branch.

I will not explain how I developed this app. My main focus is on how other apps can use this functionality.

Let’s start working on it.

  1. Clone the RemindMe App from GitHub and install it on your android device.
  2. Now, create an android project which will startActivity to Set Reminder.

 

 

3. I will first create a reminder edit screen. I will be using the same reminder screen which I used in my RemindMe app. I will explain this a little.

@Composable
fun ReminderEditScreen() {
Scaffold() {
val titleInputValue = remember { mutableStateOf(TextFieldValue()) }
val titleError = remember { mutableStateOf("") }
val descriptionInputValue = remember { mutableStateOf(TextFieldValue()) }
val descriptionError = remember { mutableStateOf("") }
var localDateTime: LocalDateTime? by remember {
mutableStateOf(null)
}
val remindTypeState = remember {
mutableStateOf(RemindType.NONE)
}
val mContext = LocalContext.current
BoxWithLayout {
Column(
Modifier
.padding(10.dp)
.fillMaxSize()
.verticalScroll(rememberScrollState())
.weight(1f, false),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.SpaceEvenly
) {
Text(
text = "Set Reminder",
fontSize = 30.sp,
fontWeight = FontWeight.Bold
)
Spacer(modifier = Modifier.height(10.dp))
OutlinedTextFieldValidation(value = titleInputValue.value.text, onValueChange = {
titleInputValue.value = TextFieldValue(it)
}, placeholder = {
Text(
text = "Enter your title"
)
},
keyboardOptions = KeyboardOptions(
capitalization = KeyboardCapitalization.None,
autoCorrect = true,
keyboardType = KeyboardType.Text,
imeAction = ImeAction.Done
),
textStyle = TextStyle(
color = Color.Black, fontSize = TextUnit.Unspecified,
fontFamily = FontFamily.SansSerif
),
maxLines = 1,
singleLine = true,
modifier = Modifier
.border(5.dp, Color.Unspecified, RoundedCornerShape(10.dp))
.fillMaxWidth()
.background(
color = Color(0xffe2ebf0),
shape = CircleShape
),
shape = CircleShape,
error = titleError.value
)
Spacer(modifier = Modifier.height(10.dp))
OutlinedTextFieldValidation(
value = descriptionInputValue.value.text,
onValueChange = {
descriptionInputValue.value = TextFieldValue(it)
},
placeholder = {
Text(
text = "Enter your subtitle"
)
},
keyboardOptions = KeyboardOptions(
capitalization = KeyboardCapitalization.None,
autoCorrect = true,
keyboardType = KeyboardType.Text,
imeAction = ImeAction.Done
),
textStyle = TextStyle(
color = Color.Black, fontSize = TextUnit.Unspecified,
fontFamily = FontFamily.SansSerif
),
maxLines = 1,
singleLine = true,
modifier = Modifier
.fillMaxWidth()
.background(
color = Color(0xffe2ebf0),
shape = CircleShape
),
shape = CircleShape,
error = descriptionError.value
)
Spacer(modifier = Modifier.height(10.dp))
DatePicker {
localDateTime = it
}
Spacer(modifier = Modifier.height(20.dp))
TimePicker(localDateTime) {
localDateTime = it
}
RepeatTypeDropDown {
remindTypeState.value = it
}
Button(onClick = {
val result = validateData(
titleInputValue,
descriptionInputValue,
titleError,
descriptionError,
localDateTime,
mContext
)
if (!result) {
return@Button
}
val title = titleInputValue.value.text
val description = descriptionInputValue.value.text
val startTimeInMillis =
localDateTime!!.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()
val reminderType = remindTypeState.value.toString()
val intent = Intent()
intent.action = Intent.ACTION_SEND
intent.data =
Uri.parse("remindme://reminder?title=${title}&description=${description}&startTimeInMillis=${startTimeInMillis}&reminderType=${reminderType}")
mContext.startActivity(intent)
}) {
Text(text = "Set Reminder")
}
}
}
}
}

I am simply using two TextFieldsDropdownDatePicker, and TimePicker to set reminders.

4. I want to explain to you an important thing that how I implemented to start RemindMe app edit reminder screen with filled data coming from intent.

For this, you need to add an intent filter in that activity that will handle ACTION_SEND action.

<intent-filter>
<action android:name="android.intent.action.SEND"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="@string/app_name_lowercase" android:host="reminder"/>
</intent-filter>
view raw manifest.xml hosted with ❤ by GitHub

Job Offers

Job Offers

There are currently no vacancies.

OUR VIDEO RECOMMENDATION

No results found.

Jobs

You need to define an action. you can use any default actions provided by android and choose a category as well.

In the data, you need to provide URI schema and host. for our example, the URI string will look.

remindme://reminder?title=title&description=decription&startTimeInMillis=1667922600000&reminderType=HOURLY
view raw uri hosted with ❤ by GitHub
  • schema is remindme
  • host is reminder
  • and appending queries title, description, startTimeInMillis, reminderType

5. In the ReminderApp you need to get intent that started your app activity. do it in onCreate()

val data: Uri? = intent.data
if (Intent.ACTION_SEND == intent.action) {
val isSchemaSame = data?.scheme == this.getString(R.string.app_name_lowercase)
val isHostSame = data?.host == "reminder"
if (isSchemaSame && isHostSame) {
val title = data?.getQueryParameter("title")
val description = data?.getQueryParameter("description")
val startTimeInMillis = data?.getQueryParameter("startTimeInMillis")
val reminderType = data?.getQueryParameter("reminderType")
val startTimeInInstant = startTimeInMillis?.toLong()
?.let { Instant.ofEpochMilli(it) }
showSetReminderScreen.postValue(true)
reminderData.postValue(
Reminder(
id = -1,
title = title ?: "",
description = description ?: "",
reminderStart = startTimeInInstant ?: Instant.now(),
remindType = RemindType.valueOf(reminderType ?: ""),
reminderEnd = Instant.now()
)
)
}
}
view raw MainActivity.kt hosted with ❤ by GitHub

We are simply breaking the URI into schema, host and queries and getting data from our URI.

6. Now, In SetReminderApp when the set reminder button is clicked we will create an implicit intent passing the Uri with all the data required.

Button(onClick = {
val result = validateData(
titleInputValue,
descriptionInputValue,
titleError,
descriptionError,
localDateTime,
mContext
)
if (!result) {
return@Button
}
val title = titleInputValue.value.text
val description = descriptionInputValue.value.text
val startTimeInMillis =
localDateTime!!.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()
val reminderType = remindTypeState.value.toString()
val intent = Intent()
intent.action = Intent.ACTION_SEND
intent.data =
Uri.parse("remindme://reminder?title=${title}&description=${description}&startTimeInMillis=${startTimeInMillis}&reminderType=${reminderType}")
mContext.startActivity(intent)
}) {
Text(text = "Set Reminder")
}

Now, If we run both apps and let’s check the output.

You can set it any time and check the notification. I have set currentTime.

 

Thank you for reading!

This article was originally published on proandroiddev.com on November 06, 2022

YOU MAY BE INTERESTED IN

YOU MAY BE INTERESTED IN

blog
We’ve broken down the Android developer roadmap into five modules, each covering different aspects…
READ MORE
Menu