一. 配置您项目的 build.gradle 文件,相关AR项目引用
官网地址
官网demo地址
1.确保您项目的 build.gradle 包括 Google 的 Maven 代码库:
allprojects {
repositories {
google()
jcenter()
}
}
2.更新您应用的 build.gradle 以添加最新的 ARCore 和 Sceneform 用户体验依赖项,确保您的项目设置与两个库都兼容。
android {
…
defaultConfig {
// Sceneform requires minSdkVersion >= 24.
minSdkVersion 24
…
}
// Sceneform libraries use language constructs from Java 8.
// Add these compile options if targeting minSdkVersion < 26.
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
…
// Provides ARCore Session and related resources.
implementation 'com.google.ar:core:1.5.0'
// Provides ArFragment, and other UX resources.
implementation 'com.google.ar.sceneform.ux:sceneform-ux:1.5.0'
// Alternatively, use ArSceneView without the UX dependency.
implementation 'com.google.ar.sceneform:core:1.5.0'
}
3.更新您的 AndroidManifest.xml
修改您的 AndroidManifest.xml 来指示您的应用使用(AR 可选)或需要(AR 必备)ARCore 和摄像头访问权限:
…
二. Android Studio中预览3D模型文件 官网说明
1.安装 Google Sceneform Tools (Beta) 插件
在 Android Studio 中,打开 Plugins 设置:
Windows:File > Settings > Plugins > Browse Repositories
macOS:Android Studio > Preferences > Plugins
然后点击 Browse repositories 并安装 Google Sceneform Tools (Beta)。
2.导入3D asset, 添加Sampledata文件(已经有,可以不再新建)
3.copy模型文件到sampledata中,如果没有模型文件, 可下载官网demo官网demo地址
4.选择.obj文件导入模型在Android studio中查看
更新您的应用的 build.gradle 文件,为新导入的 asset 添加一个 apply plugin 行和一个 sceneform.asset() 条目:
apply plugin: 'com.google.ar.sceneform.plugin'
//导入成功后,下面代码会自动生成
sceneform.asset('sampledata/models/andy.obj', // 'Source Asset Path' specified during import.
'default', // 'Material Path' specified during import.
'sampledata/models/andy.sfa', // '.sfa Output Path' specified during import.
'src/main/res/raw/andy') // '.sfb Output Path' specified during import.
4.检查是否支持ARCore,并且检查权限
//检查是否支持ARCore
/**
* Returns false and displays an error message if Sceneform can not run, true if Sceneform can run
* on this device.
*
* Sceneform requires Android N on the device as well as OpenGL 3.0 capabilities.
*
*
Finishes the activity if Sceneform can not run
*/
public static boolean checkIsSupportedDeviceOrFinish(final Activity activity) {
if (Build.VERSION.SDK_INT < VERSION_CODES.N) {
Log.e(TAG, "this APP requires Android N or later");
Toast.makeText(activity, "this APP Android N or later", Toast.LENGTH_LONG).show();
activity.finish();
return false;
}
String openGlVersionString =
((ActivityManager) activity.getSystemService(Context.ACTIVITY_SERVICE))
.getDeviceConfigurationInfo()
.getGlEsVersion();
if (Double.parseDouble(openGlVersionString) < MIN_OPENGL_VERSION) {
Log.e(TAG, "Sceneform requires OpenGL ES 3.0 later");
Toast.makeText(activity, "Sceneform requires OpenGL ES 3.0 or later", Toast.LENGTH_LONG)
.show();
activity.finish();
return false;
}
return true;
}
//检查申请权限
public static final int PERMISSION_REQUESTCODE = 0;
public static void checkPermissions(final Activity activity) {
List needRequestPermissionList = findDeniedPermissions(activity,needPermissions);
if (needRequestPermissionList != null
&& needRequestPermissionList.size() > 0) {
String[] array = needRequestPermissionList.toArray(new String[needRequestPermissionList.size()]);
activity.requestPermissions(array, PERMISSION_REQUESTCODE);
}
}
public static List findDeniedPermissions(final Activity activity,String[] permissions) {
List needRequestPermissionList = new ArrayList();
try {
for (String perm : permissions) {
Method checkSelfMethod = activity.getClass().getMethod("checkSelfPermission", String.class);
Method shouldShowRequestPermissionRationaleMethod = activity.getClass().getMethod("shouldShowRequestPermissionRationale",
String.class);
if ((Integer)checkSelfMethod.invoke(activity, perm) != PackageManager.PERMISSION_GRANTED
|| (Boolean)shouldShowRequestPermissionRationaleMethod.invoke(activity, perm)) {
needRequestPermissionList.add(perm);
}
}
} catch (Throwable e) {
}
return needRequestPermissionList;
}
三. 代码部分
1.xml文件部分
2.java代码部分
private ArFragment fragment;
private ModelRenderable andyRenderable;
fragment = (ArFragment) getSupportFragmentManager().findFragmentById(R.id.ux_fragment);
//初始化模型文件
ModelRenderable.builder()
.setSource(this, Uri.parse("andy.sfb")) //加载模型资源
.build()
.thenAccept(renderable -> andyRenderable = renderable)
.exceptionally(
throwable -> {
Toast toast =
Toast.makeText(this, "Unable to load andy renderable", Toast.LENGTH_LONG);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
return null;
});
fragment.setOnTapArPlaneListener(
(HitResult hitResult, Plane plane, MotionEvent motionEvent) -> {
if (andyRenderable == null) {
return;
}
// Create the Anchor. 创建定位点
Anchor anchor = hitResult.createAnchor();
AnchorNode anchorNode = new AnchorNode(anchor);
anchorNode.setParent(fragment.getArSceneView().getScene());
// Create the transformable andy and add it to the anchor.
TransformableNode andy = new TransformableNode(fragment.getTransformationSystem());
andy.setParent(anchorNode);
andy.setRenderable(andyRenderable);
andy.select();
});