mobilelecture.cdp12_app.RecoRangingActivity.java Source code

Java tutorial

Introduction

Here is the source code for mobilelecture.cdp12_app.RecoRangingActivity.java

Source

/**
 * The MIT License (MIT)
 *
 * Copyright (c) 2014-2015 Perples, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package mobilelecture.cdp12_app;

import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.RemoteException;
import android.support.design.widget.Snackbar;
import android.support.v4.app.ActivityCompat;
import android.util.Log;
import android.view.View;
import android.widget.ListView;

import com.perples.recosdk.RECOBeacon;
import com.perples.recosdk.RECOBeaconRegion;
import com.perples.recosdk.RECOErrorCode;
import com.perples.recosdk.RECORangingListener;

import java.util.ArrayList;
import java.util.Collection;

/**
 * RECORangingActivity class is to range regions in the foreground.
 *
 * RECORangingActivity ? foreground ?? ranging? .
 */
public class RecoRangingActivity extends RecoActivity implements RECORangingListener {

    private RecoRangingListAdapter mRangingListAdapter;
    private ListView mRegionListView;

    private String return_location_ID = "0";
    private double temp_location = 100.0;

    //  
    //This is a default proximity uuid of the RECO
    public static final String RECO_UUID = "24DDF411-8CF1-440C-87CD-E368DAF9C93E";

    // SCAN_RECO_ONLY:
    // If true, the application scans RECO beacons only, otherwise it scans all beacons.
    // It will be used when the instance of RECOBeaconManager is created.
    // true?    , false?   ? .
    // RECOBeaconManager ? ?  .

    public static final boolean SCAN_RECO_ONLY = true;

    // ENABLE_BACKGROUND_RANGING_TIMEOUT:
    // If true, the application stops to range beacons in the entered region automatically in 10 seconds (background),
    // otherwise it continues to range beacons. (It affects the battery consumption.)
    // It will be used when the instance of RECOBeaconManager is created.
    // ? ranging timeout? .
    // true? , ??  region? ranging?  ?? , 10  ?? .
    // false? , ? ranging? . ( ? ?? ?.)
    // RECOBeaconManager ? ?  .

    public static final boolean ENABLE_BACKGROUND_RANGING_TIMEOUT = true;

    // DISCONTINUOUS_SCAN:
    // There is a known android bug that some android devices scan BLE devices only once.
    // (link: http://code.google.com/p/android/issues/detail?id=65863)
    // To resolve the bug in our SDK, you can use setDiscontinuousScan() method of the RECOBeaconManager.
    // This method is to set whether the device scans BLE devices continuously or discontinuously.
    // The default is set as FALSE. Please set TRUE only for specific devices.
    // ? ? ? BLE ?  ,       (: http://code.google.com/p/android/issues/detail?id=65863) .
    //   SDK?  , RECOBeaconManager? setDiscontinuousScan()  ?  .
    //   ? BLE ?  (, ranging ?), ?? ?  ?, ??  ?  .
    //  ? FALSE ? ,  ?  TRUE  .

