Zachary Powell

Software Programmer

Zachary Powell

Download my CV Send me a Message

Android

Samsung Galaxy S6 Edge – One Strange but loveable device

Zachary Powell - 01/01/2016

Intro

I change my device pretty often, at least yearly if not more often. I have in the past, owned a number of Samsung devices as well as phones from other various brands. From memory, my order of devices owed to my main day to day device:

  • HTC Magic
  • HTC Desire S
  • Samsung Note
  • Nexus 4
  • Samsung Note 3
  • Nexus 5
  • Samsung Note 4
  • Samsung S6 Edge

I have also owned, and have, a range of other devices for testing and development work, but these above have been my devices used as the day to day phone, not just a development tool. In this review, I will look over the Edge S6 as both a day to day device, and a development tool. For me, both are important. I want a phone that will keep up with my daily usage, many phone calls, text, emails, skype and also something that can be used to test new software.

Hardware

Lets first look at the device itself. Without solid hardware, a device simply wont keep up, no matter how good the software is. I am a heavy multi tasking user and have in the past found devices struggle to keep up and keep apps running.

The device itself has a glass front and rear, with the thin metal strip around the edge. If it was not for this strip, I think the device would be very difficult to hold. The glass is pretty slippery, and when holding it in your hand you really do feel like it could just slide out. Of course Samsung have now turned to the ‘darkside’. This phone is completely sealed – no replacing batteries or actually anything without a lot of time and heat pads (https://www.ifixit.com/Teardown/Samsung+Galaxy+S6+Edge+Teardown/39158). We also no longer get a SDcard slot. This sucks, but at 32GB, the phone has more than enough memory for me.

The front of the device has the normal Samsung layout of a hardware ‘home’ button, which this time round also doubles up as the finger print reader, along with two touch buttons, a back and a recent apps button. Personally, I like having the hardware keys, leaving all the screen free for apps etc, which on a smaller phone helps a lot.

2015-12-30 09.01.49

On the left side we have the volume rocker and on the right the power button. When holding the phone in your right hand, these positions are perfect – the volume rocker is easily reached with my index finger and the power button my thumb. This might be because of having larger phones in the past, but the general size of the phone seems perfect in my hand, small enough to hold and use one handed, but still big enough for the screen high resolution to be worth it.

2015-12-30 09.03.50 2015-12-30 09.04.05

On the top we find the SIM card slot, IR transmitter and a microphone. This might seem like quite an odd position for the SIM card slot, but because of the curved screen we are not left with very much thickness on either side. The top side is really the only location it could now fit.

2015-12-30 09.03.58

Finally along the bottom we have the 3.5 headphone jack, micro USB (no USB-C here) port, another microphone and one lone speaker.

2015-12-30 09.03.25

Spec

The specs of the Edge S6 has the same internal hardware as the S6, the only real difference being the funky curved screen. I will look at this more shortly but first the devices complete spec:

  • Screen – Curved 5.1 inch screen with a resolution of 1440 x 2560 pixels (~577 ppi pixel density)
  • Chipset – Exynos 7420
  • Storage – 32GB
  • RAM – 3GB

For the complete spec check out

http://www.gsmarena.com/samsung_galaxy_s6_edge-7079.php

Nothing hugely different here to most flagships, although this is the first Exynos device I have used. It will be very interesting to see how far Samsung have come with their own SoC (System on Chip).

A quick run of some bench marks have given the below results. While benchmarks are not always a good example of real world performance, they are a great place to start!

2015-12-29 22.35.02 2015-12-29 22.33.38 2015-12-29 22.32.06

That Screen!

Of course the main selling point of the S6 Edge is its curved screen. Other than this, it is just the S6 after all, but what a screen it is! While the curve itself has little use in terms of functionality, it does change the shape of the phone in a way ,that I feel, makes the phone much easier to hold and gives the effect that its much thinner than it actually is.

2015-12-30 09.01.49

Other than the curve, the screen is a beautiful AMOLED panel, which produces an amazing colour range, and of course perfect blacks. The viewing angles are pretty damn perfect as well. This honestly has to be the best screen I have ever seen on a device.

Camera

As with every years flagship phones from Samsung, they have bumped the cameras spec, producing some really lovely images. The front camera is not really anything to write home about. It works and produces OK images in low light, but is just a standard front facing camera. If you’re a selfie lover, this might not be a selling point for you.

Personally, one of the points I look for in a new daily use phone is a good rear camera. As you may have noticed from the (pretty awful) photos of the phone in this post, I do not own a stand alone camera. I am by no means a photographer and never justified buying one. I am glad (for your sake as well as mine) that this phone lives up to that goal. Although its very dark and pretty miserable outside, the phone does a pretty good job at capturing detailed images both in low light and well lit areas.

BB-8 in a well lit room before his next advantage freaking out the dogs

BB-8 in a well lit room before his next advantage freaking out the dogs

Blaine in a dim room who does not stay still for more than a few seconds!

Blaine in a dim room who does not stay still for more than a few seconds!

The depressing weather outside...

The depressing weather outside…

Fingerprint Reader

I just wanted to stop by that other interesting hardware point of this years Samsung flagship phones, the fingerprint reader. I have used a number of readers in the past, all the way back to the Motorola Atrix, but this is the first one that actually works more times than doesn’t. Setting up new fingers is very easy to do and just involves pressing the finger on the home button a number of times so it can record from all angles. The more angles you do, the better the final result. To unlock the phone all you now have to do is press down the home button (to wake it) and hold your finger on the button for a few seconds to allow the reader to pick up your finger.

While from time to time it does fail to pick up the finger it does a pretty good job, and is finally to a point where fingerprint readers are a viable and useful method for locking and securing a phone.

Software

Over the years, Samsung have been slated for their Android “skin” TouchWiz and the large amount of extra apps they preload on devices, causing many of their older flagship phones to struggle with multi tasking due to a lack of any free RAM. After picking up my S6 Edge, Samsung announced on twitter that they where doing an open beta test of the new Android 6.0 update for all UK owners. Of course, I jumped at the chance to give marshmallow a go and updated right away.

This does mean that the software I am reviewing is very much subject to change, although even as a beta I have struggled to find any crashes or slow-downs.

Android 6.0

2015-12-30 09.05.01

Above is the current build my phone is running. We are looking at Android 6.0 (interestingly not 6.0.1) with all the normal Samsung extras (KNOX etc).

2015-12-30 09.45.03 2015-12-30 09.04.48

Over the years, Samsung have slowly dialed back the bloat that is including on their devices, and the newest version of TouchWiz is no different. Now only a handful of “S” apps are included by default and, like with the last generation, while you can not uninstall these apps, you can “disable” them, which stops them running and removes them from your app launcher.

I do hope Samsung makes some final adjustments to their skin before it launches, as stable as above is, an example of a couple of points where they have really missed the mark on design. The White background with Blue highlights for the notification draw looks really bad. It might be a personal thing, but I really don’t like it. The same can be said for the “bubbles” around app icons that are not Samsung apps. Again,  what is going on here !?!  OK, it does say a lot about how far they have come.

TouchWiz growing up

But I do feel that the newest version is a step back from their Android 5.0/1 software originally shipped with the device.

2015-12-30 09.43.16 2015-12-30 09.05.12 2015-12-30 09.05.29

This reduction of “bloatware” really can be felt. Along with the Android 6.0 improvements we now get about 1.1GB of free RAM for apps to gobble up – still not as great as other more stock android devices, but its not a bad result by Samsung and the phone really does fly. Many of the apps have also be updated with a new colour pallet which overall I do really like. It is strange to me that they can come up with some really nice simple design work for the apps like the above Phone and “Smart Manager” apps, but then miss the boat by so much with the launcher.

The Camera app itself also get a nice bump in features, with all the normal features but now with the option to shoot in RAW. Again, a great feature for someone like me who doesn’t have a DLSR, but may well want to use the added benefits of the RAW file format.

Wrap up

The Samsung S6 Edge is certainly a strange device. Does the curved screen really bring much to the game? I am not convinced, but what it does do, is allow the device to feel much thinner and I like that.

Other than that this is the same device as the S6, but that is not a bad thing at all. The hardware is solid and well built as you expect from Samsung and the new addiction of Android 6.0 brings some really nice extra features and an always welcome speed boost.

This is a phone that I would certainly recommend to anyone looking to get a new flagship phone and of cause, the S7 will be just around the corner and likely bring even more improvements, but in the fast moving world of phone hardware you can not stand waiting around because a new device will always be around the corner.

As always, please comment below with any questions.

Leave a Reply

Your email address will not be published. Required fields are marked *

Tags: ,

Apps I use on Nexus 9

Zachary Powell - 18/12/2015

My Nexus 9 is the next most used device within my work flow. I use it a lot through-out the day, both during my free time to play games, read books and magazines. But today, I want to take a moment to look at a few of the apps I use more during a day of work.

Dropbox

dropbox

Dropbox is my file sharing/backup cloud of choice. As I’m sure you know, there are a huge range of these systems available (Google drive, Onedrive, iCloud etc), but I have found that Dropbox is the only solution that works seamlessly across Windows/OSX/Ubuntu/Android/iOS and allows me to keep backups of my files from all Operating systems.

I use dropbox on my tablet to keep photos backed up, but also easily access any of my files I might need when I’m out and about. If a client needs to see a design for example, I will always have access to it.

The tablet app is also a great example of clean simple design. No fluff, just right to your data.

500px-Get_it_on_Google_play.svg

VLC

vlc

VLC is another great example of a program I use across the board. When I need to play a video file, I know that it can be played on VLC no problem. From time to time, a client might send me a video for something and with VLC I just know it will work. Again, I love using this app because of its material design and simple easy to use layout.

500px-Get_it_on_Google_play.svg

Teamviewer

teamviewer

Another big use for my tablet is accessing other computers remotely. These might be my own devices or clients. Often they need me to show them how to use software I have developed or have questions about certain features. Teamviewer allows me to do this pretty seamlessly, connecting to any device on any operating system quickly. I often leave my Mac at home and might just need to run a program while I’m out, or check on the progress of a new software build.

500px-Get_it_on_Google_play.svg

JuiceSSH

juicessh

As well as connection to full computers via Teamviewer, I also have a couple of headless servers, including a couple of Raspberry pi’s doing different tasks. One is a media server and another managers my local backup system. I also have a couple of remote servers for web development and other tasks. Using JuiceSSH, I can remotely connect to all of these via my tablet to easily check on them or run tasks.

500px-Get_it_on_Google_play.svg

Turbo Client

turbo-client

Again, just like the above two programs, I use Turbo Client to connect to servers via FTP. I have FTP servers running on my backup server and my remote servers, so if I need to access files remotely from these servers, this is the best app to use. Again it has a lovely clean design and makes accessing files very quick and easy.

500px-Get_it_on_Google_play.svg

Gmail

gmail

When I’m not out and working at my desk instead, the Nexus 9 works as a great extra screen. I tend to keep to just a couple of Apps while I’m at my desk, and most of the above apps are easier from a desktop, with far more screen space. However, what I do tend to use is either Gmail or Skype. Using Gmail on the tablet works great as a dedicated gmail terminal, as emails come in I can quickly glance down at the tablet (positioned below my main computer monitor) and read them, without stopping my current work flow. If they need a response too, I can bring up the desktop client to do such at a time that is suitable.

500px-Get_it_on_Google_play.svg

Skype

skype

The other app I will use while at my desk is Skype. Often this is used to speak with clients via video/voice chat or even via text. If I am having a busy day on Skype, I will move this to the tablet again so it does not disrupt my main work flow.

500px-Get_it_on_Google_play.svg

This is the first non development post. I will do these from time to time, explore my different work flows (what programs I use on the desktop etc), as well as reviewing hardware and software from time to time.

If you have anything you would like me to review or talk about, please comment below!

Leave a Reply

Your email address will not be published. Required fields are marked *

Tags: , ,

Adding custom Markers to Google Map

Zachary Powell - 17/12/2015

At this point, we have quite a nice little Google map application and we can now get the users location and display it on a Google map (see HERE if you have not caught up yet).

Now this works well, but what if we want to display extra data on the map? Perhaps there are locations that we want to highlight to the user. Below we will explore how we can add custom markers to the map and what can be done with them.

Plot marker with default pin

The most basic marker can be added with just a few lines of code.

LatLng position = new LatLng(53.779558, -4.042969);
MarkerOptions markerOption = new MarkerOptions().position(position);

markerOption.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE));
markerOption.title("Marker with default Pin");
mMap.addMarker(markerOption);

