Java tutorial
/** * 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 com.a3did.partner.recosample; import android.Manifest; import android.app.Activity; import android.app.ActivityManager; 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.support.design.widget.Snackbar; import android.support.v4.app.ActivityCompat; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.TextView; import android.widget.ToggleButton; import com.a3did.partner.partner.R; public class MainActivity extends Activity { //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_main_reco); mLayout = findViewById(R.id.mainLayout); View includedLayout = (View) findViewById(R.id.reco_settings_values); TextView mRecoOnlyText = (TextView) includedLayout.findViewById(R.id.recoRecoonlySetting); if (SCAN_RECO_ONLY) { mRecoOnlyText.setText(R.string.settings_result_true); } else { mRecoOnlyText.setText(R.string.settings_result_false); } TextView mDiscontinuousText = (TextView) includedLayout.findViewById(R.id.recoDiscontinouosSetting); if (DISCONTINUOUS_SCAN) { mDiscontinuousText.setText(R.string.settings_result_true); } else { mDiscontinuousText.setText(R.string.settings_result_false); } TextView mBackgroundRangingTimeoutText = (TextView) includedLayout .findViewById(R.id.recoBackgroundtimeoutSetting); if (ENABLE_BACKGROUND_RANGING_TIMEOUT) { mBackgroundRangingTimeoutText.setText(R.string.settings_result_true); } else { mBackgroundRangingTimeoutText.setText(R.string.settings_result_false); } //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("MainActivity", "The location permission (ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION) is not granted."); this.requestLocationPermission(); } else { Log.i("MainActivity", "The location permission (ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION) is already granted."); } } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_ENABLE_BT && resultCode == Activity.RESULT_CANCELED) { //If the request to turn on bluetooth is denied, the app will be finished. //? ? ? , ?? ?. finish(); return; } super.onActivityResult(requestCode, resultCode, data); } @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; } } @Override protected void onResume() { super.onResume(); if (this.isBackgroundMonitoringServiceRunning(this)) { ToggleButton toggle = (ToggleButton) findViewById(R.id.backgroundMonitoringToggleButton); toggle.setChecked(true); } if (this.isBackgroundRangingServiceRunning(this)) { ToggleButton toggle = (ToggleButton) findViewById(R.id.backgroundRangingToggleButton); toggle.setChecked(true); } } @Override protected void onDestroy() { super.onDestroy(); } /** * 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. * * This sample project requests "ACCESS_COARSE_LOCATION" permission only, * but you may request "ACCESS_FINE_LOCATION" permission depending on your application. * * "ACCESS_COARSE_LOCATION" permission is recommended. * * ? API 23 ()?? , ?? RECO SDK * (ACCESS_COARSE_LOCATION ? ACCESS_FINE_LOCATION)? . * * ?? "ACCESS_COARSE_LOCATION"? , ? ? "ACCESS_FINE_LOCATION"? . * * ? 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, R.string.location_permission_rationale, Snackbar.LENGTH_INDEFINITE) .setAction(R.string.ok, new View.OnClickListener() { @Override public void onClick(View v) { ActivityCompat.requestPermissions(MainActivity.this, new String[] { Manifest.permission.ACCESS_COARSE_LOCATION }, REQUEST_LOCATION); } }).show(); } public void onMonitoringToggleButtonClicked(View v) { ToggleButton toggle = (ToggleButton) v; if (toggle.isChecked()) { Log.i("MainActivity", "onMonitoringToggleButtonClicked off to on"); Intent intent = new Intent(this, RecoBackgroundMonitoringService.class); startService(intent); } else { Log.i("MainActivity", "onMonitoringToggleButtonClicked on to off"); stopService(new Intent(this, RecoBackgroundMonitoringService.class)); } } public void onRangingToggleButtonClicked(View v) { ToggleButton toggle = (ToggleButton) v; if (toggle.isChecked()) { Log.i("MainActivity", "onRangingToggleButtonClicked off to on"); Intent intent = new Intent(this, RecoBackgroundRangingService.class); startService(intent); } else { Log.i("MainActivity", "onRangingToggleButtonClicked on to off"); stopService(new Intent(this, RecoBackgroundRangingService.class)); } } public void onButtonClicked(View v) { Button btn = (Button) v; if (btn.getId() == R.id.monitoringButton) { final Intent intent = new Intent(this, RecoMonitoringActivity.class); startActivity(intent); } else { final Intent intent = new Intent(this, RecoRangingActivity.class); startActivity(intent); } } private boolean isBackgroundMonitoringServiceRunning(Context context) { ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); for (ActivityManager.RunningServiceInfo runningService : am.getRunningServices(Integer.MAX_VALUE)) { if (RecoBackgroundMonitoringService.class.getName().equals(runningService.service.getClassName())) { return true; } } return false; } private boolean isBackgroundRangingServiceRunning(Context context) { ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); for (ActivityManager.RunningServiceInfo runningService : am.getRunningServices(Integer.MAX_VALUE)) { if (RecoBackgroundRangingService.class.getName().equals(runningService.service.getClassName())) { return true; } } return false; } }