diff --git a/mediapipe/examples/android/src/java/com/google/mediapipe/apps/instantmotiontracking/GIFEditText.java b/mediapipe/examples/android/src/java/com/google/mediapipe/apps/instantmotiontracking/GIFEditText.java
index 1b733ed8..10e6422b 100644
--- a/mediapipe/examples/android/src/java/com/google/mediapipe/apps/instantmotiontracking/GIFEditText.java
+++ b/mediapipe/examples/android/src/java/com/google/mediapipe/apps/instantmotiontracking/GIFEditText.java
@@ -18,7 +18,7 @@ import android.content.ClipDescription;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
-import androidx.appcompat.widget.AppCompatEditText;
+import android.support.v7.widget.AppCompatEditText;
import android.util.AttributeSet;
import android.util.Log;
import android.view.inputmethod.EditorInfo;
diff --git a/mediapipe/tasks/examples/android/BUILD b/mediapipe/tasks/examples/android/BUILD
new file mode 100644
index 00000000..c07af2d2
--- /dev/null
+++ b/mediapipe/tasks/examples/android/BUILD
@@ -0,0 +1,21 @@
+# Copyright 2022 The MediaPipe Authors. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+licenses(["notice"])
+
+filegroup(
+ name = "resource_files",
+ srcs = glob(["res/**"]),
+ visibility = ["//mediapipe/tasks/examples/android:__subpackages__"],
+)
diff --git a/mediapipe/tasks/examples/android/objectdetector/src/main/AndroidManifest.xml b/mediapipe/tasks/examples/android/objectdetector/src/main/AndroidManifest.xml
new file mode 100644
index 00000000..5c53dc26
--- /dev/null
+++ b/mediapipe/tasks/examples/android/objectdetector/src/main/AndroidManifest.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mediapipe/tasks/examples/android/objectdetector/src/main/BUILD b/mediapipe/tasks/examples/android/objectdetector/src/main/BUILD
new file mode 100644
index 00000000..65b98d64
--- /dev/null
+++ b/mediapipe/tasks/examples/android/objectdetector/src/main/BUILD
@@ -0,0 +1,48 @@
+# Copyright 2022 The MediaPipe Authors. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+licenses(["notice"])
+
+package(default_visibility = ["//visibility:private"])
+
+android_binary(
+ name = "objectdetector",
+ srcs = glob(["**/*.java"]),
+ assets = [
+ "//mediapipe/tasks/testdata/vision:test_models",
+ ],
+ assets_dir = "",
+ custom_package = "com.google.mediapipe.tasks.examples.objectdetector",
+ manifest = "AndroidManifest.xml",
+ manifest_values = {
+ "applicationId": "com.google.mediapipe.tasks.examples.objectdetector",
+ },
+ multidex = "native",
+ resource_files = ["//mediapipe/tasks/examples/android:resource_files"],
+ deps = [
+ "//mediapipe/java/com/google/mediapipe/framework/image",
+ "//mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers:detection",
+ "//mediapipe/tasks/java/com/google/mediapipe/tasks/core",
+ "//mediapipe/tasks/java/com/google/mediapipe/tasks/vision/core",
+ "//mediapipe/tasks/java/com/google/mediapipe/tasks/vision/objectdetector",
+ "//third_party:androidx_appcompat",
+ "//third_party:androidx_constraint_layout",
+ "//third_party:opencv",
+ "@maven//:androidx_activity_activity",
+ "@maven//:androidx_concurrent_concurrent_futures",
+ "@maven//:androidx_exifinterface_exifinterface",
+ "@maven//:androidx_fragment_fragment",
+ "@maven//:com_google_guava_guava",
+ ],
+)
diff --git a/mediapipe/tasks/examples/android/objectdetector/src/main/java/com/google/mediapipe/tasks/examples/objectdetector/MainActivity.java b/mediapipe/tasks/examples/android/objectdetector/src/main/java/com/google/mediapipe/tasks/examples/objectdetector/MainActivity.java
new file mode 100644
index 00000000..7f7ec138
--- /dev/null
+++ b/mediapipe/tasks/examples/android/objectdetector/src/main/java/com/google/mediapipe/tasks/examples/objectdetector/MainActivity.java
@@ -0,0 +1,236 @@
+// Copyright 2022 The MediaPipe Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.mediapipe.tasks.examples.objectdetector;
+
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.Matrix;
+import android.media.MediaMetadataRetriever;
+import android.os.Bundle;
+import android.provider.MediaStore;
+import androidx.appcompat.app.AppCompatActivity;
+import android.util.Log;
+import android.view.View;
+import android.widget.Button;
+import android.widget.FrameLayout;
+import androidx.activity.result.ActivityResultLauncher;
+import androidx.activity.result.contract.ActivityResultContracts;
+import androidx.exifinterface.media.ExifInterface;
+// ContentResolver dependency
+import com.google.mediapipe.framework.image.BitmapImageBuilder;
+import com.google.mediapipe.framework.image.Image;
+import com.google.mediapipe.tasks.core.BaseOptions;
+import com.google.mediapipe.tasks.vision.core.RunningMode;
+import com.google.mediapipe.tasks.vision.objectdetector.ObjectDetectionResult;
+import com.google.mediapipe.tasks.vision.objectdetector.ObjectDetector;
+import com.google.mediapipe.tasks.vision.objectdetector.ObjectDetector.ObjectDetectorOptions;
+import java.io.IOException;
+import java.io.InputStream;
+
+/** Main activity of MediaPipe Task Object Detector reference app. */
+public class MainActivity extends AppCompatActivity {
+ private static final String TAG = "MainActivity";
+ private static final String MODEL_FILE = "coco_ssd_mobilenet_v1_1.0_quant_2018_06_29.tflite";
+
+ private ObjectDetector objectDetector;
+
+ private enum InputSource {
+ UNKNOWN,
+ IMAGE,
+ VIDEO,
+ CAMERA,
+ }
+
+ private InputSource inputSource = InputSource.UNKNOWN;
+
+ // Image mode demo component.
+ private ActivityResultLauncher imageGetter;
+ // Video mode demo component.
+ private ActivityResultLauncher videoGetter;
+ private ObjectDetectionResultImageView imageView;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+ setupImageModeDemo();
+ setupVideoModeDemo();
+ // TODO: Adds live camera demo.
+ }
+
+ /** Sets up the image mode demo. */
+ private void setupImageModeDemo() {
+ imageView = new ObjectDetectionResultImageView(this);
+ // The Intent to access gallery and read images as bitmap.
+ imageGetter =
+ registerForActivityResult(
+ new ActivityResultContracts.StartActivityForResult(),
+ result -> {
+ Intent resultIntent = result.getData();
+ if (resultIntent != null) {
+ if (result.getResultCode() == RESULT_OK) {
+ Bitmap bitmap = null;
+ try {
+ bitmap =
+ downscaleBitmap(
+ MediaStore.Images.Media.getBitmap(
+ this.getContentResolver(), resultIntent.getData()));
+ } catch (IOException e) {
+ Log.e(TAG, "Bitmap reading error:" + e);
+ }
+ try {
+ InputStream imageData =
+ this.getContentResolver().openInputStream(resultIntent.getData());
+ bitmap = rotateBitmap(bitmap, imageData);
+ } catch (IOException e) {
+ Log.e(TAG, "Bitmap rotation error:" + e);
+ }
+ if (bitmap != null) {
+ Image image = new BitmapImageBuilder(bitmap).build();
+ ObjectDetectionResult detectionResult = objectDetector.detect(image);
+ imageView.setData(image, detectionResult);
+ runOnUiThread(() -> imageView.update());
+ }
+ }
+ }
+ });
+ Button loadImageButton = findViewById(R.id.button_load_picture);
+ loadImageButton.setOnClickListener(
+ v -> {
+ if (inputSource != InputSource.IMAGE) {
+ createObjectDetector(RunningMode.IMAGE);
+ this.inputSource = InputSource.IMAGE;
+ updateLayout();
+ }
+ // Reads images from gallery.
+ Intent pickImageIntent = new Intent(Intent.ACTION_PICK);
+ pickImageIntent.setDataAndType(MediaStore.Images.Media.INTERNAL_CONTENT_URI, "image/*");
+ imageGetter.launch(pickImageIntent);
+ });
+ }
+
+ /** Sets up the video mode demo. */
+ private void setupVideoModeDemo() {
+ imageView = new ObjectDetectionResultImageView(this);
+ // The Intent to access gallery and read a video file.
+ videoGetter =
+ registerForActivityResult(
+ new ActivityResultContracts.StartActivityForResult(),
+ result -> {
+ Intent resultIntent = result.getData();
+ if (resultIntent != null) {
+ if (result.getResultCode() == RESULT_OK) {
+ MediaMetadataRetriever metaRetriever = new MediaMetadataRetriever();
+ metaRetriever.setDataSource(this, resultIntent.getData());
+ long duration =
+ Long.parseLong(
+ metaRetriever.extractMetadata(
+ MediaMetadataRetriever.METADATA_KEY_DURATION));
+ int numFrames =
+ Integer.parseInt(
+ metaRetriever.extractMetadata(
+ MediaMetadataRetriever.METADATA_KEY_VIDEO_FRAME_COUNT));
+ long frameIntervalMs = duration / numFrames;
+ for (int i = 0; i < numFrames; ++i) {
+ Image image = new BitmapImageBuilder(metaRetriever.getFrameAtIndex(i)).build();
+ ObjectDetectionResult detectionResult =
+ objectDetector.detectForVideo(image, frameIntervalMs * i);
+ // Currently only annotates the detection result on the first video frame and
+ // display it to verify the correctness.
+ // TODO: Annotates the detection result on every frame, save the
+ // annotated frames as a video file, and play back the video afterwards.
+ if (i == 0) {
+ imageView.setData(image, detectionResult);
+ runOnUiThread(() -> imageView.update());
+ }
+ }
+ }
+ }
+ });
+ Button loadVideoButton = findViewById(R.id.button_load_video);
+ loadVideoButton.setOnClickListener(
+ v -> {
+ createObjectDetector(RunningMode.VIDEO);
+ updateLayout();
+ this.inputSource = InputSource.VIDEO;
+
+ // Reads a video from gallery.
+ Intent pickVideoIntent = new Intent(Intent.ACTION_PICK);
+ pickVideoIntent.setDataAndType(MediaStore.Video.Media.INTERNAL_CONTENT_URI, "video/*");
+ videoGetter.launch(pickVideoIntent);
+ });
+ }
+
+ private void createObjectDetector(RunningMode mode) {
+ if (objectDetector != null) {
+ objectDetector.close();
+ }
+ // Initializes a new MediaPipe ObjectDetector instance
+ ObjectDetectorOptions options =
+ ObjectDetectorOptions.builder()
+ .setBaseOptions(BaseOptions.builder().setModelAssetPath(MODEL_FILE).build())
+ .setScoreThreshold(0.5f)
+ .setMaxResults(5)
+ .setRunningMode(mode)
+ .build();
+ objectDetector = ObjectDetector.createFromOptions(this, options);
+ }
+
+ private void updateLayout() {
+ // Updates the preview layout.
+ FrameLayout frameLayout = findViewById(R.id.preview_display_layout);
+ frameLayout.removeAllViewsInLayout();
+ imageView.setImageDrawable(null);
+ frameLayout.addView(imageView);
+ imageView.setVisibility(View.VISIBLE);
+ }
+
+ private Bitmap downscaleBitmap(Bitmap originalBitmap) {
+ double aspectRatio = (double) originalBitmap.getWidth() / originalBitmap.getHeight();
+ int width = imageView.getWidth();
+ int height = imageView.getHeight();
+ if (((double) imageView.getWidth() / imageView.getHeight()) > aspectRatio) {
+ width = (int) (height * aspectRatio);
+ } else {
+ height = (int) (width / aspectRatio);
+ }
+ return Bitmap.createScaledBitmap(originalBitmap, width, height, false);
+ }
+
+ private Bitmap rotateBitmap(Bitmap inputBitmap, InputStream imageData) throws IOException {
+ int orientation =
+ new ExifInterface(imageData)
+ .getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
+ if (orientation == ExifInterface.ORIENTATION_NORMAL) {
+ return inputBitmap;
+ }
+ Matrix matrix = new Matrix();
+ switch (orientation) {
+ case ExifInterface.ORIENTATION_ROTATE_90:
+ matrix.postRotate(90);
+ break;
+ case ExifInterface.ORIENTATION_ROTATE_180:
+ matrix.postRotate(180);
+ break;
+ case ExifInterface.ORIENTATION_ROTATE_270:
+ matrix.postRotate(270);
+ break;
+ default:
+ matrix.postRotate(0);
+ }
+ return Bitmap.createBitmap(
+ inputBitmap, 0, 0, inputBitmap.getWidth(), inputBitmap.getHeight(), matrix, true);
+ }
+}
diff --git a/mediapipe/tasks/examples/android/objectdetector/src/main/java/com/google/mediapipe/tasks/examples/objectdetector/ObjectDetectionResultImageView.java b/mediapipe/tasks/examples/android/objectdetector/src/main/java/com/google/mediapipe/tasks/examples/objectdetector/ObjectDetectionResultImageView.java
new file mode 100644
index 00000000..94a4a90d
--- /dev/null
+++ b/mediapipe/tasks/examples/android/objectdetector/src/main/java/com/google/mediapipe/tasks/examples/objectdetector/ObjectDetectionResultImageView.java
@@ -0,0 +1,77 @@
+// Copyright 2022 The MediaPipe Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.mediapipe.tasks.examples.objectdetector;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Matrix;
+import android.graphics.Paint;
+import androidx.appcompat.widget.AppCompatImageView;
+import com.google.mediapipe.framework.image.BitmapExtractor;
+import com.google.mediapipe.framework.image.Image;
+import com.google.mediapipe.tasks.components.containers.Detection;
+import com.google.mediapipe.tasks.vision.objectdetector.ObjectDetectionResult;
+
+/** An ImageView implementation for displaying {@link ObjectDetectionResult}. */
+public class ObjectDetectionResultImageView extends AppCompatImageView {
+ private static final String TAG = "ObjectDetectionResultImageView";
+
+ private static final int BBOX_COLOR = Color.GREEN;
+ private static final int BBOX_THICKNESS = 5; // Pixels
+ private Bitmap latest;
+
+ public ObjectDetectionResultImageView(Context context) {
+ super(context);
+ setScaleType(AppCompatImageView.ScaleType.FIT_CENTER);
+ }
+
+ /**
+ * Sets an {@link Image} and an {@link ObjectDetectionResult} to render.
+ *
+ * @param image an {@link Image} object for annotation.
+ * @param result an {@link ObjectDetectionResult} object that contains the detection result.
+ */
+ public void setData(Image image, ObjectDetectionResult result) {
+ if (image == null || result == null) {
+ return;
+ }
+ latest = BitmapExtractor.extract(image);
+ Canvas canvas = new Canvas(latest);
+ canvas.drawBitmap(latest, new Matrix(), null);
+ for (int i = 0; i < result.detections().size(); ++i) {
+ drawDetectionOnCanvas(result.detections().get(i), canvas);
+ }
+ }
+
+ /** Updates the image view with the latest {@link ObjectDetectionResult}. */
+ public void update() {
+ postInvalidate();
+ if (latest != null) {
+ setImageBitmap(latest);
+ }
+ }
+
+ private void drawDetectionOnCanvas(Detection detection, Canvas canvas) {
+ // TODO: Draws the category and the score per bounding box.
+ // Draws bounding box.
+ Paint bboxPaint = new Paint();
+ bboxPaint.setColor(BBOX_COLOR);
+ bboxPaint.setStyle(Paint.Style.STROKE);
+ bboxPaint.setStrokeWidth(BBOX_THICKNESS);
+ canvas.drawRect(detection.boundingBox(), bboxPaint);
+ }
+}
diff --git a/mediapipe/tasks/examples/android/res/drawable-v24/ic_launcher_foreground.xml b/mediapipe/tasks/examples/android/res/drawable-v24/ic_launcher_foreground.xml
new file mode 100644
index 00000000..c7bd21db
--- /dev/null
+++ b/mediapipe/tasks/examples/android/res/drawable-v24/ic_launcher_foreground.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mediapipe/tasks/examples/android/res/drawable/ic_launcher_background.xml b/mediapipe/tasks/examples/android/res/drawable/ic_launcher_background.xml
new file mode 100644
index 00000000..01f0af0a
--- /dev/null
+++ b/mediapipe/tasks/examples/android/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,74 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mediapipe/tasks/examples/android/res/layout/activity_main.xml b/mediapipe/tasks/examples/android/res/layout/activity_main.xml
new file mode 100644
index 00000000..834e9a3e
--- /dev/null
+++ b/mediapipe/tasks/examples/android/res/layout/activity_main.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mediapipe/tasks/examples/android/res/mipmap-anydpi-v26/ic_launcher.xml b/mediapipe/tasks/examples/android/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 00000000..d372a4fc
--- /dev/null
+++ b/mediapipe/tasks/examples/android/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/mediapipe/tasks/examples/android/res/mipmap-anydpi-v26/ic_launcher_round.xml b/mediapipe/tasks/examples/android/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 00000000..d372a4fc
--- /dev/null
+++ b/mediapipe/tasks/examples/android/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/mediapipe/tasks/examples/android/res/mipmap-hdpi/ic_launcher.png b/mediapipe/tasks/examples/android/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 00000000..920cbf3f
Binary files /dev/null and b/mediapipe/tasks/examples/android/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/mediapipe/tasks/examples/android/res/mipmap-hdpi/ic_launcher_foreground.png b/mediapipe/tasks/examples/android/res/mipmap-hdpi/ic_launcher_foreground.png
new file mode 100644
index 00000000..7dfa35f7
Binary files /dev/null and b/mediapipe/tasks/examples/android/res/mipmap-hdpi/ic_launcher_foreground.png differ
diff --git a/mediapipe/tasks/examples/android/res/mipmap-hdpi/ic_launcher_round.png b/mediapipe/tasks/examples/android/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 00000000..20dfc6c1
Binary files /dev/null and b/mediapipe/tasks/examples/android/res/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/mediapipe/tasks/examples/android/res/mipmap-mdpi/ic_launcher.png b/mediapipe/tasks/examples/android/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 00000000..3813caa2
Binary files /dev/null and b/mediapipe/tasks/examples/android/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/mediapipe/tasks/examples/android/res/mipmap-mdpi/ic_launcher_foreground.png b/mediapipe/tasks/examples/android/res/mipmap-mdpi/ic_launcher_foreground.png
new file mode 100644
index 00000000..d4923277
Binary files /dev/null and b/mediapipe/tasks/examples/android/res/mipmap-mdpi/ic_launcher_foreground.png differ
diff --git a/mediapipe/tasks/examples/android/res/mipmap-mdpi/ic_launcher_round.png b/mediapipe/tasks/examples/android/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 00000000..18f9ac5e
Binary files /dev/null and b/mediapipe/tasks/examples/android/res/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/mediapipe/tasks/examples/android/res/mipmap-xhdpi/ic_launcher.png b/mediapipe/tasks/examples/android/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 00000000..b79cc77a
Binary files /dev/null and b/mediapipe/tasks/examples/android/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/mediapipe/tasks/examples/android/res/mipmap-xhdpi/ic_launcher_foreground.png b/mediapipe/tasks/examples/android/res/mipmap-xhdpi/ic_launcher_foreground.png
new file mode 100644
index 00000000..811b17ce
Binary files /dev/null and b/mediapipe/tasks/examples/android/res/mipmap-xhdpi/ic_launcher_foreground.png differ
diff --git a/mediapipe/tasks/examples/android/res/mipmap-xhdpi/ic_launcher_round.png b/mediapipe/tasks/examples/android/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 00000000..2f3c752e
Binary files /dev/null and b/mediapipe/tasks/examples/android/res/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/mediapipe/tasks/examples/android/res/mipmap-xxhdpi/ic_launcher.png b/mediapipe/tasks/examples/android/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 00000000..05585e4c
Binary files /dev/null and b/mediapipe/tasks/examples/android/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/mediapipe/tasks/examples/android/res/mipmap-xxhdpi/ic_launcher_foreground.png b/mediapipe/tasks/examples/android/res/mipmap-xxhdpi/ic_launcher_foreground.png
new file mode 100644
index 00000000..46b77639
Binary files /dev/null and b/mediapipe/tasks/examples/android/res/mipmap-xxhdpi/ic_launcher_foreground.png differ
diff --git a/mediapipe/tasks/examples/android/res/mipmap-xxhdpi/ic_launcher_round.png b/mediapipe/tasks/examples/android/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 00000000..f8733242
Binary files /dev/null and b/mediapipe/tasks/examples/android/res/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/mediapipe/tasks/examples/android/res/mipmap-xxxhdpi/ic_launcher.png b/mediapipe/tasks/examples/android/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 00000000..8ccd6c84
Binary files /dev/null and b/mediapipe/tasks/examples/android/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/mediapipe/tasks/examples/android/res/mipmap-xxxhdpi/ic_launcher_foreground.png b/mediapipe/tasks/examples/android/res/mipmap-xxxhdpi/ic_launcher_foreground.png
new file mode 100644
index 00000000..06b982e3
Binary files /dev/null and b/mediapipe/tasks/examples/android/res/mipmap-xxxhdpi/ic_launcher_foreground.png differ
diff --git a/mediapipe/tasks/examples/android/res/mipmap-xxxhdpi/ic_launcher_round.png b/mediapipe/tasks/examples/android/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 00000000..501748ac
Binary files /dev/null and b/mediapipe/tasks/examples/android/res/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/mediapipe/tasks/examples/android/res/values/colors.xml b/mediapipe/tasks/examples/android/res/values/colors.xml
new file mode 100644
index 00000000..69b22338
--- /dev/null
+++ b/mediapipe/tasks/examples/android/res/values/colors.xml
@@ -0,0 +1,6 @@
+
+
+ #008577
+ #00574B
+ #D81B60
+
diff --git a/mediapipe/tasks/examples/android/res/values/strings.xml b/mediapipe/tasks/examples/android/res/values/strings.xml
new file mode 100644
index 00000000..1e6b68a9
--- /dev/null
+++ b/mediapipe/tasks/examples/android/res/values/strings.xml
@@ -0,0 +1,6 @@
+
+ Load Picture
+ Load Video
+ Start Camera
+ Please press any button above to start
+
diff --git a/mediapipe/tasks/examples/android/res/values/styles.xml b/mediapipe/tasks/examples/android/res/values/styles.xml
new file mode 100644
index 00000000..5885930d
--- /dev/null
+++ b/mediapipe/tasks/examples/android/res/values/styles.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+