First we create the LatLng for the position we want to put the pin in (this is just a random point near England). We can then use the MarkerOptions object to set a few custom options. For the most simple, we can leave this with just the initial code, but we can also change many settings for the Marker – See HERE.

Changing the Icon, we can use the default section of marker colours.

We can also set the title. This is displayed when the user clicks the marker like below.

Screenshot_20151214-114449  Screenshot_20151214-114454

Plot marker with custom image

A great way to customise these pins, is to use our own image for the pin. For example:

private void plotMarkerWithCustomImage(){
    LatLng position = new LatLng(53.784426, -1.735840);
    MarkerOptions markerOption = new MarkerOptions().position(position);

    markerOption.icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_launcher));

    markerOption.title("Marker with custom image");
    mMap.addMarker(markerOption);
}

Gives us the below:

Screenshot_20151214-120522Screenshot_20151214-120526

Plot marker with canvas

Another more complex method, is to use a canvas to display other information in the marker itself. For example:

private void plotMarkerWithCanvas(){
   LatLng position = new LatLng(53.209322, -3.405762);
   MarkerOptions markerOption = new MarkerOptions().position(position);

   Bitmap.Config conf = Bitmap.Config.ARGB_8888;
   Bitmap bmp = Bitmap.createBitmap(80, 80, conf);
   Canvas canvas1 = new Canvas(bmp);

   Paint color = new Paint();
   color.setTextSize(35);
   color.setColor(Color.BLACK);

   canvas1.drawBitmap(BitmapFactory.decodeResource(getResources(),
                R.drawable.ic_launcher), 0,0, color);

   canvas1.drawText("User Name!", 30, 40, color);

   markerOption.icon(BitmapDescriptorFactory.fromBitmap(bmp));

   markerOption.title("Marker with canvas");
   mMap.addMarker(markerOption);
}

