diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 2b3de96..b8c9b0c 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,6 +8,7 @@ + diff --git a/app/src/main/java/com/example/childguard/MainActivity.java b/app/src/main/java/com/example/childguard/MainActivity.java index 6b4c6f8..b487803 100644 --- a/app/src/main/java/com/example/childguard/MainActivity.java +++ b/app/src/main/java/com/example/childguard/MainActivity.java @@ -32,7 +32,6 @@ import com.google.firebase.firestore.FirebaseFirestore; import com.journeyapps.barcodescanner.ScanContract; import com.journeyapps.barcodescanner.ScanOptions; -// Manifest import android.Manifest; import java.util.HashMap; @@ -41,15 +40,12 @@ import java.util.Map; public class MainActivity extends AppCompatActivity { FirebaseFirestore db; - - DocumentReference mDocRef; - private HomeFragment homeFragment = HomeFragment.newInstance("test", "test");; + private HomeFragment homeFragment = HomeFragment.newInstance("test", "test"); public static final String TAG = "InspirationQuote"; - private final ActivityResultLauncher QrLauncher = registerForActivityResult( new ScanContract(), result -> { @@ -77,7 +73,7 @@ public class MainActivity extends AppCompatActivity { SharedPreferences.Editor e = pref.edit(); e.putBoolean("connection_status", false); - + // Check permissions if (!hasPermissions()) { requestPermissions(); } @@ -85,15 +81,14 @@ public class MainActivity extends AppCompatActivity { BottomNavigationView bottomNavigationView = findViewById(R.id.nav_view); this.homeFragment = HomeFragment.newInstance("test", "test"); - if(savedInstanceState == null){ + if (savedInstanceState == null) { getSupportFragmentManager().beginTransaction() .replace(findViewById(R.id.fragmentContainerView).getId(), this.homeFragment) .addToBackStack(null) .commit(); } - bottomNavigationView.setOnNavigationItemSelectedListener(v -> - { + bottomNavigationView.setOnNavigationItemSelectedListener(v -> { if (v.getItemId() == findViewById(R.id.navigation_home).getId()) { Log.d("MainActivity", "navigation_home: called"); findViewById(R.id.fab_scan_qr_code).setVisibility(FrameLayout.VISIBLE); @@ -101,8 +96,6 @@ public class MainActivity extends AppCompatActivity { .replace(findViewById(R.id.fragmentContainerView).getId(), this.homeFragment) .addToBackStack(null) .commit(); - //firebaseLink(); - } else if (v.getItemId() == findViewById(R.id.navigation_settings).getId()) { Log.d("MainActivity", "navigation_settings: called"); findViewById(R.id.fab_scan_qr_code).setVisibility(FrameLayout.GONE); @@ -130,16 +123,18 @@ public class MainActivity extends AppCompatActivity { intentFilter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED); db = FirebaseFirestore.getInstance();//Firebaseとの紐づけ - if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) { + + String btPermission = getBluetoothConnectPermission(); + if (ActivityCompat.checkSelfPermission(this, btPermission) != PackageManager.PERMISSION_GRANTED) { Log.d("BT", "No permission to connect bluetooth devices"); return; } else { Log.d("BT", "Permission to connect bluetooth devices granted"); + + registerReceiver(receiver, intentFilter); + + startForegroundService(new Intent(this, SurveillanceService.class)); } - registerReceiver(receiver, intentFilter); - - //startForegroundService(new Intent(this, SurveillanceService.class)); - } @@ -147,16 +142,21 @@ public class MainActivity extends AppCompatActivity { protected void onResume() { super.onResume(); Log.d("MainActivity onResume", "called"); -// Log.d("MainActivity onResume", "mDocRef is null"); firebaseLink(); } + + // 権限チェック用ヘルパーメソッドを追加 + private String getBluetoothConnectPermission() { + return (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) ? + Manifest.permission.BLUETOOTH_CONNECT : + Manifest.permission.BLUETOOTH; + } + /** * 乗車状態の変更 */ public void changeIsInCar() { - //共有プリファレンス全体の準備 SharedPreferences sharedPreferences = MainActivity.this.getSharedPreferences("app_situation", MODE_PRIVATE); - //共有プリファレンス 書き込みの準備 SharedPreferences.Editor E = sharedPreferences.edit(); SharedPreferences.Editor E2 = sharedPreferences.edit(); String IdPref = sharedPreferences.getString("ID", null);//アプリに記録されているIDの取得 @@ -168,54 +168,104 @@ public class MainActivity extends AppCompatActivity { Map DEFAULT_ITEM = new HashMap<>();//mapの宣言 if (!change) { //isInCarをtrueに更新 - Log.d("MainActivity", "change:"+change); + Log.d("MainActivity", "change:" + change); E.putBoolean("change", true); E.apply(); - Log.d("MainActivity", "change:"+sharedPreferences.getBoolean("change",false)); + Log.d("MainActivity", "change:" + sharedPreferences.getBoolean("change", false)); } else { - Log.d("MainActivity", "change:"+change); + Log.d("MainActivity", "change:" + change); E.putBoolean("change", false); E.apply(); - Log.d("MainActivity", "change:"+sharedPreferences.getBoolean("change",false)); + Log.d("MainActivity", "change:" + sharedPreferences.getBoolean("change", false)); } - Log.d("MainActivity", "changeIsInCar: "+sharedPreferences.getBoolean("change",false)); - isReported.update("isInCar", sharedPreferences.getBoolean("change",false)).addOnSuccessListener(unused -> Log.d(TAG, "DocumentSnapshot successfully updated!!")).addOnFailureListener(e -> Log.w(TAG, "Error updating document", e)); - E2.putBoolean("isInCarPref", sharedPreferences.getBoolean("change",false)); + Log.d("MainActivity", "changeIsInCar: " + sharedPreferences.getBoolean("change", false)); + isReported.update("isInCar", sharedPreferences.getBoolean("change", false)) + .addOnSuccessListener(unused -> Log.d(TAG, "DocumentSnapshot successfully updated!!")) + .addOnFailureListener(e -> Log.w(TAG, "Error updating document", e)); + E2.putBoolean("isInCarPref", sharedPreferences.getBoolean("change", false)); E2.apply(); } - - + /** + * 権限の保有を確認する + * @return + */ private boolean hasPermissions() { - return ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH) == PackageManager.PERMISSION_GRANTED && - ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_ADMIN) == PackageManager.PERMISSION_GRANTED && - ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_SCAN) == PackageManager.PERMISSION_GRANTED && - ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) == PackageManager.PERMISSION_GRANTED && - ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED && - ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED && - ActivityCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED && - ActivityCompat.checkSelfPermission(this, Manifest.permission.VIBRATE) == PackageManager.PERMISSION_GRANTED && - ActivityCompat.checkSelfPermission(this, Manifest.permission.FOREGROUND_SERVICE) == PackageManager.PERMISSION_GRANTED; + boolean allGranted = true; + + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) { + // <= Android 11 (API 30) + allGranted &= (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH) + == PackageManager.PERMISSION_GRANTED); + allGranted &= (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_ADMIN) + == PackageManager.PERMISSION_GRANTED); + } else { + // >= Android 12 (API 31) + allGranted &= (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_SCAN) + == PackageManager.PERMISSION_GRANTED); + allGranted &= (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) + == PackageManager.PERMISSION_GRANTED); + } + + // Location + allGranted &= (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) + == PackageManager.PERMISSION_GRANTED); + allGranted &= (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) + == PackageManager.PERMISSION_GRANTED); + + // >= Android 13 (API 32) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + allGranted &= (ActivityCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) + == PackageManager.PERMISSION_GRANTED); + } + + // Others + allGranted &= (ActivityCompat.checkSelfPermission(this, Manifest.permission.VIBRATE) + == PackageManager.PERMISSION_GRANTED); + allGranted &= (ActivityCompat.checkSelfPermission(this, Manifest.permission.FOREGROUND_SERVICE) + == PackageManager.PERMISSION_GRANTED); + + return allGranted; } + /** + * 権限のリクエストを行う + */ private void requestPermissions() { - ActivityCompat.requestPermissions(this, - new String[]{ - Manifest.permission.BLUETOOTH, - Manifest.permission.BLUETOOTH_ADMIN, - Manifest.permission.BLUETOOTH_SCAN, - Manifest.permission.BLUETOOTH_CONNECT, - Manifest.permission.ACCESS_FINE_LOCATION, - Manifest.permission.ACCESS_COARSE_LOCATION, - Manifest.permission.POST_NOTIFICATIONS, - Manifest.permission.VIBRATE, - Manifest.permission.FOREGROUND_SERVICE - }, - 2); + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) { + // <= Android 11 (API 30) + ActivityCompat.requestPermissions(this, + new String[]{ + Manifest.permission.BLUETOOTH, + Manifest.permission.BLUETOOTH_ADMIN, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.VIBRATE, + Manifest.permission.FOREGROUND_SERVICE, + }, + 2 + ); + } else { + // >= Android 12 (API 31) + ActivityCompat.requestPermissions(this, + new String[]{ + Manifest.permission.BLUETOOTH_SCAN, + Manifest.permission.BLUETOOTH_CONNECT, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.POST_NOTIFICATIONS, + Manifest.permission.VIBRATE, + Manifest.permission.FOREGROUND_SERVICE + }, + 2 + ); + } } @Override - public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + public void onRequestPermissionsResult(int requestCode, + @NonNull String[] permissions, + @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == 2) { if (!hasPermissions()) { @@ -224,20 +274,17 @@ public class MainActivity extends AppCompatActivity { } } - /** * FireBaseのIDの取得 */ public void firebaseLink() {//Firebaseのドキュメントの取得 Log.d("MainActivity", "firebaseLink: called"); - //共有プリファレンス全体の準備 SharedPreferences sharedPreferences = getSharedPreferences("app_situation", MODE_PRIVATE); String IdPref = sharedPreferences.getString("ID", null);//アプリに記録されているIDの取得 if (IdPref == null) { Log.d("onResume", "ID not initialized."); } else { mDocRef = FirebaseFirestore.getInstance().document("status/" + IdPref);//現在の位置を取得 - //updateIsInCarPref(mDocRef);//現在の位置を引数に initNotification()を処理 } } @@ -246,7 +293,8 @@ public class MainActivity extends AppCompatActivity { intentFilter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED); intentFilter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED); - if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) { + String btPermission = getBluetoothConnectPermission(); + if (ActivityCompat.checkSelfPermission(this, btPermission) != PackageManager.PERMISSION_GRANTED) { Log.d("BT", "No permission to connect bluetooth devices"); return; } else { @@ -255,22 +303,23 @@ public class MainActivity extends AppCompatActivity { registerReceiver(receiver, intentFilter); } - private final BroadcastReceiver receiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { SharedPreferences pref = getSharedPreferences("Bluetooth_situation", MODE_PRIVATE); SharedPreferences.Editor e = pref.edit(); - String action = intent.getAction(); // may need to chain this to a recognizing function + String action = intent.getAction(); BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); - Boolean isInCar = pref.getBoolean("isInCarPref", false); - if (ActivityCompat.checkSelfPermission(context, android.Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) { + boolean isInCar = pref.getBoolean("isInCarPref", false); + String btPermission = getBluetoothConnectPermission(); + if (ActivityCompat.checkSelfPermission(context, btPermission) != PackageManager.PERMISSION_GRANTED) { Log.d("BT", "No permission to connect bluetooth devices"); return; } String deviceHardwareAddress = device.getAddress(); // MAC address - String registeredId = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).getString("bluetooth_device_id", "none"); + String registeredId = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()) + .getString("bluetooth_device_id", "none"); if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) { //Bluetoothデバイスが接続されたときの処理 @@ -283,7 +332,7 @@ public class MainActivity extends AppCompatActivity { Log.d("BT_Judge", "登録済み"); changeBluetooth(true); e.putBoolean("connection_status", true); - if(homeFragment != null && homeFragment.isVisible()){ + if (homeFragment != null && homeFragment.isVisible()) { homeFragment.updateBluetoothSituation(true); } } else { @@ -293,10 +342,10 @@ public class MainActivity extends AppCompatActivity { } e.apply(); - }else if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) { + } else if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) { //bluetoothデバイスが切断されたときの処理 changeBluetooth(false); - if(homeFragment != null && homeFragment.isVisible()){ + if (homeFragment != null && homeFragment.isVisible()) { homeFragment.updateBluetoothSituation(false); } } @@ -307,7 +356,9 @@ public class MainActivity extends AppCompatActivity { * Bluetoothの接続状態を変更するメソッド */ public void changeBluetooth(boolean actual) { - getSharedPreferences("Bluetooth_situation", MODE_PRIVATE).edit().putBoolean("status", actual).apply(); + getSharedPreferences("Bluetooth_situation", MODE_PRIVATE) + .edit() + .putBoolean("status", actual) + .apply(); } } - diff --git a/app/src/main/java/com/example/childguard/SurveillanceService.java b/app/src/main/java/com/example/childguard/SurveillanceService.java index 73a8875..d4d4626 100644 --- a/app/src/main/java/com/example/childguard/SurveillanceService.java +++ b/app/src/main/java/com/example/childguard/SurveillanceService.java @@ -1,5 +1,6 @@ package com.example.childguard; +import android.Manifest; import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; @@ -12,6 +13,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; import android.content.pm.PackageManager; +import android.os.Build; import android.os.Handler; import android.os.IBinder; import android.os.VibrationEffect; @@ -169,7 +171,8 @@ public class SurveillanceService extends Service { * @return Bluetoothの権限の有無 true: 許可されていない false: 許可されている */ private boolean isNotBluetoothGranted() { - if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) { + String btPermission = getBluetoothConnectPermission(); + if (ActivityCompat.checkSelfPermission(this, btPermission) != PackageManager.PERMISSION_GRANTED) { Log.d(TAG, "Bluetoothの権限が許可されていません"); return true; } else { @@ -190,6 +193,16 @@ public class SurveillanceService extends Service { registerReceiver(receiver, intentFilter); } + /** + * Bluetoothの接続権限を取得 + * @return Bluetoothの接続権限 + */ + private String getBluetoothConnectPermission() { + return (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) ? + android.Manifest.permission.BLUETOOTH_CONNECT : + Manifest.permission.BLUETOOTH; + } + /** * Firestoreのスナップショットリスナーを設定 * @param mDocRef Firestoreのドキュメントリファレンス diff --git a/app/src/main/java/com/example/childguard/bluetooth_setupFragment.java b/app/src/main/java/com/example/childguard/bluetooth_setupFragment.java index e8e3f55..92d7516 100644 --- a/app/src/main/java/com/example/childguard/bluetooth_setupFragment.java +++ b/app/src/main/java/com/example/childguard/bluetooth_setupFragment.java @@ -7,6 +7,7 @@ import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothManager; import android.content.Context; import android.content.pm.PackageManager; +import android.os.Build; import android.os.Bundle; import androidx.core.app.ActivityCompat; @@ -23,6 +24,7 @@ import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; +import android.widget.Toast; import java.util.ArrayList; import java.util.Objects; @@ -91,15 +93,36 @@ public class bluetooth_setupFragment extends Fragment { } - if (ActivityCompat.checkSelfPermission(requireActivity().getApplicationContext(), android.Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) { - // TODO: Consider calling - // ActivityCompat#requestPermissions - // here to request the missing permissions, and then overriding - // public void onRequestPermissionsResult(int requestCode, String[] permissions, - // int[] grantResults) - // to handle the case where the user grants the permission. See the documentation - // for ActivityCompat#requestPermissions for more details. - return view; +// if (ActivityCompat.checkSelfPermission(requireActivity().getApplicationContext(), android.Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) { +// // TODO: Consider calling +// // ActivityCompat#requestPermissions +// // here to request the missing permissions, and then overriding +// // public void onRequestPermissionsResult(int requestCode, String[] permissions, +// // int[] grantResults) +// // to handle the case where the user grants the permission. See the documentation +// // for ActivityCompat#requestPermissions for more details. +// return view; +// } + + // >= Android 12 + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) { + if (ActivityCompat.checkSelfPermission(requireActivity().getApplicationContext(), android.Manifest.permission.BLUETOOTH) != PackageManager.PERMISSION_GRANTED) { + Log.w("Bluetooth", "Permission not granted(Android 12-)"); + // show toast then force close the app (Workaround) + Toast.makeText(requireActivity().getApplicationContext(), "Bluetoothの権限が必須です!", Toast.LENGTH_SHORT).show(); + requireActivity().finish(); + } else { + Log.w("Bluetooth", "Permission granted(Android 12-)"); + } + } else { + if (ActivityCompat.checkSelfPermission(requireActivity().getApplicationContext(), android.Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) { + Log.w("Bluetooth", "Permission not granted(Android 12+)"); + // show toast then force close the app (Workaround) + Toast.makeText(requireActivity().getApplicationContext(), "Bluetoothの権限が必須です!", Toast.LENGTH_SHORT).show(); + requireActivity().finish(); + } else { + Log.w("Bluetooth", "Permission granted(Android 12+)"); + } } Set pairedDevices = bluetoothAdapter.getBondedDevices();