com.elkriefy.android.apps.permissionmigrationguide.MainActivity.java Source code

Java tutorial

Introduction

Here is the source code for com.elkriefy.android.apps.permissionmigrationguide.MainActivity.java

Source

/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * 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.elkriefy.android.apps.permissionmigrationguide;

import android.Manifest;
import android.annotation.TargetApi;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
import com.google.android.gms.location.LocationServices;

import java.util.ArrayList;
import java.util.List;

/**
 * Location sample showcase the Location API and retrieve the last know location.
 *
 * This have 3 different methods:
 * 1. Doing so before Android Marshmallow
 * 2. Doing so in Android Marshmallow
 * 3. Doing so but using the Support library to handle Runtime permissions in Android Marshmallow
 * and above.
 */
public class MainActivity extends AppCompatActivity implements ConnectionCallbacks, OnConnectionFailedListener {

    protected static final String TAG = "MainActivity";
    /**
     * Can only use lower 8 bits for requestCode when using support library solution
     */
    private static final int MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 4;

    private static final int NO_PERMISSIONS_CHECK = 0;
    private static final int MARSHMALLOW_PERMISSIONS_CHECK = 1;
    private static final int SUPPORT_LIBRARY_PERMISSION_CHECK = 2;

    /**
     * Provides the entry point to Google Play services.
     */
    protected GoogleApiClient mGoogleApiClient;

    /**
     * Represents a geographical location.
     */
    protected Location mLastLocation;
    protected String mLatitudeLabel;
    protected String mLongitudeLabel;
    protected TextView mLatitudeText;
    protected TextView mLongitudeText;
    protected Spinner mSpinner;
    protected int mState;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_activity);
        mState = NO_PERMISSIONS_CHECK;

        mLatitudeLabel = getResources().getString(R.string.latitude_label);
        mLongitudeLabel = getResources().getString(R.string.longitude_label);
        mLatitudeText = (TextView) findViewById((R.id.latitude_text));
        mLongitudeText = (TextView) findViewById((R.id.longitude_text));
        mSpinner = (Spinner) findViewById((R.id.permission_case_chooser));

        buildGoogleApiClient();
        populateSpinner();
    }

    private void populateSpinner() {
        List<String> list = new ArrayList<>();
        list.add("No permissions check");
        list.add("Android Marshmallow permissions");
        list.add("Support Library Permissions");
        ArrayAdapter<String> dataAdapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, list);
        dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        mSpinner.setAdapter(dataAdapter);
        mSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                if (mGoogleApiClient.isConnected()) {
                    mGoogleApiClient.disconnect();
                }
                switch (position) {
                case NO_PERMISSIONS_CHECK:
                    mState = NO_PERMISSIONS_CHECK;
                    break;
                case MARSHMALLOW_PERMISSIONS_CHECK:
                    mState = MARSHMALLOW_PERMISSIONS_CHECK;
                    break;
                case SUPPORT_LIBRARY_PERMISSION_CHECK:
                    mState = SUPPORT_LIBRARY_PERMISSION_CHECK;
                    break;
                }
                mGoogleApiClient.connect();
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {
                if (mGoogleApiClient.isConnected()) {
                    mGoogleApiClient.disconnect();
                }
            }
        });
    }

    /**
     * Builds a GoogleApiClient. Uses the addApi() method to request the LocationServices API.
     */
    protected synchronized void buildGoogleApiClient() {
        mGoogleApiClient = new GoogleApiClient.Builder(this).addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this).addApiIfAvailable(LocationServices.API).build();
    }

    @Override
    protected void onStop() {
        super.onStop();
        if (mGoogleApiClient.isConnected()) {
            mGoogleApiClient.disconnect();
        }
    }

    private void getLocation() {
        // Provides a simple way of getting a device's location and is well suited for
        // applications that do not require a fine-grained location and that do not need location
        // updates. Gets the best and most recent location currently available, which may be null
        // in rare cases when a location is not available.
        mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
        if (mLastLocation != null) {
            mLatitudeText.setText(String.format("%s: %f", mLatitudeLabel, mLastLocation.getLatitude()));
            mLongitudeText.setText(String.format("%s: %f", mLongitudeLabel, mLastLocation.getLongitude()));
        } else {
            Toast.makeText(this, R.string.no_location_detected, Toast.LENGTH_LONG).show();
        }
    }

    @Override
    public void onConnectionFailed(ConnectionResult result) {
        // Refer to the javadoc for ConnectionResult to see what error codes might be returned in
        // onConnectionFailed.
        Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = " + result.getErrorCode());
    }

    @Override
    public void onConnectionSuspended(int cause) {
        // The connection to Google Play services was lost for some reason. We call connect() to
        // attempt to re-establish the connection.
        Log.i(TAG, "Connection suspended");
        mGoogleApiClient.connect();
    }

    /**
     * Runs when a GoogleApiClient object successfully connects.
     */
    @Override
    public void onConnected(Bundle connectionHint) {
        switch (mState) {
        case NO_PERMISSIONS_CHECK:
            getLocation();
            break;
        case MARSHMALLOW_PERMISSIONS_CHECK:
            if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1)
                marshmallowPermissionsFlowOnConnected();
            else {
                Toast.makeText(this, R.string.not_marshmallow, Toast.LENGTH_LONG).show();
            }
            break;
        case SUPPORT_LIBRARY_PERMISSION_CHECK:
            supportLibPermissionsOnConnected();
            break;
        }

    }

    @TargetApi(Build.VERSION_CODES.M)
    private void marshmallowPermissionsFlowOnConnected() {
        if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            getLocation();
        } else {
            // Should we show an explanation?
            if (shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION)) {
                // Explain to the user why we need to read the contacts
                Toast.makeText(this, R.string.permission_rationale, Toast.LENGTH_LONG).show();
            }

            requestPermissions(new String[] { Manifest.permission.ACCESS_FINE_LOCATION },
                    MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[],
            @NonNull int[] grantResults) {
        marshmallowonRequestPermissionsResult(requestCode, grantResults);
    }

    private void marshmallowonRequestPermissionsResult(int requestCode, @NonNull int[] grantResults) {
        switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION: {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // permission was granted
                getLocation();
            } else {
                // permission denied, boo! Disable the
                // functionality that depends on this permission.
                Toast.makeText(this, R.string.permission_denied, Toast.LENGTH_LONG).show();
            }
            return;
        }
        }
    }

    private void supportLibPermissionsOnConnected() {
        if (ActivityCompat.checkSelfPermission(this,
                Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            getLocation();
        } else {
            // Should we show an explanation?
            if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                    Manifest.permission.ACCESS_FINE_LOCATION)) {
                // Explain to the user why we need to read the contacts
                Toast.makeText(this, R.string.permission_rationale, Toast.LENGTH_LONG).show();
            }

            ActivityCompat.requestPermissions(this, new String[] { Manifest.permission.ACCESS_FINE_LOCATION },
                    MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
        }
    }

}