Here we create a new Bitmap image and a Canvas on that image. We can then create any custom Bitmap that we want. For example, adding text to the image, or loading another bitmap onto it.

Once created we can use this to set the icon. The above would give us:

Screenshot_20151214-121324 Screenshot_20151214-121328

For the complete example, as always check out the github project HERE. If you have any comments or questions please ask below

 

Leave a Reply

Your email address will not be published. Required fields are marked *

Tags: , ,

Display Users current location on Google Map

Zachary Powell - 14/12/2015

Before starting this guide, check out the Google Map example HERE if you have not already read it.

Now that we have a working Map, there is a range of examples we can cover. One that is very widely required, is displaying the users current location. When using a map, it is often the case that the user will want to be able to see where they currently are. Below we will explore what needs to be added to our Google Map example to display the users current location and update the marker as the user moves.

Manifest Changes

First we need to set some permissions in the Android manifest of our project. In Android studio, open the Manifest folder and open AndroidManifest.xml

We then need to add the below lines to manifest our side of the application tag.

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />

If you are using my Google Map Example code your manifest should then look like this:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.zpwebsites.basicgooglemapexample">

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />


    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        
        <meta-data
            android:name="com.google.android.geo.API_KEY"
            android:value="@string/google_maps_key" />

        <activity
            android:name=".MapsActivity"
            android:label="@string/title_activity_maps">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

