super. onCreate (savedInstanceState);
setContentView(R.layout.map_google);
Button myLocationButton = (Button) findViewById(R.id.myLocationButton);
myLocationButton.setVisibility(View.VISIBLE);
myLocationButton.setOnClickListener (this);
((SupportMapFragment) getSupportFragmentManager () .findFragmentById(R.id.map)).getMapAsync (this);
}
@Override
public boolean onMarkerClick (Marker marker) {
// To get the GeoObject that owns the marker we use the following
// method:
GeoObject geoObject = mGoogleMapPlugin.getGeoObjectOwner (marker);
if (geoObject!= null) {
Toast.makeText (this, «Click on a marker owned by a GeoOject with the name: " + geoObject.getName (),
Toast.LENGTH_SHORT).show ();
}
return false;
}
@Override
protected void onResume () {
super. onResume ();
// When the activity is resumed it is time to enable the
// BeyondarLocationManager
BeyondarLocationManager. enable ();
}
@Override
protected void onPause () {
super. onPause ();
// To avoid unnecessary battery usage disable BeyondarLocationManager
// when the activity goes on pause.
BeyondarLocationManager. disable ();
}
@Override
public void onClick (View v) {
// When the user clicks on the button we animate the map to the user
// location
LatLng userLocation = new LatLng(mWorld.getLatitude (), mWorld.getLongitude ());
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom (userLocation, 15));
mMap.animateCamera (CameraUpdateFactory. zoomTo (19), 2000, null);
}
@Override
public void onMapReady (GoogleMap googleMap) {
mMap=googleMap;
// We create the world and fill the world
mWorld = CustomWorldHelper.generateObjects (this);
// As we want to use GoogleMaps, we are going to create the plugin and
// attach it to the World
mGoogleMapPlugin = new GoogleMapWorldPlugin (this);
// Then we need to set the map in to the GoogleMapPlugin
mGoogleMapPlugin.setGoogleMap (mMap);
// Now that we have the plugin created lets add it to our world.
// NOTE: It is better to load the plugins before start adding object in
// to the world.
mWorld.addPlugin (mGoogleMapPlugin);
mMap.setOnMarkerClickListener (this);
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(mGoogleMapPlugin.getLatLng (), 15));
mMap.animateCamera (CameraUpdateFactory. zoomTo (19), 2000, null);
// Lets add the user position to the map
GeoObject user = new GeoObject (1000l);
user.setGeoPosition(mWorld.getLatitude (), mWorld.getLongitude ());
user.setImageResource (R. drawable. flag);
user.setName («User position»);
mWorld.addBeyondarObject (user);
BeyondarLocationManager.addWorldLocationUpdate (mWorld);
BeyondarLocationManager.addGeoObjectLocationUpdate (user);
// We need to set the LocationManager to the BeyondarLocationManager.
BeyondarLocationManager
.setLocationManager ((LocationManager) getSystemService (Context. LOCATION_SERVICE));
}
}
package com.beyondar. example;
import android. os. Bundle;
import android.support.v4.app.FragmentActivity;
import android.widget.Toast;
import com.beyondar.android.plugin. googlemap. GoogleMapWorldPlugin;
import com.beyondar.android.world.GeoObject;
import com.beyondar.android. world. World;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps. GoogleMap;
import com.google.android.gms.maps. GoogleMap. OnMarkerClickListener;
import com.google.android.gms.maps. OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.Marker;
public class GoogleMapActivity extends FragmentActivity implements OnMarkerClickListener, OnMapReadyCallback {
private GoogleMap mMap;
private GoogleMapWorldPlugin mGoogleMapPlugin;
private World mWorld;
@Override
protected void onCreate (Bundle savedInstanceState) {
super. onCreate (savedInstanceState);
setContentView(R.layout.map_google);
((SupportMapFragment) getSupportFragmentManager () .findFragmentById(R.id.map)).getMapAsync (this);
}
@Override
public boolean onMarkerClick (Marker marker) {
// To get the GeoObject that owns the marker we use the following
// method:
GeoObject geoObject = mGoogleMapPlugin.getGeoObjectOwner (marker);
if (geoObject!= null) {
Toast.makeText (this, «Click on a marker owned by a GeoOject with the name: " + geoObject.getName (),
Toast.LENGTH_SHORT).show ();
}
return false;
}
@Override
public void onMapReady (GoogleMap googleMap) {
mMap=googleMap;
// We create the world and fill the world
mWorld = CustomWorldHelper.generateObjects (this);
// As we want to use GoogleMaps, we are going to create the plugin and
// attach it to the World
mGoogleMapPlugin = new GoogleMapWorldPlugin (this);
// Then we need to set the map in to the GoogleMapPlugin
mGoogleMapPlugin.setGoogleMap (mMap);
// Now that we have the plugin created lets add it to our world.
// NOTE: It is better to load the plugins before start adding object in to the world.
mWorld.addPlugin (mGoogleMapPlugin);
mMap.setOnMarkerClickListener (this);
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(mGoogleMapPlugin.getLatLng (), 15));
mMap.animateCamera (CameraUpdateFactory. zoomTo (19), 2000, null);
// Lets add the user position
GeoObject user = new GeoObject (1000l);
user.setGeoPosition(mWorld.getLatitude (), mWorld.getLongitude ());
user.setImageResource (R. drawable. flag);
user.setName («User position»);
mWorld.addBeyondarObject (user);
}
}
После запуска приложения на Android устройстве появится список с примерами.
Simple AR camera показывает набор изображений на фоне камеры. При этом изображения расположены в пространстве вокруг устройства.
Simple camera with a max/min distance far for rendering показывает набор изображений на фоне камеры с возможностью регулировки расстояния до изображений.
BeyondAR World in Google maps показывает набор изображений на карте.
AR camera with Google maps показывает набор изображений на фоне камеры с кнопкой переключения на карту.
Camera with touch events показывает набор изображений на фоне камеры, а также сообщение при нажатии на одном из изображений.
Camera with screenshot показывает набор изображений на фоне камеры с кнопкой скриншота.
Change GeoObject images on touch показывает набор изображений на фоне камеры, которые заменяются на другие изображения при нажатии.
Change GeoObject images on touch показывает набор изображений на фоне камеры, которые заменяются на другие изображения при нажатии.
Attach view to GeoObject показывает набор изображений на фоне камеры с добавлением вида к изображению при нажатии.
Set static view to geoObject вместо изображений показывает виды на фоне камеры, а также сообщение при нажатии на одном из видов.
Customize sensor filter показывает набор изображений на фоне камеры с возможностью регулировки чувствительности датчика ориентации.
Simple AR camera with a radar view показывает набор изображений на фоне камеры, а также расположение изображений вокруг устройства.
Using BeyondarLocationManager показывает набор изображений на карте с кнопкой обновления местоположения.
Для работы BeyondAR фреймворка в файле манифеста приложения декларируются необходимые разрешения и наличие сенсоров устройства.
<! Minimum permissions for Beyondar >
<uses-permission android:name="android.permission.CAMERA» />
<! For Beyondar this is not mandatory unless you want to load something from Internet (for instance images) >
<uses-permission android:name="android.permission.INTERNET» />
<! BeyondAR needs the following features >
<uses-feature android:name="android.hardware.camera» />
<uses-feature android:name="android.hardware.sensor.accelerometer» />
<uses-feature android:name="android.hardware.sensor.compass» />
Активность SimpleCameraActivity, отображающая набор изображений на фоне камеры, имеет достаточно простой код.
package com.beyondar. example;
import android. os. Bundle;
import android.support.v4.app.FragmentActivity;
import android.view. Window;
import com.beyondar.android.fragment.BeyondarFragmentSupport;
import com.beyondar.android. world. World;
public class SimpleCameraActivity extends FragmentActivity {
private BeyondarFragmentSupport mBeyondarFragment;
private World mWorld;
/** Called when the activity is first created. */
@Override
public void onCreate (Bundle savedInstanceState) {
super. onCreate (savedInstanceState);
// Hide the window title.
requestWindowFeature (Window. FEATURE_NO_TITLE);
setContentView(R.layout.simple_camera);
mBeyondarFragment = (BeyondarFragmentSupport) getSupportFragmentManager().findFragmentById(R.id.beyondarFragment);
// We create the world and fill it
mWorld = CustomWorldHelper.generateObjects (this);
// and send it to the fragment
mBeyondarFragment.setWorld (mWorld);
// We also can see the Frames per seconds
mBeyondarFragment.showFPS (true);
}
}
В методе onCreate создается фрагмент BeyondarFragmentSupport, отвечающий за отображение вида камеры и вида BeyondarGLSurfaceView, рисующего дополненную реальность.
Для этого используется файл компоновки.
<?xml version=«1.0» encoding=«utf-8»? >
<FrameLayout xmlns: android="http://schemas.android.com/apk/res/android"
android: layout_width=«match_parent»
android: layout_height=«match_parent»
android: id="@+id/parentFrameLayout»>
<fragment
android: id="@+id/beyondarFragment»
android:name="com.beyondar.android.fragment.BeyondarFragmentSupport»
android: layout_width=«match_parent»
android: layout_height=«match_parent» />
</FrameLayout>
Далее создается объект World контейнер объектов дополненной реальности, который затем добавляется во фрагмент BeyondarFragmentSupport.
Метод mBeyondarFragment.showFPS (true) показывает количество кадров в секунду в левом верхнем углу экрана.
Вся магия по созданию объектов дополненной реальности осуществляется в классе CustomWorldHelper.
Здесь создается новый контейнер World, устанавливается его местоположение в реальном мире, а также на основе изображений создаются объекты GeoObject, которые добавляются в контейнер World.
public static World sharedWorld;
sharedWorld = new World (context);
sharedWorld.setGeoPosition (41.90533734214473d, 2.565848038959814d);
GeoObject go4 = new GeoObject (4l);
go4.setGeoPosition (41.90518862002349d, 2.565662767707665d);
go4.setImageUri("assets://creature_7.png»);
go4.setName («Image from assets»);
sharedWorld.addBeyondarObject (go4);
По умолчанию для контейнера World и для его объектов, в классе CustomWorldHelper, задаются фиксированные координаты в реальном мире. Исправим это, привязав координаты контейнера World к местоположению устройства.
Для определения местоположения устройства используем Fused location provider API (Android API Level> v9, Android Build Tools> v21).
Изменим код классов CustomWorldHelper, GoogleMapActivity и SimpleCameraActivity.
import android.annotation.SuppressLint;
import android.content.Context;
import android. location. Location;
import android.widget.Toast;
import com.beyondar.android.world.GeoObject;
import com.beyondar.android. world. World;
@SuppressLint («SdCardPath»)
public class CustomWorldHelper {
public static final int LIST_TYPE_EXAMPLE_1 = 1;
public static World sharedWorld;
public static World generateObjects (Context context, Location mCurrentLocation) {
sharedWorld = new World (context);
// The user can set the default bitmap. This is useful if you are
// loading images form Internet and the connection get lost
sharedWorld.setDefaultImage(R.drawable.beyondar_default_unknow_icon);
// User position (you can change it using the GPS listeners form Android
// API)
if (mCurrentLocation== null) {
mCurrentLocation=new Location (»»);
mCurrentLocation.setLatitude (41.90533734214473d);
mCurrentLocation.setLongitude (2.565848038959814d);
}
sharedWorld.setGeoPosition(mCurrentLocation.getLatitude(),mCurrentLocation.getLongitude ());