    public static final boolean DISCONTINUOUS_SCAN = false;
    private static final int REQUEST_ENABLE_BT = 1;
    private static final int REQUEST_LOCATION = 10;
    private BluetoothManager mBluetoothManager;
    private BluetoothAdapter mBluetoothAdapter;
    private View mLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_reco_ranging);

        // 

        //If a user device turns off bluetooth, request to turn it on.
        //?  ?? .
        mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
        mBluetoothAdapter = mBluetoothManager.getAdapter();

        if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
            Intent enableBTIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBTIntent, REQUEST_ENABLE_BT);
        }

        /**
         * In order to use RECO SDK for Android API 23 (Marshmallow) or higher,
         * the location permission (ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION) is required.
         * Please refer to the following permission guide and sample code provided by Google.
         *
         * ? API 23 ()?? , ?? RECO SDK  
         *   (ACCESS_COARSE_LOCATION ? ACCESS_FINE_LOCATION)?  .
         *  ? , ?  ?  ?.
         *
         * http://www.google.com/design/spec/patterns/permissions.html
         * https://github.com/googlesamples/android-RuntimePermissions
         */
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (ActivityCompat.checkSelfPermission(getApplicationContext(),
                    Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                Log.i("RecoRangingActivity",
                        "The location permission (ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION) is not granted.");
                this.requestLocationPermission();
            } else {
                Log.i("RecoRangingActivity",
                        "The location permission (ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION) is already granted.");
            }
        }

        // ??

        //mRecoManager will be created here. (Refer to the RECOActivity.onCreate())
        //mRecoManager ?  ??. RECOActivity.onCreate()  .

        //Set RECORangingListener (Required)
        //RECORangingListener  . ()
        mRecoManager.setRangingListener(this);

        /**
         * Bind RECOBeaconManager with RECOServiceConnectListener, which is implemented in RECOActivity
         * You SHOULD call this method to use monitoring/ranging methods successfully.
         * After binding, onServiceConenct() callback method is called.
         * So, please start monitoring/ranging AFTER the CALLBACK is called.
         *
         * RECOServiceConnectListener  RECOBeaconManager bind . RECOServiceConnectListener RECOActivity? ? .
         * monitoring ? ranging ?  , ?  "" ? .
         * bind?, onServiceConnect()   ?.    ? monitoring / ranging ?  ?.
         */
        mRecoManager.bind(this);
    }

    @Override
    protected void onResume() {
        super.onResume();

        mRangingListAdapter = new RecoRangingListAdapter(this);
        mRegionListView = (ListView) findViewById(R.id.list_ranging);
        mRegionListView.setAdapter(mRangingListAdapter);
    }

    @Override
    protected void onDestroy() {

        Intent intent_getType = getIntent();
        String activity_TYPE = intent_getType.getStringExtra("TYPE");

        Intent intent_out_location;

        Log.i("", "activity_TYPE : " + activity_TYPE);
        if (activity_TYPE != null && activity_TYPE.equals("0")) {
            //if (activity_TYPE.equalsIgnoreCase("0")) {
            intent_out_location = new Intent(getApplicationContext(), MapViewActivity.class);
            intent_out_location.putExtra("current_location_ID", return_location_ID);
            intent_out_location.putExtra("current_location_LOC", temp_location + "");
            Log.i("RECORangingActivity", "" + return_location_ID + "  " + temp_location);
            intent_out_location.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
            startActivity(intent_out_location);
        } else {
            Intent intent_out_inform = getIntent();
            String menuname = intent_out_inform.getStringExtra("GoodsName");
            String cornername = intent_out_inform.getStringExtra("ConerName");

            Log.i("RECORangingActivity", "menu + coner : " + menuname + " " + cornername);

            intent_out_location = new Intent(getApplicationContext(), GoodsMapSearch.class);
            intent_out_location.putExtra("current_location_ID", return_location_ID);
            intent_out_location.putExtra("current_location_LOC", temp_location + "");
            intent_out_location.putExtra("GoodsName", menuname);
            intent_out_location.putExtra("ConerName", cornername);

            intent_out_location.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
            startActivity(intent_out_location);
            //setResult(RESULT_OK, intent_out_inform);
        }

        super.onDestroy();
        this.stop(mRegions);
        this.unbind();
    }

    private void unbind() {
        try {
            mRecoManager.unbind();
        } catch (RemoteException e) {
            Log.i("RECORangingActivity", "Remote Exception");
            e.printStackTrace();
        }
    }

    @Override
    public void onServiceConnect() {
        Log.i("RECORangingActivity", "onServiceConnect()");
        mRecoManager.setDiscontinuousScan(RecoRangingActivity.DISCONTINUOUS_SCAN);
        this.start(mRegions);
        //Write the code when RECOBeaconManager is bound to RECOBeaconService
    }

    @Override
    public void didRangeBeaconsInRegion(Collection<RECOBeacon> recoBeacons, RECOBeaconRegion recoRegion) {
        Log.i("RECORangingActivity", "didRangeBeaconsInRegion() region: " + recoRegion.getUniqueIdentifier()
                + ", number of beacons ranged: " + recoBeacons.size());
        mRangingListAdapter.updateAllBeacons(recoBeacons);
        mRangingListAdapter.notifyDataSetChanged();
        //Write the code when the beacons in the region is received

        for (int i = 0; i < mRangingListAdapter.getCount(); i++) {
            if (temp_location > Double.valueOf(mRangingListAdapter.getAccuracy(i))) {
                temp_location = Double.valueOf(mRangingListAdapter.getAccuracy(i));
                return_location_ID = mRangingListAdapter.getMinor(i);
            }
        }

        if (recoBeacons.size() >= 3) {
            onDestroy();
            finish();
        }
    }

    @Override
    protected void start(ArrayList<RECOBeaconRegion> regions) {

        /**
         * There is a known android bug that some android devices scan BLE devices only once. (link: http://code.google.com/p/android/issues/detail?id=65863)
         * To resolve the bug in our SDK, you can use setDiscontinuousScan() method of the RECOBeaconManager.
         * This method is to set whether the device scans BLE devices continuously or discontinuously.
         * The default is set as FALSE. Please set TRUE only for specific devices.
         *
         * mRecoManager.setDiscontinuousScan(true);
         */

        for (RECOBeaconRegion region : regions) {
            try {
                mRecoManager.startRangingBeaconsInRegion(region);
            } catch (RemoteException e) {
                Log.i("RECORangingActivity", "Remote Exception");
                e.printStackTrace();
            } catch (NullPointerException e) {
                Log.i("RECORangingActivity", "Null Pointer Exception");
                e.printStackTrace();
            }
        }

    }

    @Override
    protected void stop(ArrayList<RECOBeaconRegion> regions) {
        for (RECOBeaconRegion region : regions) {
            try {
                mRecoManager.stopRangingBeaconsInRegion(region);
            } catch (RemoteException e) {
                Log.i("RECORangingActivity", "Remote Exception");
                e.printStackTrace();
            } catch (NullPointerException e) {
                Log.i("RECORangingActivity", "Null Pointer Exception");
                e.printStackTrace();
            }
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode) {
        case REQUEST_LOCATION: {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Snackbar.make(mLayout, R.string.location_permission_granted, Snackbar.LENGTH_LONG).show();
            } else {
                Snackbar.make(mLayout, R.string.location_permission_not_granted, Snackbar.LENGTH_LONG).show();
            }
        }
        default:
            break;
        }
    }

    //  

    /**
     * In order to use RECO SDK for Android API 23 (Marshmallow) or higher,
     * the location permission (ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION) is required.
     * <p/>
     * This sample project requests "ACCESS_COARSE_LOCATION" permission only,
     * but you may request "ACCESS_FINE_LOCATION" permission depending on your application.
     * <p/>
     * "ACCESS_COARSE_LOCATION" permission is recommended.
     * <p/>
     * ? API 23 ()?? , ?? RECO SDK  
     *   (ACCESS_COARSE_LOCATION ? ACCESS_FINE_LOCATION)?  .
     * <p/>
     *   ?? "ACCESS_COARSE_LOCATION"? , ? ? "ACCESS_FINE_LOCATION"?   .
     * <p/>
     * ? ACCESS_COARSE_LOCATION ? .
     */
    private void requestLocationPermission() {
        if (!ActivityCompat.shouldShowRequestPermissionRationale(this,
                Manifest.permission.ACCESS_COARSE_LOCATION)) {
            ActivityCompat.requestPermissions(this, new String[] { Manifest.permission.ACCESS_COARSE_LOCATION },
                    REQUEST_LOCATION);
            return;
        }

        Snackbar.make(mLayout, "Location permission is needed to monitor or range beacons.",
                Snackbar.LENGTH_INDEFINITE).setAction("ok", new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        ActivityCompat.requestPermissions(RecoRangingActivity.this,
                                new String[] { Manifest.permission.ACCESS_COARSE_LOCATION }, REQUEST_LOCATION);
                    }
                }).show();
    }

    @Override
    public void onServiceFail(RECOErrorCode errorCode) {
        //Write the code when the RECOBeaconService is failed.
        //See the RECOErrorCode in the documents.
        return;
    }

    @Override
    public void rangingBeaconsDidFailForRegion(RECOBeaconRegion region, RECOErrorCode errorCode) {
        //Write the code when the RECOBeaconService is failed to range beacons in the region.
        //See the RECOErrorCode in the documents.
        return;
    }
}