These permissions are required to get the users current location. We want the file location when available, but if there is no GPS connection, the coarse location can be used to get a rough user location based on a mobile signal.

Centre Map on Current Location

We are going to create a method called centerMapOnMyLocation(). This will be called once the map is loaded and will grab the users current location using GPS if available. The complete method:

private void centerMapOnMyLocation() {
        LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        Criteria criteria = new Criteria();

        Location location = null;

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {

            location = locationManager.getLastKnownLocation(locationManager.getBestProvider(criteria, false));
        }

        if (location != null)
        {
            Long = location.getLongitude();
            Lat = location.getLatitude();
            mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(
                    new LatLng(location.getLatitude(), location.getLongitude()), 13));

            CameraPosition cameraPosition = new CameraPosition.Builder()
                    .target(new LatLng(location.getLatitude(), location.getLongitude()))      // Sets the center of the map to location user
                    .zoom(17)                   // Sets the zoom
                    .bearing(0)                // Sets the orientation of the camera to east
                    .tilt(40)                   // Sets the tilt of the camera to 30 degrees
                    .build();                   // Creates a CameraPosition from the builder
            mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
        }else{
            mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(53.779558, -4.042969), 5.5f));
            CharSequence text = "Sorry, we where unable to get your location, please check your GPS";
            int duration = Toast.LENGTH_LONG;
            Toast.makeText(this.getBaseContext(), text, duration).show();
        }
    }

First we set up a couple of variables which will be used within the method.

LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
Location location = null;

The LocationManager will be used to get the current location from the system. This handles querying the GPS for the location. The Location object will then be used to store the Location that is returned by the LocationManager.

if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            location = locationManager.getLastKnownLocation(locationManager.getBestProvider(criteria, false));
        }

Next, as of Android API level 23 (Android version 6.0), we now have to check that the permissions we require have been accepted by the user. If they have been accepted, we can go ahead and use the LocationManager to call the .getLastKnownLocation(). This will return the last location from the system. If GPS is available, this will return the current location.

