-
Notifications
You must be signed in to change notification settings - Fork 1.2k
/
AugmentedImageActivity.java
222 lines (194 loc) · 7.31 KB
/
AugmentedImageActivity.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
/*
* Copyright 2018 Google LLC
*
* 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.ar.core.examples.c.augmentedimage;
import android.hardware.display.DisplayManager;
import android.net.Uri;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import com.bumptech.glide.Glide;
import com.bumptech.glide.RequestManager;
import com.google.android.material.snackbar.Snackbar;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
/**
* This is a simple example that shows how to use ARCore AugmentedImage C API.
*
* <p>In this example, we assume all images are static or moving slowly with a large occupation of
* the screen. If the target is actively moving, we recommend to check
* ArAugmentedImage_getTrackingMethod() and render only when the tracking method equals to
* AR_AUGMENTED_IMAGE_TRACKING_METHOD_FULL_TRACKING. See details in <a
* href="https://developers.google.com/ar/develop/c/augmented-images/">Recognize and Augment
* Images</a>.
*/
public class AugmentedImageActivity extends AppCompatActivity
implements GLSurfaceView.Renderer, DisplayManager.DisplayListener {
private static final String TAG = AugmentedImageActivity.class.getSimpleName();
private GLSurfaceView surfaceView;
private ImageView fitToScanView;
private RequestManager glideRequestManager;
private Snackbar snackbar;
private boolean viewportChanged = false;
private int viewportWidth;
private int viewportHeight;
// Opaque native pointer to the native application instance.
private long nativeApplication;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
surfaceView = (GLSurfaceView) findViewById(R.id.surfaceview);
// Set up renderer.
surfaceView.setPreserveEGLContextOnPause(true);
surfaceView.setEGLContextClientVersion(2);
surfaceView.setEGLConfigChooser(8, 8, 8, 8, 16, 0); // Alpha used for plane blending.
surfaceView.setRenderer(this);
surfaceView.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
surfaceView.setWillNotDraw(false);
JniInterface.assetManager = getAssets();
nativeApplication = JniInterface.createNativeApplication(getAssets());
fitToScanView = findViewById(R.id.image_view_fit_to_scan);
glideRequestManager = Glide.with(this);
glideRequestManager
.load(Uri.parse("file:///android_asset/fit_to_scan.png"))
.into(fitToScanView);
}
@Override
protected void onResume() {
super.onResume();
// ARCore requires camera permissions to operate. If we did not yet obtain runtime
// permission on Android M and above, now is a good time to ask the user for it.
if (!CameraPermissionHelper.hasCameraPermission(this)) {
CameraPermissionHelper.requestCameraPermission(this);
return;
}
try {
JniInterface.onResume(nativeApplication, getApplicationContext(), this);
surfaceView.onResume();
} catch (Exception e) {
Log.e(TAG, "Exception resuming session", e);
displayInSnackbar(e.getMessage());
return;
}
fitToScanView.setVisibility(View.VISIBLE);
// Listen to display changed events to detect 180° rotation, which does not cause a config
// change or view resize.
getSystemService(DisplayManager.class).registerDisplayListener(this, null);
}
@Override
public void onPause() {
super.onPause();
surfaceView.onPause();
JniInterface.onPause(nativeApplication);
getSystemService(DisplayManager.class).unregisterDisplayListener(this);
}
@Override
public void onDestroy() {
super.onDestroy();
// Synchronized to avoid racing onDrawFrame.
synchronized (this) {
JniInterface.destroyNativeApplication(nativeApplication);
nativeApplication = 0;
}
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
// Standard Android full-screen functionality.
getWindow()
.getDecorView()
.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
GLES20.glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
JniInterface.onGlSurfaceCreated(nativeApplication);
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
viewportWidth = width;
viewportHeight = height;
viewportChanged = true;
}
@Override
public void onDrawFrame(GL10 gl) {
// Synchronized to avoid racing onDestroy.
synchronized (this) {
if (nativeApplication == 0) {
return;
}
if (viewportChanged) {
int displayRotation = getWindowManager().getDefaultDisplay().getRotation();
JniInterface.onDisplayGeometryChanged(
nativeApplication, displayRotation, viewportWidth, viewportHeight);
viewportChanged = false;
}
JniInterface.onGlSurfaceDrawFrame(nativeApplication, this);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] results) {
super.onRequestPermissionsResult(requestCode, permissions, results);
if (!CameraPermissionHelper.hasCameraPermission(this)) {
Toast.makeText(this, "Camera permission is needed to run this application", Toast.LENGTH_LONG)
.show();
if (!CameraPermissionHelper.shouldShowRequestPermissionRationale(this)) {
// Permission denied with checking "Do not ask again".
CameraPermissionHelper.launchPermissionSettings(this);
}
finish();
}
}
// DisplayListener methods
@Override
public void onDisplayAdded(int displayId) {}
@Override
public void onDisplayRemoved(int displayId) {}
@Override
public void onDisplayChanged(int displayId) {
viewportChanged = true;
}
public void hideFitToScanImage() {
this.runOnUiThread(
new Runnable() {
@Override
public void run() {
fitToScanView.setVisibility(View.GONE);
}
});
}
/** Display the message in the snackbar. */
private void displayInSnackbar(String message) {
snackbar =
Snackbar.make(findViewById(android.R.id.content), message, Snackbar.LENGTH_INDEFINITE);
snackbar.show();
}
}