For more technical insights, check out LoopBack on GitHub:
10 |github.com/strongloop/loopback
11 |and our extended documentation:
12 | 13 |To keep coding, poke around the Android project. For instance, 14 | have a look at the way the app shares a single instance of RestAdapter 15 | through GuideApplication, or read through more of the comments 16 | in the Lesson Fragments.
17 | ]]>20 |
21 | callback@strongloop.com 22 |
23 | ]]>The next three Lessons will teach you a little about LoopBack, 27 | a self-hosted and open-source mobile API tier from StrongLoop.
28 |Let\'s not waste any time with words. This is a simple 29 | Fragment - just swipe to the next page to get started.
30 | ]]>This form creates a new Ammo model on the server. 34 | Ammo, mind you has no pre-defined format!
35 |See LessonOneFragment.java for implementation details, 36 | paying special attention to the AmmoModel class and 37 | the LessonOneFragment.sendRequest method. 38 | ]]>
For more technical insights, check out LoopBack on GitHub:
10 |github.com/strongloop/loopback
11 |and our extended documentation:
12 | 13 |To keep coding, poke around the Android project. For instance, 14 | have a look at the way the app shares a single instance of RestAdapter 15 | through GuideApplication, or read through more of the comments 16 | in the Lesson Fragments.
17 | ]]>20 |
21 | callback@strongloop.com 22 |
23 | ]]>The next three Lessons will teach you a little about LoopBack, 27 | a self-hosted and open-source mobile API tier from StrongLoop.
28 |Let\'s not waste any time with words. This is a simple 29 | Fragment - just swipe to the next page to get started.
30 | ]]>This form creates a new Note model on the server. 34 | Note, mind you has no pre-defined format!
35 |See LessonOneFragment.java for implementation details, 36 | paying special attention to the NoteModel class and 37 | the LessonOneFragment.sendRequest method. 38 | ]]>
220 | * If it isn't installed {@link SupportMapFragment} (and 221 | * {@link com.google.android.gms.maps.MapView MapView}) will show a prompt for the user to 222 | * install/update the Google Play services APK on their device. 223 | *
224 | * A user can return to this FragmentActivity after following the prompt and correctly
225 | * installing/updating/enabling the Google Play services. Since the FragmentActivity may not
226 | * have been completely destroyed during this process (it is likely that it would only be
227 | * stopped or paused), {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)}
228 | * may not be called again so we should call this method in {@link #onResume()}
229 | * to guarantee that it will be called.
230 | */
231 | private void setUpMapIfNeeded() {
232 | canDisplayMap = detectGoogleMapsSupport();
233 |
234 | if (!canDisplayMap) {
235 | setupAlternateView();
236 | return;
237 | }
238 |
239 | setupMapView();
240 | }
241 |
242 | private void setupMapView() {
243 | // Do a null check to confirm that we have not already
244 | // instantiated the fragment.
245 | if (mapFragment == null)
246 | mapFragment = new SupportMapFragment();
247 | replaceMapFrame(mapFragment);
248 | }
249 |
250 | private void setupAlternateView() {
251 | // Do a null check to confirm that we have not already
252 | // instantiated the fragment.
253 | if (listFragment == null)
254 | listFragment = new LocationListFragment();
255 | replaceMapFrame(listFragment);
256 | }
257 |
258 | private void replaceMapFrame(final Fragment newFragment) {
259 | final FragmentManager fragmentManager = getChildFragmentManager();
260 | final FragmentTransaction transaction = fragmentManager.beginTransaction();
261 | transaction.replace(R.id.map_frame, newFragment);
262 | transaction.commit();
263 | }
264 |
265 |
266 | boolean detectGoogleMapsSupport() {
267 | // 1. Check for OpenGL ES 2.0
268 | final ActivityManager activityManager =
269 | (ActivityManager)getActivity().getSystemService(Context.ACTIVITY_SERVICE);
270 | final ConfigurationInfo configurationInfo =
271 | activityManager.getDeviceConfigurationInfo();
272 | if (configurationInfo.reqGlEsVersion < 0x20000) {
273 | Log.w("LessonThreeFragment", "Device does not support OpenGL ES 2.0");
274 | return false;
275 | }
276 |
277 | // 2. Check for Google Play Services availability
278 | final int playServicesStatus =
279 | GooglePlayServicesUtil.isGooglePlayServicesAvailable(getActivity());
280 | if (playServicesStatus != ConnectionResult.SUCCESS
281 | && Build.HARDWARE.contains("golfdish")) {
282 | // It's not possible to install or update Google Play on an emulator
283 | Log.w("LessonThreeFragment",
284 | "Detected an emulator with missing or outdated Play Services.");
285 | return false;
286 | }
287 |
288 | Log.i("LessonThreeFragment", "Locations will be displayed in Google Maps.");
289 | return true;
290 | }
291 |
292 | public static class LocationListFragment extends Fragment {
293 | ViewGroup rootView;
294 |
295 | @Override
296 | public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
297 | final Bundle savedInstanceState) {
298 |
299 | rootView = (ViewGroup) inflater.inflate(
300 | R.layout.fragment_location_list, container, false);
301 | return rootView;
302 | }
303 |
304 | public ListView getList() {
305 | return (ListView) rootView.findViewById(R.id.list);
306 | }
307 | }
308 | }
309 |
--------------------------------------------------------------------------------
/LoopbackGuideApplication/src/com/strongloop/android/loopback/guide/lessons/LessonThreeFragment.java:
--------------------------------------------------------------------------------
1 | package com.strongloop.android.loopback.guide.lessons;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 | import java.util.Map;
6 |
7 | import org.json.JSONArray;
8 | import org.json.JSONException;
9 | import org.json.JSONObject;
10 |
11 | import android.annotation.SuppressLint;
12 | import android.app.ActivityManager;
13 | import android.content.Context;
14 | import android.content.pm.ConfigurationInfo;
15 | import android.location.Location;
16 | import android.os.Build;
17 | import android.os.Bundle;
18 | import android.support.v4.app.Fragment;
19 | import android.support.v4.app.FragmentManager;
20 | import android.support.v4.app.FragmentTransaction;
21 | import android.util.Log;
22 | import android.view.LayoutInflater;
23 | import android.view.View;
24 | import android.view.ViewGroup;
25 | import android.widget.ArrayAdapter;
26 | import android.widget.Button;
27 | import android.widget.ListView;
28 | import android.widget.TextView;
29 | import android.widget.Toast;
30 |
31 | import com.google.android.gms.common.ConnectionResult;
32 | import com.google.android.gms.common.GooglePlayServicesUtil;
33 | import com.google.android.gms.maps.CameraUpdateFactory;
34 | import com.google.android.gms.maps.GoogleMap;
35 | import com.google.android.gms.maps.SupportMapFragment;
36 | import com.google.android.gms.maps.model.LatLng;
37 | import com.google.android.gms.maps.model.MarkerOptions;
38 | import com.google.common.collect.ImmutableMap;
39 | import com.strongloop.android.loopback.Model;
40 | import com.strongloop.android.loopback.ModelRepository;
41 | import com.strongloop.android.loopback.RestAdapter;
42 | import com.strongloop.android.loopback.guide.GuideApplication;
43 | import com.strongloop.android.loopback.guide.R;
44 | import com.strongloop.android.loopback.guide.util.HtmlFragment;
45 | import com.strongloop.android.remoting.adapters.Adapter;
46 |
47 | /**
48 | * Implementation for Lesson Three: Don't Outgrow, Outbuild.
49 | */
50 | public class LessonThreeFragment extends HtmlFragment {
51 | final LatLng MY_POSITION = new LatLng(37.56572191237293, -122.32357978820802);
52 |
53 | /**
54 | * Loads all Locations from the server, passing them to our MapView
55 | * to be displayed as pins.
56 | */
57 | private void sendRequest() {
58 | // 1. Grab the shared RestAdapter instance.
59 | final GuideApplication app = (GuideApplication)getActivity().getApplication();
60 | final RestAdapter adapter = app.getLoopBackAdapter();
61 |
62 | // 2. Instantiate our ModelRepository. Rather than create a subclass
63 | // this time, we'll use the base classes to show off their off-the-shelf
64 | // super-powers.
65 | final ModelRepository
255 | * If it isn't installed {@link SupportMapFragment} (and
256 | * {@link com.google.android.gms.maps.MapView MapView}) will show a prompt for the user to
257 | * install/update the Google Play services APK on their device.
258 | *
259 | * A user can return to this FragmentActivity after following the prompt and correctly
260 | * installing/updating/enabling the Google Play services. Since the FragmentActivity may not
261 | * have been completely destroyed during this process (it is likely that it would only be
262 | * stopped or paused), {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)}
263 | * may not be called again so we should call this method in {@link #onResume()}
264 | * to guarantee that it will be called.
265 | */
266 | private void setUpMapIfNeeded() {
267 | canDisplayMap = detectGoogleMapsSupport();
268 |
269 | if (!canDisplayMap) {
270 | setupAlternateView();
271 | return;
272 | }
273 |
274 | setupMapView();
275 | }
276 |
277 | private void setupMapView() {
278 | // Do a null check to confirm that we have not already
279 | // instantiated the fragment.
280 | if (mapFragment == null)
281 | mapFragment = new SupportMapFragment();
282 | replaceMapFrame(mapFragment);
283 | }
284 |
285 | private void setupAlternateView() {
286 | // Do a null check to confirm that we have not already
287 | // instantiated the fragment.
288 | if (listFragment == null)
289 | listFragment = new LocationListFragment();
290 | replaceMapFrame(listFragment);
291 | }
292 |
293 | private void replaceMapFrame(final Fragment newFragment) {
294 | final FragmentManager fragmentManager = getChildFragmentManager();
295 | final FragmentTransaction transaction = fragmentManager.beginTransaction();
296 | transaction.replace(R.id.map_frame, newFragment);
297 | transaction.commit();
298 | }
299 |
300 |
301 | boolean detectGoogleMapsSupport() {
302 | // 1. Check for OpenGL ES 2.0
303 | final ActivityManager activityManager =
304 | (ActivityManager)getActivity().getSystemService(Context.ACTIVITY_SERVICE);
305 | final ConfigurationInfo configurationInfo =
306 | activityManager.getDeviceConfigurationInfo();
307 | if (configurationInfo.reqGlEsVersion < 0x20000) {
308 | Log.w("LessonThreeFragment", "Device does not support OpenGL ES 2.0");
309 | return false;
310 | }
311 |
312 | // 2. Check for Google Play Services availability
313 | final int playServicesStatus =
314 | GooglePlayServicesUtil.isGooglePlayServicesAvailable(getActivity());
315 | if (playServicesStatus != ConnectionResult.SUCCESS
316 | && Build.HARDWARE.contains("golfdish")) {
317 | // It's not possible to install or update Google Play on an emulator
318 | Log.w("LessonThreeFragment",
319 | "Detected an emulator with missing or outdated Play Services.");
320 | return false;
321 | }
322 |
323 | Log.i("LessonThreeFragment", "Locations will be displayed in Google Maps.");
324 | return true;
325 | }
326 |
327 | public static class LocationListFragment extends Fragment {
328 | ViewGroup rootView;
329 |
330 | @Override
331 | public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
332 | final Bundle savedInstanceState) {
333 |
334 | rootView = (ViewGroup) inflater.inflate(
335 | R.layout.fragment_location_list, container, false);
336 | return rootView;
337 | }
338 |
339 | public ListView getList() {
340 | return (ListView) rootView.findViewById(R.id.list);
341 | }
342 | }
343 | }
344 |
--------------------------------------------------------------------------------