if (location != null)
        {
            Long = location.getLongitude();
            Lat = location.getLatitude();
           
            CameraPosition cameraPosition = new CameraPosition.Builder()
                    .target(new LatLng(Lat, Long))      // Sets the center of the map to location user
                    .zoom(17)                   // Sets the zoom
                    .bearing(0)                // Sets the orientation of the camera to east
                    .tilt(40)                   // Sets the tilt of the camera to 30 degrees
                    .build();                   // Creates a CameraPosition from the builder
            mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
        }

If the location has been returned, we can then get the locations longitude and latitude using the getter methods.  Once we have the location in the form of co-ordinates, we build a CameraPosition object, setting the target to the users position and setting up other camera settings, zoom level, bearing and tilt.

Finally, by passing this CameraPosition object to the animateCamera() method of the Google map object, we can move the maps view to centre on the users location.

else{
            mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(53.779558, -4.042969), 5.5f));
            CharSequence text = "Sorry, we where unable to get your location, please check your GPS";
            int duration = Toast.LENGTH_LONG;
            Toast.makeText(this.getBaseContext(), text, duration).show();
        }

We then use an else statement to cover if the location was not returned, either because the user declined the permissions or for some reason, theLocationManager failed to return the location object. In this else statement, we just move the camera to a pre-defined location and display a Toast message to let the user know we failed to get their position.

Then we need to edit our onMapRead() function to call our centerMapOnMyLocation() method, once our map is ready to use. We also call setMyLocationEnabled(true) so that the map will display a marker at the users location.

public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;
        mMap.setMyLocationEnabled(true);
        centerMapOnMyLocation();
}

Using LocationListener to update the users location

At this point, we have an app that centres to the users location on starting up the map, but if the user then moves it will not update the map. This is where we need to set up a LocationListener to monitor for location changes and update the map accordingly.

LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
        LocationListener locationListener = new LocationListener() {
            public void onLocationChanged(Location location) {
                Long = location.getLongitude();
                Lat = location.getLatitude();
            }

            public void onStatusChanged(String provider, int status, Bundle extras) {
            }

            public void onProviderEnabled(String provider) {
            }

            public void onProviderDisabled(String provider) {
            }
        };

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
        }

Within the onCreate() method we add the above code. This sets up a LocationManager and a LocationListener. The LocationManager is the same as before using the Location service, while the LocationListener sets up the code to be run when a location changes. Within the onLocationChanged() method, we get the new Longitude and Latitude and update our Long and Lat variables.

Then, we need to run the same check to make sure the user has accepted our permissions again. If they have, we can then go ahead and register the LocationListener with the LocationManager. This allows the onLocationChanged() code to be run when the users location changes.

Complete Example

Once we have added all the above code, the app can not be run and display the current users location.

If you would like to check out the complete applications code, you can find it HERE. This code will be updated in the future to hold all example code for Google Maps.

As always if you have any questions please comment below.

Leave a Reply

Your email address will not be published. Required fields are marked *

Tags: , , ,

Using Google Maps within Android app

Zachary Powell - 11/12/2015

Don’t worry, there is a pattern to my posts, honestly! All will become clear further down the line.

Google has a range of great APIs and extras, and one that comes in pretty handy from time to time, is the Google Maps API. This allows you to display a custom Google Map within your own application. This is useful if you have any location based information you might want to display *cough* buildings *cough*

Google actually has a pretty good guide on the subject over at https://developers.google.com/maps/documentation/android-api/start. Do check it out, Though, I will cover all your need below and its worth a read for extra tips and hints!

Set up

For this (and all Android) guide we will be using Android studio. It is now the only supported IDE by Google and has come a long way in the few years its been in development. If you are not already using it, download and install Android Studio now.

Next, (again if you have not already) make sure to install the Google Play services package into the Android SDK, details of this are to be found HERE.

Creating Activity that displays map

Screen Shot 2015-12-08 at 13.43.43

The easiest way to create a new activity that displays a Google Map is by using Android studios built in “New Activity” menu. As long as you have the above set up correctly, you will see in this list the option for a “Google Map Activity”. This will create all the files needed and handle the basic set up. Now that is all well and good, but lets actually have a look at what is created and what the code that has been generated does.

MapsActivity.java

The activity file that handles the actual code, the generated code:

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {

    private GoogleMap mMap;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_maps);
        // Obtain the SupportMapFragment and get notified when the map is ready to be used.
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);
    }
    
    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;

        LatLng sydney = new LatLng(-34, 151);
        mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
        mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
    }
}

