Skip to content

Commit 6697ec3

Browse files
authored
Merge branch 'main' into single-option
2 parents ac9a7a7 + 6f61cb5 commit 6697ec3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+1161
-184
lines changed

.github/workflows/apply_spotless.yml

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,13 @@ jobs:
4444
- name: Run spotlessApply
4545
run: ./gradlew :compose:spotlessApply --init-script gradle/init.gradle.kts --no-configuration-cache --stacktrace
4646

47+
- name: Run spotlessApply for Wear
48+
run: ./gradlew :wear:spotlessApply --init-script gradle/init.gradle.kts --no-configuration-cache --stacktrace
49+
50+
- name: Run spotlessApply for Misc
51+
run: ./gradlew :misc:spotlessApply --init-script gradle/init.gradle.kts --no-configuration-cache --stacktrace
52+
4753
- name: Auto-commit if spotlessApply has changes
4854
uses: stefanzweifel/git-auto-commit-action@v5
4955
with:
50-
commit_message: Apply Spotless
51-
52-
- name: Run spotlessApply for Wear
53-
run: ./gradlew :wear:spotlessApply --init-script gradle/init.gradle.kts --no-configuration-cache --stacktrace
56+
commit_message: Apply Spotless

.github/workflows/build.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,5 @@ jobs:
4545
run: ./gradlew :kotlin:build
4646
- name: Build Wear snippets
4747
run: ./gradlew :wear:build
48+
- name: Build misc snippets
49+
run: ./gradlew :misc:build
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
/*
2+
* Copyright 2024 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.example.compose.snippets.text
18+
19+
import androidx.compose.foundation.layout.Column
20+
import androidx.compose.foundation.layout.fillMaxSize
21+
import androidx.compose.foundation.layout.fillMaxWidth
22+
import androidx.compose.foundation.layout.padding
23+
import androidx.compose.foundation.lazy.LazyColumn
24+
import androidx.compose.material3.ListItem
25+
import androidx.compose.material3.OutlinedTextField
26+
import androidx.compose.material3.Text
27+
import androidx.compose.runtime.Composable
28+
import androidx.compose.runtime.getValue
29+
import androidx.compose.runtime.mutableStateOf
30+
import androidx.compose.runtime.saveable.rememberSaveable
31+
import androidx.compose.runtime.setValue
32+
import androidx.compose.ui.Modifier
33+
import androidx.compose.ui.tooling.preview.Preview
34+
import androidx.compose.ui.unit.dp
35+
import androidx.lifecycle.ViewModel
36+
import androidx.lifecycle.compose.collectAsStateWithLifecycle
37+
import androidx.lifecycle.viewmodel.compose.viewModel
38+
import kotlinx.coroutines.flow.MutableStateFlow
39+
import kotlinx.coroutines.flow.StateFlow
40+
41+
// [START android_compose_text_filtertextviewmodel]
42+
class FilterTextViewModel : ViewModel() {
43+
private val items = listOf(
44+
"Cupcake",
45+
"Donut",
46+
"Eclair",
47+
"Froyo",
48+
"Gingerbread",
49+
"Honeycomb",
50+
"Ice Cream Sandwich"
51+
)
52+
53+
private val _filteredItems = MutableStateFlow(items)
54+
var filteredItems: StateFlow<List<String>> = _filteredItems
55+
56+
fun filterText(input: String) {
57+
// This filter returns the full items list when input is an empty string.
58+
_filteredItems.value = items.filter { it.contains(input, ignoreCase = true) }
59+
}
60+
}
61+
// [END android_compose_text_filtertextviewmodel]
62+
63+
// [START android_compose_text_filtertextview]
64+
@Composable
65+
fun FilterTextView(modifier: Modifier = Modifier, viewModel: FilterTextViewModel = viewModel()) {
66+
val filteredItems by viewModel.filteredItems.collectAsStateWithLifecycle()
67+
var text by rememberSaveable { mutableStateOf("") }
68+
69+
Column(
70+
modifier = Modifier
71+
.fillMaxSize()
72+
.padding(all = 10.dp)
73+
) {
74+
OutlinedTextField(
75+
value = text,
76+
onValueChange = {
77+
text = it
78+
viewModel.filterText(text)
79+
},
80+
label = { Text("Filter Text") },
81+
modifier = Modifier.fillMaxWidth()
82+
)
83+
84+
LazyColumn {
85+
items(
86+
count = filteredItems.size,
87+
key = { index -> filteredItems[index] }
88+
) {
89+
ListItem(
90+
headlineContent = { Text(filteredItems[it]) },
91+
modifier = Modifier
92+
.fillParentMaxWidth()
93+
.padding(10.dp)
94+
)
95+
}
96+
}
97+
}
98+
}
99+
// [END android_compose_text_filtertextview]
100+
101+
@Preview(showBackground = true)
102+
@Composable
103+
private fun FilterTextViewPreview() {
104+
FilterTextView()
105+
}

misc/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/build

misc/build.gradle.kts

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
plugins {
2+
alias(libs.plugins.android.application)
3+
alias(libs.plugins.kotlin.android)
4+
alias(libs.plugins.ksp)
5+
alias(libs.plugins.hilt)
6+
alias(libs.plugins.compose.compiler)
7+
}
8+
9+
android {
10+
compileSdk = libs.versions.compileSdk.get().toInt()
11+
namespace = "com.example.snippets"
12+
13+
defaultConfig {
14+
applicationId = "com.example.snippets"
15+
minSdk = libs.versions.minSdk.get().toInt()
16+
targetSdk = libs.versions.targetSdk.get().toInt()
17+
versionCode = 1
18+
versionName = "1.0"
19+
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
20+
}
21+
22+
kotlin {
23+
jvmToolchain(17)
24+
}
25+
26+
buildTypes {
27+
getByName("debug") {
28+
signingConfig = signingConfigs.getByName("debug")
29+
}
30+
31+
getByName("release") {
32+
isMinifyEnabled = false
33+
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"),
34+
"proguard-rules.pro")
35+
}
36+
}
37+
compileOptions {
38+
sourceCompatibility = JavaVersion.VERSION_17
39+
targetCompatibility = JavaVersion.VERSION_17
40+
}
41+
buildFeatures {
42+
compose = true
43+
// Disable unused AGP features
44+
viewBinding = true
45+
}
46+
47+
}
48+
dependencies {
49+
val composeBom = platform(libs.androidx.compose.bom)
50+
implementation(composeBom)
51+
androidTestImplementation(composeBom)
52+
implementation(libs.androidx.core.ktx)
53+
implementation(libs.androidx.activity.compose)
54+
implementation(libs.androidx.compose.runtime)
55+
implementation(libs.androidx.compose.foundation)
56+
implementation(libs.androidx.compose.foundation.layout)
57+
implementation(libs.androidx.compose.ui.util)
58+
implementation(libs.androidx.compose.ui.tooling.preview)
59+
implementation(libs.androidx.compose.material3)
60+
61+
implementation(libs.hilt.android)
62+
implementation(libs.androidx.hilt.navigation.compose)
63+
implementation(libs.kotlinx.serialization.json)
64+
ksp(libs.hilt.compiler)
65+
66+
implementation(libs.androidx.lifecycle.runtime)
67+
testImplementation(libs.junit)
68+
androidTestImplementation(libs.junit)
69+
androidTestImplementation(libs.androidx.test.core)
70+
androidTestImplementation(libs.androidx.test.runner)
71+
androidTestImplementation(libs.androidx.test.espresso.core)
72+
}
File renamed without changes.

misc/src/main/AndroidManifest.xml

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
3+
<permission android:name="com.example.snippets.CUSTOM_PERMISSION"/>
4+
5+
<!--[START android_broadcast_receiver_10_manifest_permission]-->
6+
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
7+
<!--[END android_broadcast_receiver_10_manifest_permission]-->
8+
9+
<application
10+
android:name=".MyApplication"
11+
android:allowBackup="true"
12+
android:icon="@mipmap/ic_launcher"
13+
android:label="@string/app_name"
14+
android:roundIcon="@mipmap/ic_launcher_round"
15+
android:supportsRtl="true"
16+
android:theme="@style/Theme.Snippets">
17+
18+
<!-- [START android_broadcast_receiver_1_receiver_manifest]-->
19+
<!-- If this receiver listens for broadcasts sent from the system or from
20+
other apps, even other apps that you own, set android:exported to "true". -->
21+
<receiver android:name=".MyBroadcastReceiver" android:exported="false">
22+
<intent-filter>
23+
<action android:name="com.example.snippets.ACTION_UPDATE_DATA" />
24+
</intent-filter>
25+
</receiver>
26+
<!-- [END android_broadcast_receiver_1_receiver_manifest]-->
27+
<!-- [START android_broadcast_receiver_11_receiver_manifest_with_permission]-->
28+
<!-- If this receiver listens for broadcasts sent from the system or from
29+
other apps, even other apps that you own, set android:exported to "true". -->
30+
<receiver
31+
android:name=".MyBroadcastReceiverWithPermission"
32+
android:permission="android.permission.ACCESS_COARSE_LOCATION"
33+
android:exported="true">
34+
<intent-filter>
35+
<action android:name="com.example.snippets.ACTION_UPDATE_DATA" />
36+
</intent-filter>
37+
</receiver>
38+
<!-- [END android_broadcast_receiver_11_receiver_manifest_with_permission]-->
39+
<activity
40+
android:name="com.example.snippets.MainActivity"
41+
android:exported="true"
42+
android:theme="@style/Theme.Snippets">
43+
<intent-filter>
44+
<action android:name="android.intent.action.MAIN" />
45+
<category android:name="android.intent.category.LAUNCHER" />
46+
</intent-filter>
47+
</activity>
48+
</application>
49+
50+
</manifest>
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
package com.example.snippets;
2+
3+
import android.content.BroadcastReceiver;
4+
import android.content.Context;
5+
import android.content.Intent;
6+
import android.content.IntentFilter;
7+
import android.os.Bundle;
8+
9+
import androidx.activity.ComponentActivity;
10+
import androidx.core.content.ContextCompat;
11+
12+
import java.util.Objects;
13+
14+
import javax.inject.Inject;
15+
16+
import dagger.hilt.android.qualifiers.ApplicationContext;
17+
18+
// Warning for reader: This file has the Java code snippets for completeness of the corresponding
19+
// documentation page, but these snippets are not part of the actual sample. Refer to the Kotlin
20+
// code for the actual sample.
21+
public class BroadcastReceiverJavaSnippets {
22+
23+
// [START android_broadcast_receiver_2_class_java]
24+
public static class MyBroadcastReceiver extends BroadcastReceiver {
25+
26+
@Inject
27+
DataRepository dataRepository;
28+
29+
@Override
30+
public void onReceive(Context context, Intent intent) {
31+
if (Objects.equals(intent.getAction(), "com.example.snippets.ACTION_UPDATE_DATA")) {
32+
String data = intent.getStringExtra("com.example.snippets.DATA");
33+
// Do something with the data, for example send it to a data repository:
34+
if (data != null) { dataRepository.updateData(data); }
35+
}
36+
}
37+
}
38+
// [END android_broadcast_receiver_2_class_java]
39+
40+
/** @noinspection ConstantValue, unused */
41+
public static class BroadcastReceiverViewModel {
42+
Context context;
43+
44+
public BroadcastReceiverViewModel(@ApplicationContext Context context) {
45+
this.context = context;
46+
}
47+
48+
// [START android_broadcast_receiver_3_definition_java]
49+
MyBroadcastReceiver myBroadcastReceiver = new MyBroadcastReceiver();
50+
// [END android_broadcast_receiver_3_definition_java]
51+
52+
public void registerBroadcastReceiver() {
53+
// [START android_broadcast_receiver_4_intent_filter_java]
54+
IntentFilter filter = new IntentFilter("com.example.snippets.ACTION_UPDATE_DATA");
55+
// [END android_broadcast_receiver_4_intent_filter_java]
56+
// [START android_broadcast_receiver_5_exported_java]
57+
boolean listenToBroadcastsFromOtherApps = false;
58+
int receiverFlags = listenToBroadcastsFromOtherApps
59+
? ContextCompat.RECEIVER_EXPORTED
60+
: ContextCompat.RECEIVER_NOT_EXPORTED;
61+
// [END android_broadcast_receiver_5_exported_java]
62+
63+
// [START android_broadcast_receiver_6_register_java]
64+
ContextCompat.registerReceiver(context, myBroadcastReceiver, filter, receiverFlags);
65+
// [END android_broadcast_receiver_6_register_java]
66+
67+
// [START android_broadcast_receiver_12_register_with_permission_java]
68+
ContextCompat.registerReceiver(
69+
context, myBroadcastReceiver, filter,
70+
android.Manifest.permission.ACCESS_COARSE_LOCATION,
71+
null, // scheduler that defines thread, null means run on main thread
72+
receiverFlags
73+
);
74+
// [END android_broadcast_receiver_12_register_with_permission_java]
75+
}
76+
77+
public void unregisterBroadcastReceiver() {
78+
context.unregisterReceiver(myBroadcastReceiver);
79+
}
80+
81+
public void sendBroadcast(String newData, boolean usePermission) {
82+
if(usePermission) {
83+
// [START android_broadcast_receiver_8_send_java]
84+
Intent intent = new Intent("com.example.snippets.ACTION_UPDATE_DATA");
85+
intent.putExtra("com.example.snippets.DATA", newData);
86+
intent.setPackage("com.example.snippets");
87+
context.sendBroadcast(intent);
88+
// [END android_broadcast_receiver_8_send_java]
89+
} else {
90+
Intent intent = new Intent("com.example.snippets.ACTION_UPDATE_DATA");
91+
intent.putExtra("com.example.snippets.DATA", newData);
92+
intent.setPackage("com.example.snippets");
93+
// [START android_broadcast_receiver_9_send_with_permission_java]
94+
context.sendBroadcast(intent, android.Manifest.permission.ACCESS_COARSE_LOCATION);
95+
// [END android_broadcast_receiver_9_send_with_permission_java]
96+
}
97+
}
98+
}
99+
100+
/** @noinspection InnerClassMayBeStatic*/
101+
// [START android_broadcast_receiver_13_activity_java]
102+
class MyActivity extends ComponentActivity {
103+
MyBroadcastReceiver myBroadcastReceiver;
104+
105+
@Override
106+
protected void onCreate(Bundle savedInstanceState) {
107+
super.onCreate(savedInstanceState);
108+
// [START_EXCLUDE]
109+
IntentFilter filter = new IntentFilter("com.example.snippets.ACTION_UPDATE_DATA");
110+
boolean listenToBroadcastsFromOtherApps = false;
111+
int receiverFlags = listenToBroadcastsFromOtherApps
112+
? ContextCompat.RECEIVER_EXPORTED
113+
: ContextCompat.RECEIVER_NOT_EXPORTED;
114+
// [END_EXCLUDE]
115+
ContextCompat.registerReceiver(this, myBroadcastReceiver, filter, receiverFlags);
116+
// Set content
117+
}
118+
}
119+
// [END android_broadcast_receiver_13_activity_java]
120+
}

0 commit comments

Comments
 (0)