As you can see, the code required is actually pretty minimal to get a map displayed. The main code that is important is within the onCreate() method. Here we set up the MapFragment view and then fire off the fragments getMapAsync() method. This handles the background code to actually connect to the Google Map API and load a new map.

The onMapReady() method then takes care of any post processing we want to do on the Map. Here we set up the private GoogleMap variable to allow us to manipulate the Map from other methods within our activity.

We then set up an example LatLng object. We are using Sydney, but of course it could be any location in the world.

LatLng sydney = new LatLng(-34, 151);

Then we add a basic marker to the map at the created location.

mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));

And finally we move the screen to focus to that location.

        mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));

activity_map.xml

This is the fragment view for the map, again very simple.

<fragment xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:map="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/map"
    android:name="com.google.android.gms.maps.SupportMapFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.zpwebsites.basicgooglemapexample.MapsActivity" />

Nothing special about this as we insert the map into the fragment from code.

google_map_api.xml

<resources>
    <string name="google_maps_key" templateMergeStrategy="preserve" translatable="false">YOUR_KEY_HERE</string>
</resources>

This is the final file created. Here is where we need to insert out API Key from Google to allow us to talk to the Google Map server and actually display a map.

Getting API Key

So now we have a very basic app ready to run, but if you try to run the app as it is, the map will not load. We need to get a API Key from Google to allow us to display the map.

To get this set up, follow the steps in the Google Guide HERE

Complete Example

Once you have added the key to your google_map_api.xml, you should now be able to run the application and see a map.

If you would like to checkout the complete applications code you can find it HERE. This code will be updated in the future to hold all example code for Google Maps.

As always if you have any questions please comment below.

Leave a Reply

Your email address will not be published. Required fields are marked *

Tags: , ,

Using SQLITE database to store data within Android App

Zachary Powell - 09/12/2015

In our last post, we explored using SharedPreferences to save data. This works well for simple primitive data, but if we have a more advanced data structure we will need a better way to store it. As with other programs we would look towards a database. Android supports SQLite Databases, so this is what we would use.

What is SQLite?

First and foremost, before we look at how we can use the SQLite database on Android, lets take a second to look at what SQLite actually is.

SQLite is an in-process library that implements a self-contained, serverless, zero-configuration, transactional SQL database engine. The code for SQLite is in the public domain and is thus free for use for any purpose, commercial or private. SQLite is the most widely deployed database in the world, with more applications than we can count, including several high-profile projects.

SQLite is an embedded SQL database engine. Unlike most other SQL databases, SQLite does not have a separate server process. SQLite reads and writes directly to ordinary disk files. A complete SQL database with multiple tables, indices, triggers and views, is contained in a single disk file. The database file format is cross-platform – you can freely copy a database between 32-bit and 64-bit systems or between big-endian and little-endian architectures. These features make SQLite a popular choice as an Application File Format. Think of SQLite not as a replacement for Oracle but as a replacement for fopen()

From – https://www.sqlite.org/about.html

Or more simply put SQLite is a very light and easy to use implementation of a SQL database, which does not require a server to run and is perfect for running on a phone.

Java Object Class

Lets first look at an example, simple object class. This will be the object we save to the database and the object we build when retrieving data back from the database. In our example, we will look at a database which holds a range of buildings. Each building will have its name, description, long and lat stored.

public class Building {
    String Name;
    String Decription;
    double Long;
    double Lat;

    Building(){
    }
    Building(String n, String d, double lo, double la){
        Name = n;
        Decription = d;
        Long = lo;
        Lat = la;
    }
    public double getLong() {
        return Long;
    }
    public double getLat() {
        return Lat;
    }
    public String getName() {
        return Name;
    }
    public String getDecription() {
        return Decription;
    }
    public void setName(String name) {
        this.Name = name;
    }
    public void setDesc(String desc) {
        this.Decription = desc;
    }
    public void setLong(double aLong) {
        this.Long = aLong;
    }
    public void setLat(double lat) {
        this.Lat = lat;
    }
    public String toString(){
        return "Name: " + Name + " Decription: " + Decription + " Long: " + Long + " Lat: " + Lat;
    }
}

This is a pretty standard object class with getters and setters set up as well as two construction methods, one that is empty and another that takes all the arguments. These will make creating and reading data much easier. Of course this is just an example of a data structure, you may wish to save to a database.

Database Handler

The Database Handler is the class that we will use to create and access the SQLite database. Below is the complete example which we will then brake down and explore.

public class DBHelper extends SQLiteOpenHelper {

    public static final String DATABASE_NAME = "locations.db";
    SQLiteDatabase db;

    public DBHelper(Context context)
    {
        super(context, DATABASE_NAME , null, 1);
        db = this.getWritableDatabase();
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE LocationInfo (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, Name TEXT, Description TEXT, Longitude TEXT, Lat TEXT)");
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS LocationInfo");
        onCreate(db);
    }

    public void clearLocations(){
        db = this.getWritableDatabase();
        db.execSQL("delete from LocationInfo");
        db.close();
    }

    public boolean insertLocation  (Building place) {
        db = this.getWritableDatabase();
        ContentValues contentValues = new ContentValues();
        contentValues.put("Name", place.getName());
        contentValues.put("Description", place.getDecription());
        contentValues.put("Longitude", place.getLong());
        contentValues.put("Lat", place.getLat());
        db.insert("LocationInfo", null, contentValues);
        db.close();
        return true;
    }

    public ArrayList<Building> getAllLocations()
    {
        db = this.getWritableDatabase();
        ArrayList<Building> array_list = new ArrayList();
        Cursor res;
        res =  db.rawQuery( "select * from LocationInfo", null );
       
        res.moveToFirst();
        while(res.isAfterLast() == false){
            BuildingLocation place = new BuildingLocation();
            place.setName(res.getString(res.getColumnIndex("Name")));
            place.setDesc(res.getString(res.getColumnIndex("Description")));
            place.setLat(res.getDouble(res.getColumnIndex("Lat")));
            place.setLong(res.getDouble(res.getColumnIndex("Longitude")));
            array_list.add(place);
            res.moveToNext();
        }
        db.close();
        return array_list;
    }
}

Lets brake this example down a little and go over the important parts.

Firstly, we extent our helper class with SQLiteOpenHelper. This is the Android class that handles the database creation.

Next we have the Constructor method for the database, this uses the SQLiteOpenHelper Constructor to create a database file with the name variable using:

super(context, DATABASE_NAME , null, 1);

The other two methods that we override from the parent class are the below:

@Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE LocationInfo (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, Name TEXT, Description TEXT, Longitude TEXT, Lat TEXT)");
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS LocationInfo");
        onCreate(db);
    }

The onCreate method is called when the database file is created. Here we run the SQL to create the table within the database file and here we create fields for all the fields with the Building object class. As with all SQL databases we also create and ID field that is auto-incremented.

The onUpgrade method is called if we need to make changes to a pre-existing database on a users device. For example, if we wanted to release an upgrade to our app that adds another field to the table, we run this method, it drops the table and then re-runs the onCreate.

The Next method clearLocations() is a simple example of method to interact with the database. Here we just run a SQL statement to clear the table of all data. The method takes no arguments and does not return anything. It is important to note that we must first open the database again, and once we have executed the SQL, we need to close the database.

The next method (below) is an example of a method used to insert data into the database

public boolean insertLocation  (Building place) {
        db = this.getWritableDatabase();
        ContentValues contentValues = new ContentValues();
        contentValues.put("Name", place.getName());
        contentValues.put("Description", place.getDecription());
        contentValues.put("Longitude", place.getLong());
        contentValues.put("Lat", place.getLat());
        db.insert("LocationInfo", null, contentValues);
        db.close();
        return true;
    }

Here we take a Building object as a argument. The safest and easiest way to then insert this data into the database is to create a ContentValues object. This allows you to “put” each primitive data  object from the Building object into a form that can be inserted into the database. The .put() method takes two argument. The first is the name of the table column and the second is the data you wish to put into that column.

Using the Building objects getter classes we load all the data we plan to store in the database for that Building object. Then using the .insert() method, we can pass the ContentValues object along with the name of the database table. Finally once again we close the database.

public ArrayList<Building> getAllLocations()
    {
        db = this.getWritableDatabase();
        ArrayList<Building> array_list = new ArrayList();
        Cursor res;
        res =  db.rawQuery( "select * from LocationInfo", null );
       
        res.moveToFirst();
        while(res.isAfterLast() == false){
            BuildingLocation place = new BuildingLocation();
            place.setName(res.getString(res.getColumnIndex("Name")));
            place.setDesc(res.getString(res.getColumnIndex("Description")));
            place.setLat(res.getDouble(res.getColumnIndex("Lat")));
            place.setLong(res.getDouble(res.getColumnIndex("Longitude")));
            array_list.add(place);
            res.moveToNext();
        }
        db.close();
        return array_list;
    }

Finally we have an example of a method to get data back out of the database. Here we use a Cursor object to move over the retrieved data. The SQL query we run simply returns a Cursor object with all the data in the table, but we may want to be more specific with the data we get back.

Using a whole loop, we then move over each object within the Cursor, using the method  .getColumnIndex() to return a columns index based on its name and then using the respected .get method depending on the data type. Using out Building objects setter classes we can then build up a building object to add to the array.

Once we have looped over the whole cursor object we can simply close the database and return our array of Building objects.

Example of Use

With the above, you have all you need to start working with databases within Android, but lets just take a second to see how we might use the above code within another method, perhaps an activity where the user enters a building details and saves them to the database. In  Below example we just set the values but the data could be taken from EditText view etc.

DBHelper mydb = new DBHelper(this);

String name = "Church";
String desc = "The tallest building in the village";
double longitude = 1.458375;
double Lat = 52.105336;

Building map = new Building();
map.setName(name);
map.setDesc(desc);
map.setLong(longitude);
map.setLat(Lat);
mydb.insertLocation(map);

As always if you have any questions feel free to comment below.

Leave a Reply

Your email address will not be published. Required fields are marked *

Tags: , ,

Using SharedPreferences in Android to store data

Zachary Powell - 06/12/2015

Shared Preferences are a great way to store primitive data types across user sessions.

What does this mean? Using Shared Preferences, you can save some form of data (string, boolean, integer…) in a way that means your app can retrieve that data at any point even after the app has been exited. This, as you might have guessed, is designed to allow you to save settings that the user might set within your app and that is the example we will use.

Shared Preferences are very simple to use. With just a couple of methods you can set and get your saved data with no need to worry about files or parsing the data. In the background, Shared Preferences are actually stored in a file within your Applications data directory. As such, it is important to note that while a normal user would not have access to this file, if the users device is rooted, they could access and manually edit this file. It is not recommended to use this for storing if a user has unlocked a paid features for example.

Setting a Shared Preference

Setting and getting a shared preference are very easy tasks, but it makes sense to set before we get.

First we create a SharedPreference object and initialise it as below:

SharedPreferences sharedPref = getSharedPreferences("MyPref", Context.MODE_PRIVATE);

getSharedPreferences takes two arguments, the first a string. This is the name of our preference file – if this file does not already exist it will be created. The second argument is an integer, which defines the operating mode. Possible values are:

  • Context.MODE_PRIVATE (value 0) – The preference file can only be accessed by the application that created it. This is the default operation mode.
  • Context.MODE_WORLD_WRITEABLE (value 2) – The preference file can be written to by all applications. This mode was deprecated in API 17 due to the clear security issues
  • Context.MODE_WORLD_READABLE (value 1) – The preference file can be read by all applications. Again this mode was deprecated in API 17

So we now have a SharedPerference object to work with, but to set and save a preference, we need to get a Shared Preference editor, set the required Preference and then save it so that its written to our preference file.

sharedPref.edit().putBoolean("show_background", false).apply();

In the above example, we first get our editor with .edit() then call the .put() method. There is a method for each supported data type – see HERE for the complete list. Our example is setting a boolean data type so we use .putBoolean().

These methods take two arguments, the first is a String. This is the key used to identify the Preference and we will use this to retrieve the data. The second argument is the data itself .putBoolean() takes a Boolean.

Finally we call .apply() on this to actually save the Preference to the file.

Getting a Shared Preference

As I said before, getting a Shared Preference is just as easy (actually easier!). Again, we retrieve our preference file, just as we did before.

SharedPreferences sharedPref = getSharedPreferences("MyPref", Context.MODE_PRIVATE);

Then we can access any preference we have saved to this file. In the below example we access the “show_background” preference.

Boolean background = sharedPref.getBoolean("show_background", true);

Here we use the .getBoolean() method. Each data type has a method – for the complete list see HERE. These methods all take two arguments. The first is a String which is the key for the Preference we are getting and the second is the default value to be returned if the Preference is not found.

This second argument is important as it allows us to use the method before the user may have actually set the preference. For example, when the user first launches the application.

And that is it all you need to know about using Shared Preferences! If you have any questions, please leave them in the comments below.

 

Leave a Reply

Your email address will not be published. Required fields are marked *

Tags: , ,

“ Any fool can write code that a computer can understand. Good programmers write code that humans can understand. ”

-Martin Fowler