Housinnhennkougo #17
|  | @ -1,37 +1,17 @@ | |||
| package com.example.childguard; | ||||
| 
 | ||||
| import static android.content.ContentValues.TAG; | ||||
| import static android.content.Context.MODE_PRIVATE; | ||||
| 
 | ||||
| import android.content.SharedPreferences; | ||||
| import android.os.Bundle; | ||||
| import android.util.Log; | ||||
| import android.view.LayoutInflater; | ||||
| import android.view.View; | ||||
| import android.view.ViewGroup; | ||||
| import android.widget.FrameLayout; | ||||
| import android.widget.TextView; | ||||
| 
 | ||||
| import androidx.core.content.res.ResourcesCompat; | ||||
| import androidx.fragment.app.Fragment; | ||||
| import androidx.fragment.app.FragmentManager; | ||||
| import androidx.fragment.app.FragmentTransaction; | ||||
| import androidx.print.PrintHelper; | ||||
| 
 | ||||
| import android.preference.PreferenceManager; | ||||
| import android.util.Log; | ||||
| import android.view.LayoutInflater; | ||||
| import android.view.View; | ||||
| import android.view.ViewGroup; | ||||
| import android.widget.Button; | ||||
| import android.widget.FrameLayout; | ||||
| import android.widget.TextView; | ||||
| import android.widget.Toast; | ||||
| 
 | ||||
| import androidx.annotation.NonNull; | ||||
| 
 | ||||
| import com.google.android.gms.tasks.OnFailureListener; | ||||
| import com.google.android.gms.tasks.OnSuccessListener; | ||||
| import com.google.firebase.firestore.DocumentReference; | ||||
| import com.google.firebase.firestore.FirebaseFirestore; | ||||
| 
 | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
| import java.util.Objects; | ||||
| 
 | ||||
| /** | ||||
|  * A simple {@link Fragment} subclass. | ||||
|  | @ -75,10 +55,12 @@ public class HomeFragment extends Fragment implements OnEventListener{ | |||
|     @Override | ||||
|     public void onCreate(Bundle savedInstanceState) { | ||||
|         super.onCreate(savedInstanceState); | ||||
| 
 | ||||
|         if (getArguments() != null) { | ||||
|             // mParam1 = getArguments().getString(ARG_PARAM1); | ||||
|             mParam2 = getArguments().getString(ARG_PARAM2); | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|  | @ -110,7 +92,7 @@ public class HomeFragment extends Fragment implements OnEventListener{ | |||
|         transaction.commit(); | ||||
|     } | ||||
| 
 | ||||
|     private boolean updateUiState(boolean state) { | ||||
|     private boolean updateUiState(boolean isInCar) { | ||||
|         Log.d("HomeFragment", "updateUiState: called"); | ||||
|         // Init | ||||
|         TextView tv; | ||||
|  | @ -123,13 +105,13 @@ public class HomeFragment extends Fragment implements OnEventListener{ | |||
|             return false; | ||||
|         } catch (IllegalStateException e) { | ||||
|             Log.d("HomeFragment", "updateUiState: view is not attached"); | ||||
| //            getParentFragmentManager().beginTransaction().replace(R.id.fragmentContainerView, HomeFragment.newInstance("test", "test")).commit(); | ||||
| //            updateUiState(state); | ||||
|             getParentFragmentManager().beginTransaction().replace(R.id.fragmentContainerView, HomeFragment.newInstance("test", "test")).commit(); | ||||
|             updateUiState(isInCar); | ||||
|             return false; | ||||
|         } | ||||
|         String get_on = "\n乗車状態"; | ||||
|         String get_off = "\n降車状態"; | ||||
|         if (state) { | ||||
|         if (!isInCar) { | ||||
|             //乗車状態にする | ||||
|             fl.setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.frame_style_orange, null)); | ||||
|             tv.setText(get_on); | ||||
|  | @ -143,9 +125,10 @@ public class HomeFragment extends Fragment implements OnEventListener{ | |||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public boolean onEvent(boolean state) { | ||||
|     public boolean onEvent(boolean isInCar) { | ||||
|         Log.d("HomeFragment", "onEvent: called"); | ||||
|         return updateUiState(state); | ||||
| 
 | ||||
|         return updateUiState(isInCar); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,67 +1,47 @@ | |||
| package com.example.childguard; | ||||
| 
 | ||||
| import static java.security.AccessController.getContext; | ||||
| 
 | ||||
| import androidx.activity.result.ActivityResultLauncher; | ||||
| import androidx.appcompat.app.ActionBar; | ||||
| import androidx.appcompat.app.AppCompatActivity; | ||||
| import androidx.browser.customtabs.CustomTabsIntent; | ||||
| import androidx.core.app.ActivityCompat; | ||||
| import androidx.core.app.NotificationCompat; | ||||
| import androidx.core.app.NotificationManagerCompat; | ||||
| 
 | ||||
| import android.annotation.SuppressLint; | ||||
| import android.app.NotificationChannel; | ||||
| import android.app.NotificationManager; | ||||
| import android.app.PendingIntent; | ||||
| import android.bluetooth.BluetoothAdapter; | ||||
| import android.bluetooth.BluetoothDevice; | ||||
| import android.bluetooth.BluetoothManager; | ||||
| import android.content.BroadcastReceiver; | ||||
| import android.content.Context; | ||||
| import android.content.SharedPreferences; | ||||
| import android.content.Intent; | ||||
| import android.content.IntentFilter; | ||||
| import android.content.SharedPreferences; | ||||
| import android.content.pm.PackageManager; | ||||
| import android.graphics.Color; | ||||
| import android.graphics.Paint; | ||||
| import android.net.Uri; | ||||
| import android.os.Build; | ||||
| import android.os.Bundle; | ||||
| import android.os.Vibrator; | ||||
| 
 | ||||
| import com.google.android.material.bottomnavigation.BottomNavigationView; | ||||
| 
 | ||||
| import java.text.DateFormat; | ||||
| import java.text.SimpleDateFormat; | ||||
| import java.util.Date; | ||||
| import java.util.Random; | ||||
| import java.util.UUID; | ||||
| 
 | ||||
| import android.preference.PreferenceManager; | ||||
| import android.util.Log; | ||||
| import android.widget.FrameLayout; | ||||
| import android.widget.TextView; | ||||
| import android.widget.Toast; | ||||
| import androidx.annotation.Nullable; | ||||
| import androidx.appcompat.app.AppCompatActivity; | ||||
| import androidx.core.content.res.ResourcesCompat; | ||||
| import androidx.core.graphics.Insets; | ||||
| import androidx.core.view.ViewCompat; | ||||
| import androidx.core.view.WindowInsetsCompat; | ||||
| import androidx.fragment.app.Fragment; | ||||
| import androidx.fragment.app.FragmentManager; | ||||
| 
 | ||||
| import androidx.activity.result.ActivityResultLauncher; | ||||
| import androidx.appcompat.app.AppCompatActivity; | ||||
| import androidx.browser.customtabs.CustomTabsIntent; | ||||
| import androidx.core.app.ActivityCompat; | ||||
| import androidx.core.app.NotificationCompat; | ||||
| import androidx.fragment.app.Fragment; | ||||
| 
 | ||||
| import com.google.android.material.bottomnavigation.BottomNavigationView; | ||||
| import com.google.firebase.firestore.DocumentReference; | ||||
| import com.google.firebase.firestore.DocumentSnapshot; | ||||
| import com.google.firebase.firestore.EventListener; | ||||
| import com.google.firebase.firestore.FirebaseFirestore; | ||||
| import com.google.firebase.firestore.FirebaseFirestoreException; | ||||
| import com.google.zxing.integration.android.IntentIntegrator; | ||||
| import com.google.zxing.integration.android.IntentResult; | ||||
| import com.journeyapps.barcodescanner.ScanContract; | ||||
| import com.journeyapps.barcodescanner.ScanOptions; | ||||
| 
 | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| public class MainActivity extends AppCompatActivity { | ||||
| 
 | ||||
|     FirebaseFirestore db; | ||||
|     BluetoothManager bluetoothManager; | ||||
|     BluetoothAdapter bluetoothAdapter; | ||||
| 
 | ||||
|  | @ -71,14 +51,6 @@ public class MainActivity extends AppCompatActivity { | |||
| 
 | ||||
|     public static final String TAG = "InspirationQuote"; | ||||
| 
 | ||||
|     boolean flg = false; | ||||
| 
 | ||||
|     //↓日付を取得するやつ | ||||
|     public static String getNowDate() { | ||||
|         @SuppressLint("SimpleDateFormat") final DateFormat df = new SimpleDateFormat("yyy/MM/dd HH:mm:ss"); | ||||
|         final Date date = new Date(System.currentTimeMillis()); | ||||
|         return df.format(date); | ||||
|     } | ||||
| 
 | ||||
|     private final ActivityResultLauncher<ScanOptions> QrLauncher = registerForActivityResult( | ||||
|             new ScanContract(), | ||||
|  | @ -105,7 +77,7 @@ public class MainActivity extends AppCompatActivity { | |||
|     protected void onCreate(Bundle savedInstanceState) { | ||||
|         super.onCreate(savedInstanceState); | ||||
|         setContentView(R.layout.activity_main); | ||||
| //        super.onStart(); | ||||
|         db = FirebaseFirestore.getInstance();//Firebaseとの紐づけ | ||||
| 
 | ||||
|         BottomNavigationView bottomNavigationView = findViewById(R.id.nav_view); | ||||
| 
 | ||||
|  | @ -120,6 +92,8 @@ 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_notification).getId()) { | ||||
|                 findViewById(R.id.fab_scan_qr_code).setVisibility(FrameLayout.VISIBLE); | ||||
|                 getSupportFragmentManager().beginTransaction() | ||||
|  | @ -142,6 +116,7 @@ public class MainActivity extends AppCompatActivity { | |||
|             ScanOptions options = new ScanOptions(); | ||||
|             options.setPrompt("QRコードを読み取ってください"); | ||||
|             QrLauncher.launch(options); | ||||
| 
 | ||||
|         }); | ||||
| 
 | ||||
|         //Bluetooth検知機能 | ||||
|  | @ -152,74 +127,57 @@ public class MainActivity extends AppCompatActivity { | |||
|         if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) { | ||||
|             Log.d("BT", "No permission to connect bluetooth devices"); | ||||
|             return; | ||||
|         } | ||||
|         else { | ||||
|         } else { | ||||
|             Log.d("BT", "Permission to connect bluetooth devices granted"); | ||||
|         } | ||||
|         registerReceiver(receiver, intentFilter); | ||||
| 
 | ||||
|         changessituation(); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     protected void onResume() { | ||||
|         super.onResume(); | ||||
|         changessituation(); | ||||
|         Log.d("onResume", "called"); | ||||
|         Log.d("onResume", "mDocRef is null"); | ||||
|         SharedPreferences sharedPreferences = getSharedPreferences("app_situation", MODE_PRIVATE); | ||||
|         String IdPref = sharedPreferences.getString("ID", null); | ||||
|         if (IdPref == null) { | ||||
|             Log.d("onResume", "ID not initialized."); | ||||
|         } else { | ||||
|             mDocRef = FirebaseFirestore.getInstance().document("users/" + IdPref);//現在の位置を取得 | ||||
|             this.flg = false; | ||||
|             initNotification(mDocRef); | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         firebaselink(); | ||||
|     } | ||||
| 
 | ||||
|     private void initNotification(DocumentReference mDocRef) { | ||||
|     private void initNotification(DocumentReference mDocRef) {//サイト上で押されたボタンの管理 | ||||
|         // 共有プリファレンス全体の準備 | ||||
|         SharedPreferences sharedPreferences = getSharedPreferences("app_situation", MODE_PRIVATE); | ||||
| 
 | ||||
|         // Init pref | ||||
|         SharedPreferences sharedPreferences = getSharedPreferences("app_situation",MODE_PRIVATE); | ||||
|         mDocRef.addSnapshotListener(this, (documentSnapshot, e) -> { | ||||
| 
 | ||||
|         mDocRef.addSnapshotListener(this, new EventListener<DocumentSnapshot>() { | ||||
|             @Override | ||||
|             public void onEvent(@Nullable DocumentSnapshot documentSnapshot, @Nullable FirebaseFirestoreException e) { | ||||
|                 Log.d("nt", "イベント開始"); | ||||
|                 //共有プリファレンス 書き込みの準備 | ||||
|                 SharedPreferences.Editor E=sharedPreferences.edit(); | ||||
|                 //車の乗り降りを管理するtrue=乗車、false=降車 | ||||
|                 boolean isInCar = sharedPreferences.getBoolean("car", false); | ||||
|                 if (flg && documentSnapshot != null && documentSnapshot.exists()) { | ||||
| 
 | ||||
|                     String parent = documentSnapshot.getString("parent"); | ||||
|                     Log.d("nt", "レスポンスを検知しました1"); | ||||
| 
 | ||||
|                     assert parent != null; | ||||
|                     if (parent.equals("s")) {//FireBaseの更新情報が"S"のとき=サイト上で第三者ボタンが押されたとき | ||||
|                         if (isInCar) { | ||||
|                             int importance = NotificationManager.IMPORTANCE_DEFAULT; | ||||
|                             NotificationChannel channel = new NotificationChannel("CHANNEL_ID", "通報通知", importance); | ||||
|                             channel.setDescription("第3者からの通報を検知しました"); | ||||
|                             NotificationManager notificationManager = getSystemService(NotificationManager.class); | ||||
|                             notificationManager.createNotificationChannel(channel); | ||||
|                             Log.d("nt", "レスポンスを検知しました2"); | ||||
|                             notifyMain(); | ||||
|                         } | ||||
|                     } else { | ||||
|                         E.putBoolean("car", !isInCar); | ||||
|                         E.apply(); | ||||
|                         // SupportFragmentManagerが現在表示しているFragmentを取得 | ||||
|                         Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.fragmentContainerView); | ||||
|                         if (fragment instanceof HomeFragment) { | ||||
|                             ((HomeFragment) fragment).onEvent(!isInCar); | ||||
|                         } else { | ||||
|                             Log.d("nt", "HomeFragment is not visible"); | ||||
|                         } | ||||
|             Log.d("nt", "イベント開始"); | ||||
|             //共有プリファレンス 書き込みの準備 | ||||
|             SharedPreferences.Editor E = sharedPreferences.edit(); | ||||
|             //車の乗り降りを管理するtrue=乗車、false=降車 | ||||
|             if (documentSnapshot.exists()) {//exists()でdocumentSnapshotの中のファイルの存在の確認 | ||||
|                 Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.fragmentContainerView); | ||||
|                 Boolean isInCar = sharedPreferences.getBoolean("isInCarPref", false);//現在の乗降状態を保存する共有プリファレンス | ||||
|                 E.putBoolean("isInCarPref", documentSnapshot.getBoolean("isInCar"));//乗降状態の判定 | ||||
|                 E.apply();//確定処理 | ||||
|                 Log.d("nt", "レスポンスを検知しました1"); | ||||
|                 //FireBaseで更新された情報の判定 | ||||
|                 if (documentSnapshot.getBoolean("isReported") == false) {//isReportedがfalseのとき=サイト上で保護者ボタンが押されたとき | ||||
|                     if (fragment instanceof HomeFragment) {//fragementがHomeFragmentのインスタンスかの判定 | ||||
|                         changessituation();//  changessituation()メソッドを処理→アプリ側の乗降状態を変化 | ||||
|                     } | ||||
|                 } else if (isInCar) {//第三者ボタンが押されたときにisInCarがtrueのとき=乗車状態のとき→いたずら防止 | ||||
|                     int importance = NotificationManager.IMPORTANCE_DEFAULT; | ||||
|                     NotificationChannel channel = new NotificationChannel("CHANNEL_ID", "通報通知", importance); | ||||
|                     channel.setDescription("第3者からの通報を検知しました"); | ||||
|                     NotificationManager notificationManager = getSystemService(NotificationManager.class); | ||||
|                     notificationManager.createNotificationChannel(channel); | ||||
|                     Log.d("nt", "レスポンスを検知しました2"); | ||||
|                     NotificationSetting();//通知に関する設定のメソッド | ||||
|                     Notification(getApplicationContext());//通知を行うメソッド | ||||
|                     ResetReported();// ResetReported();メソッドを処理→FireBaseのisReportedをfalseにする | ||||
|                 } else {//第三者ボタンが押されたときにisInCarがfalseのとき=降車状態のとき | ||||
|                     ResetReported();// ResetReported();を処理→FireBaseのisReportedをfalseにする | ||||
|                     Log.d("nt", "何もなし"); | ||||
|                 } | ||||
|                 flg = true; | ||||
|             } | ||||
|         }); | ||||
| 
 | ||||
|  | @ -233,13 +191,12 @@ public class MainActivity extends AppCompatActivity { | |||
|         public void onReceive(Context context, Intent intent) { | ||||
|             String action = intent.getAction(); // may need to chain this to a recognizing function | ||||
|             BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); | ||||
|             HomeFragment homeFragment=new HomeFragment(); | ||||
| //            HomeFragment homeFragment=new HomeFragment(); | ||||
| 
 | ||||
|             if (ActivityCompat.checkSelfPermission(context, android.Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) { | ||||
|                 Log.d("BT", "No permission to connect bluetooth devices"); | ||||
|                 return; | ||||
|             } | ||||
|             String deviceName = device.getName(); | ||||
|             String deviceHardwareAddress = device.getAddress(); // MAC address | ||||
| 
 | ||||
|             if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) { | ||||
|  | @ -262,46 +219,105 @@ public class MainActivity extends AppCompatActivity { | |||
|         } | ||||
|     }; | ||||
| 
 | ||||
|     //↓通知のやつ | ||||
|     public void notifyMain() { | ||||
|         //↓通知をする際に起動するバイブレーション | ||||
|         ((Vibrator) getSystemService(Context.VIBRATOR_SERVICE)).vibrate(1000); | ||||
|         //↓通知の詳細設定的な奴 | ||||
|         NotificationCompat.Builder builder = new NotificationCompat | ||||
|                 .Builder(this, "CHANNEL_ID") | ||||
| 
 | ||||
|     public void firebaselink() {//Firebaseのドキュメントの取得 | ||||
|         //共有プリファレンス全体の準備 | ||||
|         SharedPreferences sharedPreferences = getSharedPreferences("app_situation", MODE_PRIVATE); | ||||
|         String IdPref = sharedPreferences.getString("ID", null);////アプリに記録されているIDの取得 | ||||
|         if (IdPref == null) {//FireBaseのIDがアプリに登録されているとき | ||||
|             Log.d("onResume", "ID not initialized."); | ||||
|         } else { | ||||
|             mDocRef = FirebaseFirestore.getInstance().document("status/" + IdPref);//現在の位置を取得 | ||||
|             initNotification(mDocRef);//現在の位置を引数に initNotification()を処理 | ||||
| 
 | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public void ResetReported() {//FireBaseのisReportedをfalseに初期化するメソッド | ||||
|         //共有プリファレンス全体の準備 | ||||
|         SharedPreferences sharedPreferences = MainActivity.this.getSharedPreferences("app_situation", MODE_PRIVATE); | ||||
|         String IdPref = sharedPreferences.getString("ID", null);//アプリに記録されているIDの取得 | ||||
|         db = FirebaseFirestore.getInstance();//Firebaseとの紐づけ | ||||
|         DocumentReference isReported = db.collection("status").document(IdPref);//更新するドキュメントとの紐づけ | ||||
|         Map<String, Boolean> DEFAULT_ITEM = new HashMap<>();//mapの宣言 | ||||
|         //isReportedをfalseに更新 | ||||
|         isReported.update("isReported", false).addOnSuccessListener(unused -> Log.d(TAG, "DocumentSnapshot successfully updated!")).addOnFailureListener(e -> Log.w(TAG, "Error updating document", e)); | ||||
|     } | ||||
| 
 | ||||
|     public void NotificationSetting() {//通知に関する設定の処理を行うメソッド | ||||
|         int importance = NotificationManager.IMPORTANCE_DEFAULT; | ||||
|         //通知チャネルの実装 | ||||
|         NotificationChannel channel = new NotificationChannel("CHANNEL_ID", "通知", importance); | ||||
|         channel.setDescription("第三者により置き去りの通報が行われたときに通知します。"); | ||||
| 
 | ||||
|         NotificationManager notificationManager = getSystemService(NotificationManager.class); | ||||
|         notificationManager.createNotificationChannel(channel); | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     public void Notification(Context context) {//実際に通知を行うメソッド | ||||
|         final String CHANNEL_ID = "my_channel_id"; | ||||
|         // 通知がクリックされたときに送信されるIntent | ||||
|         Intent intent = new Intent(context, MainActivity.class); | ||||
|         intent.setAction("OPEN_ACTIVITY"); | ||||
|         // PendingIntentの作成 | ||||
|         int requestCode = 100; | ||||
|         int flags = 0; | ||||
|         PendingIntent pendingIntent = PendingIntent.getActivity(context, requestCode, intent, flags | PendingIntent.FLAG_IMMUTABLE); | ||||
| 
 | ||||
|         ((Vibrator) getSystemService(Context.VIBRATOR_SERVICE)).vibrate(2000);//バイブレーション | ||||
| 
 | ||||
|         @SuppressLint("NotificationTrampoline") NotificationCompat.Builder builder = new NotificationCompat.Builder(context, "CHANNEL_ID") | ||||
|                 .setSmallIcon(android.R.drawable.ic_menu_info_details) | ||||
|                 .setContentTitle("通報検知") | ||||
|                 .setContentText("子供の置き去りを検知しました。") | ||||
|                 .setPriority(NotificationCompat.PRIORITY_DEFAULT); | ||||
|                 .setContentTitle("子供の置き去りをしていませんか?")//通知のタイトル | ||||
|                 .setContentText("第三者からの通報が行われました。")//通知の本文 | ||||
|                 .setContentIntent(pendingIntent)//通知をタップするとActivityへ移動する | ||||
|                 .setAutoCancel(true)//通知をタップすると削除する | ||||
|                 .setPriority(NotificationCompat.PRIORITY_HIGH) // プライオリティを高く設定 | ||||
|                 .setVisibility(NotificationCompat.VISIBILITY_PUBLIC); // ロック画面に表示する | ||||
| 
 | ||||
|         NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this); | ||||
|         // NotificationChannelの作成(Android 8.0以降) | ||||
|         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { | ||||
|             NotificationManager notificationManager = context.getSystemService(NotificationManager.class); | ||||
|             if (notificationManager != null) { | ||||
|                 NotificationChannel channel = new NotificationChannel( | ||||
|                         CHANNEL_ID, | ||||
|                         "Channel Name", | ||||
|                         NotificationManager.IMPORTANCE_HIGH | ||||
|                 ); | ||||
| 
 | ||||
|                 channel.setDescription("Channel Description"); | ||||
|                 channel.enableLights(true); | ||||
|                 channel.setLightColor(Color.RED); | ||||
|                 channel.enableVibration(true); | ||||
|                 notificationManager.createNotificationChannel(channel); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         NotificationManager notificationManager = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE); | ||||
|         if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.POST_NOTIFICATIONS) != 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; | ||||
|         } | ||||
|         notificationManager.notify(R.string.app_name, builder.build()); | ||||
|         notificationManager.notify(R.string.app_name, builder.build());//通知の表示 | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     public void changessituation() {//乗降状態の管理をするためにHomeFramgentを呼び出すメソッド | ||||
| 
 | ||||
|         SharedPreferences sharedPreferences = getSharedPreferences("app_situation", MODE_PRIVATE); | ||||
|         //共有プリファレンス 書き込みの準備 | ||||
|         SharedPreferences.Editor E = sharedPreferences.edit(); | ||||
|         Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.fragmentContainerView); | ||||
|         Boolean isInCar = sharedPreferences.getBoolean("isInCarPref", false);//現在の乗降状態を保存する共有プリファレンス | ||||
|         ((HomeFragment) fragment).onEvent(!isInCar); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void onStop() { | ||||
|     public void onStop() {//アプリをバックグラウンドにした時のメソッド | ||||
|         super.onStop(); | ||||
|         Intent intent = new Intent(getApplication(), TestService.class); | ||||
|         startService(intent); | ||||
|     } | ||||
| 
 | ||||
|     //Bluetooth_setupの戻るボタン | ||||
|     public void setupBackButton(boolean enableBackButton) { | ||||
|         ActionBar actionBar = getSupportActionBar(); | ||||
|         actionBar.setDisplayHomeAsUpEnabled(enableBackButton); | ||||
|         startService(intent);//TestServiceを起動 | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -0,0 +1,16 @@ | |||
| package com.example.childguard; | ||||
| 
 | ||||
| import android.content.BroadcastReceiver; | ||||
| import android.content.Context; | ||||
| import android.content.Intent; | ||||
| 
 | ||||
| public class NotificationReceiver extends BroadcastReceiver {//通知をタップしたときにアプリを起動する処理 | ||||
|     @Override | ||||
|     public void onReceive(Context context, Intent intent) { | ||||
|         if (intent.getAction() != null && intent.getAction().equals("OPEN_ACTIVITY")) {// 通知がタップされたときの処理 | ||||
|             Intent openIntent = new Intent(context, MainActivity.class);   // MainActivityを起動 | ||||
|             openIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); | ||||
|             context.startActivity(openIntent); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -1,33 +0,0 @@ | |||
| //package com.example.childguard; | ||||
| // | ||||
| //import android.graphics.Color; | ||||
| //import android.graphics.drawable.Drawable; | ||||
| //import android.os.Bundle; | ||||
| //import android.widget.TextView; | ||||
| // | ||||
| //import androidx.appcompat.app.AppCompatActivity; | ||||
| // | ||||
| //public class QR extends AppCompatActivity { | ||||
| //    String get_on="乗車状態"; | ||||
| //    String get_off ="降車状態"; | ||||
| //    TextView tv=findViewById(R.id.situation); | ||||
| //    @Override | ||||
| //    protected void onCreate(Bundle savedInstanceState){ | ||||
| //        super.onCreate(savedInstanceState); | ||||
| //        setContentView(R.layout.fragment_qr); | ||||
| //        //多分いらないコード | ||||
| //        findViewById(R.id.camera).setOnClickListener( | ||||
| //                v -> { | ||||
| //                    if(get_on.equals(tv.getText().toString())){ | ||||
| //                        tv.setText(get_off); | ||||
| //                        findViewById(R.id.situation_bg).setBackgroundColor(Color.parseColor("#dcdcdc")); | ||||
| //                    } | ||||
| //                    else { | ||||
| //                        tv.setText(get_on); | ||||
| //                        findViewById(R.id.situation_bg).setBackgroundColor(Color.parseColor("#ff4500")); | ||||
| //                    } | ||||
| //                } | ||||
| //        ); | ||||
| //    } | ||||
| // | ||||
| //} | ||||
|  | @ -1,125 +0,0 @@ | |||
| package com.example.childguard; | ||||
| 
 | ||||
| import android.content.Intent; | ||||
| import android.content.SharedPreferences; | ||||
| import android.net.Uri; | ||||
| import android.os.Bundle; | ||||
| 
 | ||||
| import androidx.activity.result.ActivityResultLauncher; | ||||
| import androidx.activity.result.contract.ActivityResultContracts; | ||||
| import androidx.browser.customtabs.CustomTabsIntent; | ||||
| import androidx.fragment.app.Fragment; | ||||
| import androidx.fragment.app.FragmentManager; | ||||
| import androidx.fragment.app.FragmentTransaction; | ||||
| 
 | ||||
| import android.util.Log; | ||||
| import android.view.LayoutInflater; | ||||
| import android.view.View; | ||||
| import android.view.ViewGroup; | ||||
| import android.widget.Button; | ||||
| import android.widget.Toast; | ||||
| 
 | ||||
| import com.google.zxing.integration.android.IntentIntegrator; | ||||
| import com.google.zxing.integration.android.IntentResult; | ||||
| import com.journeyapps.barcodescanner.ScanContract; | ||||
| import com.journeyapps.barcodescanner.ScanOptions; | ||||
| 
 | ||||
| import java.util.Objects; | ||||
| 
 | ||||
| /** | ||||
|  * A simple {@link Fragment} subclass. | ||||
|  * Use the {@link QRFragment#newInstance} factory method to | ||||
|  * create an instance of this fragment. | ||||
|  */ | ||||
| public class QRFragment extends Fragment { | ||||
|     //QRコードから受け取ったURLの受け渡しの宣言 | ||||
| //   OnDataPass dataPass; | ||||
|     // TODO: Rename parameter arguments, choose names that match | ||||
|     // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER | ||||
|     private static final String ARG_PARAM1 = "param1"; | ||||
|     private static final String ARG_PARAM2 = "param2"; | ||||
| 
 | ||||
|     // TODO: Rename and change types of parameters | ||||
|     private String mParam1; | ||||
|     private String mParam2; | ||||
| 
 | ||||
|     public QRFragment() { | ||||
|         // Required empty public constructor | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Use this factory method to create a new instance of | ||||
|      * this fragment using the provided parameters. | ||||
|      * | ||||
|      * @param param1 Parameter 1. | ||||
|      * @param param2 Parameter 2. | ||||
|      * @return A new instance of fragment QRFragment. | ||||
|      */ | ||||
|     // TODO: Rename and change types and number of parameters | ||||
|     public static QRFragment newInstance(String param1, String param2) { | ||||
|         QRFragment fragment = new QRFragment(); | ||||
|         Bundle args = new Bundle(); | ||||
|         args.putString(ARG_PARAM1, param1); | ||||
|         args.putString(ARG_PARAM2, param2); | ||||
|         fragment.setArguments(args); | ||||
|         return fragment; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void onCreate(Bundle savedInstanceState) { | ||||
|         super.onCreate(savedInstanceState); | ||||
|         if (getArguments() != null) { | ||||
|             mParam1 = getArguments().getString(ARG_PARAM1); | ||||
|             mParam2 = getArguments().getString(ARG_PARAM2); | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     private final ActivityResultLauncher<ScanOptions> fragmentLauncher = registerForActivityResult(new ScanContract(), | ||||
|             result -> { | ||||
|                 String contents = result.getContents(); | ||||
|                 if (contents == null) { | ||||
|                     Toast.makeText(getContext(), "QRコードが読み取れませんでした", Toast.LENGTH_LONG).show(); | ||||
|                 } else if (!contents.contains("https://practicefirestore1-8808c.web.app/")) { | ||||
|                     Toast.makeText(getContext(), "Chiled Guardに対応するQRコードではありません", Toast.LENGTH_LONG).show(); | ||||
|                 } else { | ||||
|                     //URLの表示 | ||||
|                     Toast.makeText(getContext(), contents, Toast.LENGTH_SHORT).show(); | ||||
|                     //ブラウザを起動し、URL先のサイトを開く | ||||
|                     CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder(); | ||||
|                     CustomTabsIntent customTabsIntent = builder.build(); | ||||
|                     customTabsIntent.launchUrl(requireContext(), Uri.parse(contents)); | ||||
|                 } | ||||
| 
 | ||||
|                 getParentFragmentManager().popBackStack(); | ||||
|             }); | ||||
| 
 | ||||
|     @Override | ||||
|     public View onCreateView(LayoutInflater inflater, ViewGroup container, | ||||
|                              Bundle savedInstanceState) { | ||||
|         // Inflate the layout for this fragment | ||||
|         View view = inflater.inflate(R.layout.fragment_qr, container, false); | ||||
| 
 | ||||
| 
 | ||||
|         Log.d("QRFragment", "onClick: called"); | ||||
|         //QRリーダ起動 | ||||
|         fragmentLauncher.launch(new ScanOptions()); | ||||
| 
 | ||||
|         return view; | ||||
|     } | ||||
|     //画面遷移メソッド | ||||
|     private void replaceFragment(Fragment fragment) { | ||||
|         // フラグメントマネージャーの取得 | ||||
|         FragmentManager manager = getParentFragmentManager(); // アクティビティではgetSupportFragmentManager()? | ||||
|         // フラグメントトランザクションの開始 | ||||
|         FragmentTransaction transaction = manager.beginTransaction(); | ||||
|         // レイアウトをfragmentに置き換え(追加) | ||||
|         transaction.replace(R.id.fragmentContainerView, fragment); | ||||
|         // 置き換えのトランザクションをバックスタックに保存する | ||||
|         transaction.addToBackStack(null); | ||||
|         // フラグメントトランザクションをコミット | ||||
|         transaction.commit(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | @ -1,156 +0,0 @@ | |||
| package com.example.childguard; | ||||
| 
 | ||||
| import static android.content.Context.MODE_PRIVATE; | ||||
| 
 | ||||
| import android.content.SharedPreferences; | ||||
| import android.graphics.Bitmap; | ||||
| import android.graphics.BitmapFactory; | ||||
| import android.graphics.Canvas; | ||||
| import android.graphics.Paint; | ||||
| import android.graphics.drawable.BitmapDrawable; | ||||
| import android.os.Bundle; | ||||
| 
 | ||||
| import androidx.fragment.app.Fragment; | ||||
| import androidx.fragment.app.FragmentManager; | ||||
| import androidx.fragment.app.FragmentTransaction; | ||||
| import androidx.print.PrintHelper; | ||||
| 
 | ||||
| import android.preference.PreferenceManager; | ||||
| import android.util.AndroidRuntimeException; | ||||
| import android.view.LayoutInflater; | ||||
| import android.view.View; | ||||
| import android.view.ViewGroup; | ||||
| import android.widget.ImageView; | ||||
| 
 | ||||
| import com.google.zxing.BarcodeFormat; | ||||
| import com.google.zxing.WriterException; | ||||
| import com.journeyapps.barcodescanner.BarcodeEncoder; | ||||
| 
 | ||||
| /** | ||||
|  * A simple {@link Fragment} subclass. | ||||
|  * Use the {@link QrPrintFragment#newInstance} factory method to | ||||
|  * create an instance of this fragment. | ||||
|  */ | ||||
| public class QrPrintFragment extends Fragment { | ||||
| 
 | ||||
|     // TODO: Rename parameter arguments, choose names that match | ||||
|     // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER | ||||
|     private static final String ARG_PARAM1 = "param1"; | ||||
|     private static final String ARG_PARAM2 = "param2"; | ||||
| 
 | ||||
|     // TODO: Rename and change types of parameters | ||||
|     private String mParam1; | ||||
|     private String mParam2; | ||||
| 
 | ||||
|     public QrPrintFragment() { | ||||
|         // Required empty public constructor | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Use this factory method to create a new instance of | ||||
|      * this fragment using the provided parameters. | ||||
|      * | ||||
|      * @param param1 Parameter 1. | ||||
|      * @param param2 Parameter 2. | ||||
|      * @return A new instance of fragment QrPrintFragment. | ||||
|      */ | ||||
|     // TODO: Rename and change types and number of parameters | ||||
|     public static QrPrintFragment newInstance(String param1, String param2) { | ||||
|         QrPrintFragment fragment = new QrPrintFragment(); | ||||
|         Bundle args = new Bundle(); | ||||
|         args.putString(ARG_PARAM1, param1); | ||||
|         args.putString(ARG_PARAM2, param2); | ||||
|         fragment.setArguments(args); | ||||
|         return fragment; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void onCreate (Bundle savedInstanceState) { | ||||
|         super.onCreate(savedInstanceState); | ||||
|         if (getArguments() != null) { | ||||
|             mParam1 = getArguments().getString(ARG_PARAM1); | ||||
|             mParam2 = getArguments().getString(ARG_PARAM2); | ||||
| 
 | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|    // @Override | ||||
|     public View onCreateView(LayoutInflater inflater, ViewGroup container, | ||||
|                              Bundle savedInstanceState) { | ||||
|         //共有プリファレンス全体の準備 | ||||
|         SharedPreferences sharedPreferences = getActivity().getSharedPreferences("app_situation", MODE_PRIVATE); | ||||
|         //User毎のドメインを保存する | ||||
|         String IdPref=sharedPreferences.getString("ID",null); | ||||
|         // Inflate the layout for this fragment | ||||
|         View view=inflater.inflate(R.layout.fragment_qr_print, container, false);; | ||||
|         //固定のドメイン | ||||
|         String KoteiURL = "https://practicefirestore1-8808c.web.app/?id="; | ||||
|         //すべてのドメイン | ||||
|         String AllURL; | ||||
|         //IdPrefにの値が初期値の場合 | ||||
|         if(IdPref==null) { | ||||
|             //User毎のドメイン | ||||
|             String userURL = getArguments().getString("STR_KEY"); | ||||
|             //キー"ID"の値をuserURLの値にする | ||||
|             SharedPreferences.Editor e = sharedPreferences.edit(); | ||||
|             e.putString("ID", userURL); | ||||
|             //確定処理 | ||||
|             e.apply(); | ||||
|             //二つのドメインを合成する | ||||
|             AllURL=KoteiURL+userURL; | ||||
|         }else{ | ||||
|             //二つのドメインを合成する | ||||
|             AllURL=KoteiURL+IdPref; | ||||
|         } | ||||
| 
 | ||||
|         int size = 2500; | ||||
|         ImageView imageViewQrCode; | ||||
|         Bitmap QRGazou; | ||||
|         try { | ||||
|             //QRコード生成 | ||||
|             BarcodeEncoder barcodeEncoder = new BarcodeEncoder(); | ||||
|             Bitmap bitmapqr = barcodeEncoder.encodeBitmap(AllURL, BarcodeFormat.QR_CODE, size, size); | ||||
|             imageViewQrCode = (ImageView) view.findViewById(R.id.qr_view); | ||||
|             imageViewQrCode.setTranslationX(1000); | ||||
|             imageViewQrCode.setTranslationY(1000); | ||||
|             imageViewQrCode.setImageBitmap(bitmapqr); | ||||
|         } catch (WriterException e) { | ||||
|             throw new AndroidRuntimeException("Barcode Error.", e); | ||||
|         } | ||||
|         //    画像合成の準備 | ||||
|         //    ここのエラーは直すと何故か動かなくなる。このままで動くので放置 | ||||
|         Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.a_group_qr_sos); | ||||
|         Bitmap bitmap1 = ((BitmapDrawable) imageViewQrCode.getDrawable()).getBitmap(); | ||||
|         int width = bitmap.getWidth(); // 元ファイルの幅取得 | ||||
|         int height = bitmap.getHeight(); // 元ファイルの高さ取得 | ||||
|         QRGazou = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); | ||||
|         //Canvasの準備 | ||||
|         Canvas canvas = new Canvas(QRGazou); | ||||
|         //画像のサイズの調整 | ||||
|         int disWidth = (width - bitmap1.getWidth()) / 2; | ||||
|         int disHeight = (int) ((height - bitmap1.getHeight()) / 1.3); | ||||
|         canvas.drawBitmap(bitmap, 0, 0, (Paint) null); // image, x座標, y座標, Paintインスタンス | ||||
|         canvas.drawBitmap(bitmap1, disWidth, disHeight, (Paint) null); // 画像合成 | ||||
|         //Androidからプリンターへ印刷指示を出すサポートライブラリ | ||||
|         PrintHelper printHelper = new PrintHelper(getActivity()); | ||||
|         printHelper.setColorMode(PrintHelper.COLOR_MODE_COLOR); | ||||
|         printHelper.setScaleMode(PrintHelper.SCALE_MODE_FIT); | ||||
|         printHelper.printBitmap("job_name", QRGazou); | ||||
|         HomeFragment homeFragment=new HomeFragment(); | ||||
| //        replaceFragment(homeFragment); | ||||
|         return view; | ||||
|     } | ||||
|       //画面遷移メソッド | ||||
|     private void replaceFragment(Fragment fragment) { | ||||
|         // フラグメントマネージャーの取得 | ||||
|         FragmentManager manager = getParentFragmentManager(); // アクティビティではgetSupportFragmentManager()? | ||||
|         // フラグメントトランザクションの開始 | ||||
|         FragmentTransaction transaction = manager.beginTransaction(); | ||||
|         // レイアウトをfragmentに置き換え(追加) | ||||
|         transaction.replace(R.id.fragmentContainerView, fragment); | ||||
|         // 置き換えのトランザクションをバックスタックに保存する | ||||
|         transaction.addToBackStack(null); | ||||
|         // フラグメントトランザクションをコミット | ||||
|         transaction.commit(); | ||||
|     } | ||||
| } | ||||
|  | @ -8,7 +8,9 @@ import android.graphics.Canvas; | |||
| import android.graphics.Paint; | ||||
| import android.graphics.drawable.BitmapDrawable; | ||||
| import android.util.AndroidRuntimeException; | ||||
| import android.util.DisplayMetrics; | ||||
| import android.util.Log; | ||||
| import android.view.WindowManager; | ||||
| import android.widget.ImageView; | ||||
| 
 | ||||
| import androidx.print.PrintHelper; | ||||
|  | @ -35,6 +37,7 @@ public class QrUtils { | |||
|         AllURL=KoteiURL+key; | ||||
| 
 | ||||
|         int size = 1500; | ||||
|         int qrCodeSize = calculateQRCodeSize(); // 画面密度に応じてサイズを計算 | ||||
|         Bitmap QRGazou; | ||||
|         Bitmap bitmapqr; | ||||
|         try { | ||||
|  | @ -55,10 +58,21 @@ public class QrUtils { | |||
| 
 | ||||
|         // 画像のサイズの調整 | ||||
|         int disWidth = (width - bitmapqr.getWidth()) / 2; | ||||
|         int disHeight = (int) ((height - bitmapqr.getHeight()) / 1.3); | ||||
|         int disHeight = (int) ((height - bitmapqr.getHeight()) / 1.4); | ||||
|         canvas.drawBitmap(bitmap, 0, 0, (Paint) null); | ||||
|         canvas.drawBitmap(bitmapqr, disWidth, disHeight, (Paint) null); // 画像合成 | ||||
|         //Androidからプリンターへ印刷指示を出すサポートライブラリ | ||||
|         return QRGazou; | ||||
|     } | ||||
|     private int calculateQRCodeSize() { | ||||
|         // 画面解像度を取得 | ||||
|         DisplayMetrics metrics = new DisplayMetrics(); | ||||
|         WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); | ||||
|         windowManager.getDefaultDisplay().getMetrics(metrics); | ||||
| 
 | ||||
|         // 画面密度に基づいてQRコードのサイズを計算 | ||||
|         float density = context.getResources().getDisplayMetrics().density; | ||||
|         return (int) (1500 * density); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -1,6 +1,5 @@ | |||
| package com.example.childguard; | ||||
| 
 | ||||
| import android.bluetooth.BluetoothAdapter; | ||||
| import android.content.Context; | ||||
| import android.content.SharedPreferences; | ||||
| import android.preference.PreferenceManager; | ||||
|  | @ -16,7 +15,6 @@ import androidx.appcompat.app.AlertDialog; | |||
| import androidx.recyclerview.widget.RecyclerView; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| import java.util.function.Predicate; | ||||
| 
 | ||||
| public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ItemViewHolder> { | ||||
| 
 | ||||
|  |  | |||
|  | @ -5,21 +5,14 @@ import static android.content.Context.MODE_PRIVATE; | |||
| 
 | ||||
| import android.content.SharedPreferences; | ||||
| import android.os.Bundle; | ||||
| 
 | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.fragment.app.Fragment; | ||||
| import androidx.print.PrintHelper; | ||||
| 
 | ||||
| import android.util.Log; | ||||
| import android.view.LayoutInflater; | ||||
| import android.view.View; | ||||
| import android.view.ViewGroup; | ||||
| import android.widget.Button; | ||||
| import android.widget.Toast; | ||||
| 
 | ||||
| import com.google.android.gms.tasks.OnFailureListener; | ||||
| import com.google.android.gms.tasks.OnSuccessListener; | ||||
| import com.google.firebase.firestore.DocumentReference; | ||||
| import androidx.fragment.app.Fragment; | ||||
| 
 | ||||
| import com.google.firebase.firestore.FirebaseFirestore; | ||||
| 
 | ||||
| import java.util.HashMap; | ||||
|  | @ -76,18 +69,16 @@ public class SettingFragment extends Fragment { | |||
|                 Toast.makeText(getActivity(), "再印刷", Toast.LENGTH_SHORT).show(); | ||||
|                 getParentFragmentManager().beginTransaction().addToBackStack(null).replace(R.id.fragmentContainerView, GenerateQrFragment.newInstance(sharedPreferences.getString("ID", "none"))).commit(); | ||||
|             } else { | ||||
|                 String valueParent = "placeholder"; | ||||
|                 String valueBorn = "placeholder"; | ||||
|                 Map<String, String> user = new HashMap<>();//mapの宣言 | ||||
|                 Map<String, Boolean> DEFAULT_ITEM = new HashMap<>();//mapの宣言 | ||||
| 
 | ||||
|                 Log.d("HomeFragment", "onClick is called"); | ||||
| 
 | ||||
|                 //mapに入れる | ||||
|                 user.put("parent", valueParent); | ||||
|                 user.put("born", valueBorn); | ||||
|                 DEFAULT_ITEM.put("isInCar", false); | ||||
|                 DEFAULT_ITEM.put("isReported", false); | ||||
|                 //新しいドキュメントにIDを作って追加 | ||||
|                 db.collection("users") | ||||
|                         .add(user) | ||||
|                 db.collection("status") | ||||
|                         .add(DEFAULT_ITEM) | ||||
|                         .addOnSuccessListener(documentReference -> { | ||||
|                             //成功したら | ||||
|                             //documentReference.getId()でID取得 | ||||
|  | @ -95,6 +86,7 @@ public class SettingFragment extends Fragment { | |||
|                             SharedPreferences.Editor e = sharedPreferences.edit(); | ||||
|                             // キー"alreadySaved"の値をtrueにする | ||||
|                             e.putBoolean("alreadySaved", true); | ||||
| 
 | ||||
|                             //確定処理 | ||||
|                             e.apply(); | ||||
|                             //画面遷移&ID受け渡し | ||||
|  |  | |||
|  | @ -1,15 +1,22 @@ | |||
| package com.example.childguard; | ||||
| 
 | ||||
| import android.annotation.SuppressLint; | ||||
| import android.app.NotificationChannel; | ||||
| import android.app.NotificationManager; | ||||
| import android.app.PendingIntent; | ||||
| import android.app.Service; | ||||
| import android.bluetooth.BluetoothDevice; | ||||
| import android.content.BroadcastReceiver; | ||||
| import android.content.Context; | ||||
| import android.content.Intent; | ||||
| import android.content.SharedPreferences; | ||||
| import android.content.IntentFilter; | ||||
| import android.content.pm.PackageManager; | ||||
| import android.graphics.Color; | ||||
| import android.os.Build; | ||||
| import android.os.Handler; | ||||
| import android.os.IBinder; | ||||
| import android.os.Looper; | ||||
| import android.os.Vibrator; | ||||
| import android.preference.PreferenceManager; | ||||
| import android.util.Log; | ||||
|  | @ -17,112 +24,240 @@ import android.util.Log; | |||
| import androidx.annotation.Nullable; | ||||
| import androidx.core.app.ActivityCompat; | ||||
| import androidx.core.app.NotificationCompat; | ||||
| import androidx.core.app.NotificationManagerCompat; | ||||
| 
 | ||||
| public class TestService extends Service  { | ||||
| import com.google.firebase.firestore.DocumentReference; | ||||
| import com.google.firebase.firestore.FirebaseFirestore; | ||||
| 
 | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| public class TestService extends Service { | ||||
|     FirebaseFirestore db; | ||||
|     DocumentReference mDocRef; | ||||
| 
 | ||||
|     public static final String TAG = "InspirationQuote"; | ||||
| 
 | ||||
|     public PeriodicTaskManager periodicTaskManager; | ||||
| 
 | ||||
| 
 | ||||
|     @Override | ||||
|     public int onStartCommand(Intent intent, int flags, int startId) { | ||||
| 
 | ||||
|         //Bluetooth検知機能 | ||||
|         IntentFilter intentFilter = new IntentFilter(); | ||||
|         intentFilter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED); | ||||
|         intentFilter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED); | ||||
| 
 | ||||
|         if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) { | ||||
|             Log.d("BT", "No permission to connect bluetooth devices"); | ||||
| 
 | ||||
|         } | ||||
|         else { | ||||
|             Log.d("BT", "Permission to connect bluetooth devices granted"); | ||||
|         //共有プリファレンス全体の準備 | ||||
|         SharedPreferences sharedPreferences = getSharedPreferences("app_situation", MODE_PRIVATE); | ||||
|         String IdPref = sharedPreferences.getString("ID", null);//アプリに記録されているIDの取得 | ||||
|         if (IdPref == null) {//FireBaseのIDがアプリに登録されているとき | ||||
|             Log.d("onResume", "ID not initialized."); | ||||
|         } else { | ||||
|             mDocRef = FirebaseFirestore.getInstance().document("status/" + IdPref);//現在の位置を取得 | ||||
|             initNotification(mDocRef);//現在の位置を引数に initNotification()を処理 | ||||
|         } | ||||
|         return flags; | ||||
|     } | ||||
| 
 | ||||
|     private void initNotification(DocumentReference mDocRef) {//サイト上で押されたボタンの管理 | ||||
|         // PeriodicTaskManagerのインスタンス化 | ||||
|         periodicTaskManager = new PeriodicTaskManager(); | ||||
|         // 共有プリファレンス全体の準備 | ||||
|         SharedPreferences sharedPreferences = getSharedPreferences("app_situation", MODE_PRIVATE); | ||||
|         //車の乗り降りを管理するtrue=乗車、false=降車 | ||||
|         //exists()でdocumentSnapshotの中のファイルの存在の確認 | ||||
|         mDocRef.addSnapshotListener((documentSnapshot, e) -> { | ||||
| 
 | ||||
|         registerReceiver(receiver, intentFilter); | ||||
|         //audioStart(); | ||||
|             Log.d("nt", "イベント開始"); | ||||
|             //共有プリファレンス 書き込みの準備 | ||||
|             SharedPreferences.Editor E = sharedPreferences.edit(); | ||||
|             //車の乗り降りを管理するtrue=乗車、false=降車 | ||||
|             if (documentSnapshot.exists()) {//exists()でdocumentSnapshotの中のファイルの存在の確認 | ||||
|                 Boolean isInCar = sharedPreferences.getBoolean("isInCarPref", false);//現在の乗降状態を保存する共有プリファレンス | ||||
|                 E.putBoolean("isInCarPref", documentSnapshot.getBoolean("isInCar"));//乗降状態の判定 | ||||
|                 E.apply();//確定処理 | ||||
|                 Log.d("nt", "レスポンスを検知しました1"); | ||||
|                 if (documentSnapshot.getBoolean("isReported") == true && isInCar) {//isReportedがtrueかつisInCarがtrueのとき=サイト上で第三者ボタンが押されたときに乗車状態のとき | ||||
|                     ResetReported();// ResetReported();を処理→FireBaseのisReportedをfalseにする | ||||
|                     int importance = NotificationManager.IMPORTANCE_DEFAULT; | ||||
|                     NotificationChannel channel = new NotificationChannel("CHANNEL_ID", "通報通知", importance); | ||||
|                     channel.setDescription("第3者からの通報を検知しました"); | ||||
|                     NotificationManager notificationManager = getSystemService(NotificationManager.class); | ||||
|                     notificationManager.createNotificationChannel(channel); | ||||
|                     Log.d("nt", "レスポンスを検知しました2"); | ||||
|                     NotificationSetting();//通知に関する設定のメソッド | ||||
|                     Notification(getApplicationContext());//通知を行うメソッド | ||||
|                 } else if(isInCar){//Bluetoothの切断後5分以上乗車状態のままのとき→QRコード読み取りを忘れているとき→置き去り発生 | ||||
|                     ResetReported();//ResetReported();を処理→FireBaseのisReportedをfalseにする | ||||
|                     periodicTaskManager.startPeriodicTask();//通知のループをストップする | ||||
|                 }else { | ||||
|                     ResetReported();//ResetReported();を処理→FireBaseのisReportedをfalseにする | ||||
|                     periodicTaskManager.stopPeriodicTask();//5分毎に通知を行う | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|         return START_NOT_STICKY; | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     public void ResetReported() {//FireBaseのisReportedをfalseに初期化するメソッド | ||||
|         //共有プリファレンス全体の準備 | ||||
|         SharedPreferences sharedPreferences = getSharedPreferences("app_situation", MODE_PRIVATE); | ||||
|         String IdPref = sharedPreferences.getString("ID", null);//アプリに記録されているIDの取得 | ||||
|         db = FirebaseFirestore.getInstance();//Firebaseとの紐づけ | ||||
|         DocumentReference isReported = db.collection("status").document(IdPref);//更新するドキュメントとの紐づけ | ||||
|         Map<String, Boolean> DEFAULT_ITEM = new HashMap<>();//mapの宣言 | ||||
|         DEFAULT_ITEM.put("isReported", false); | ||||
|         //isReportedをfalseに更新 | ||||
|         isReported.update("isReported", false).addOnSuccessListener(unused -> Log.d(TAG, "DocumentSnapshot successfully updated!")).addOnFailureListener(e -> Log.w(TAG, "Error updating document", e)); | ||||
|     } | ||||
| 
 | ||||
|     public void NotificationSetting() {//通知に関する設定の処理を行うメソッド | ||||
|             int importance = NotificationManager.IMPORTANCE_DEFAULT; | ||||
|             //通知チャネルの実装 | ||||
|             NotificationChannel channel = new NotificationChannel("CHANNEL_ID", "通知", importance); | ||||
|             channel.setDescription("第三者により置き去りの通報が行われたときに通知します。"); | ||||
| 
 | ||||
|             NotificationManager notificationManager = getSystemService(NotificationManager.class); | ||||
|             notificationManager.createNotificationChannel(channel); | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     private final BroadcastReceiver receiver = new BroadcastReceiver() { | ||||
|     public void Notification(Context context) {//実際に通知を行うメソッド | ||||
|          final String CHANNEL_ID = "my_channel_id"; | ||||
|         // 通知がクリックされたときに送信されるIntent | ||||
|         Intent intent = new Intent(context, MainActivity.class); | ||||
|         intent.setAction("OPEN_ACTIVITY"); | ||||
|         // PendingIntentの作成 | ||||
|         int requestCode = 100; | ||||
|         int flags = 0; | ||||
|         PendingIntent pendingIntent = PendingIntent.getActivity(context, requestCode, intent, flags | PendingIntent.FLAG_IMMUTABLE); | ||||
| 
 | ||||
|         @Override | ||||
|         public void onReceive(Context context, Intent intent) { | ||||
|             String action = intent.getAction(); // may need to chain this to a recognizing function | ||||
|             BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); | ||||
|             HomeFragment homeFragment=new HomeFragment(); | ||||
|         ((Vibrator) getSystemService(Context.VIBRATOR_SERVICE)).vibrate(2000);//バイブレーション | ||||
| 
 | ||||
|             if (ActivityCompat.checkSelfPermission(context, android.Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) { | ||||
|                 Log.d("BT", "No permission to connect bluetooth devices"); | ||||
|                 return; | ||||
|             } | ||||
|             String deviceName = device.getName(); | ||||
|             String deviceHardwareAddress = device.getAddress(); // MAC address | ||||
|         @SuppressLint("NotificationTrampoline") NotificationCompat.Builder builder = new NotificationCompat.Builder(context, "CHANNEL_ID") | ||||
|                 .setSmallIcon(android.R.drawable.ic_menu_info_details) | ||||
|                 .setContentTitle("子供の置き去りをしていませんか?")//通知のタイトル | ||||
|                 .setContentText("第三者からの通報が行われました。")//通知の本文 | ||||
|                 .setContentIntent(pendingIntent)//通知をタップするとActivityへ移動する | ||||
|                 .setAutoCancel(true)//通知をタップすると削除する | ||||
|                 .setPriority(NotificationCompat.PRIORITY_HIGH) // プライオリティを高く設定 | ||||
|                 .setVisibility(NotificationCompat.VISIBILITY_PUBLIC); // ロック画面に表示する | ||||
| 
 | ||||
|             if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) { | ||||
|                 //Do something if connected | ||||
|                 Log.d("BT", "Device connected"); | ||||
| 
 | ||||
|                 String registeredId = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).getString("bluetooth_device_id", "none"); | ||||
| 
 | ||||
|                 Log.d("BT_Judge", "Registered: " + registeredId); | ||||
| 
 | ||||
|                 if (deviceHardwareAddress.equals(registeredId)) { | ||||
|                     Log.d("BT_Judge", "登録済み"); | ||||
|                 } else Log.d("BT_Judge", "未登録"); | ||||
| 
 | ||||
|             } else if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) { | ||||
|                 //Do something if disconnected | ||||
|                 Log.d("BT", "Device disconnected"); | ||||
|         // NotificationChannelの作成(Android 8.0以降) | ||||
|         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { | ||||
|             NotificationManager notificationManager = context.getSystemService(NotificationManager.class); | ||||
|             if (notificationManager != null) { | ||||
|                 NotificationChannel channel = new NotificationChannel( | ||||
|                         CHANNEL_ID, | ||||
|                         "Channel Name", | ||||
|                         NotificationManager.IMPORTANCE_HIGH | ||||
|                 ); | ||||
| 
 | ||||
|                 channel.setDescription("Channel Description"); | ||||
|                 channel.enableLights(true); | ||||
|                 channel.setLightColor(Color.RED); | ||||
|                 channel.enableVibration(true); | ||||
|                 notificationManager.createNotificationChannel(channel); | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
| 
 | ||||
|     private void audioStart(){ | ||||
|         //↓通知をする際に起動するバイブレーション | ||||
|         ((Vibrator) getSystemService(Context.VIBRATOR_SERVICE)).vibrate(1000); | ||||
|         //通知のやつ↓ | ||||
|         int importance = NotificationManager.IMPORTANCE_DEFAULT; | ||||
| 
 | ||||
|         NotificationChannel channel = new NotificationChannel("CHANNEL_ID", "通報通知", importance); | ||||
|         //説明・説明 ここに通知の説明を書くことができる↓ | ||||
|         channel.setDescription("第3者からの通報を検知しました"); | ||||
| 
 | ||||
|         NotificationManager notificationManager = getSystemService(NotificationManager.class); | ||||
|         notificationManager.createNotificationChannel(channel); | ||||
|         //通知のやつ↑ | ||||
|         Log.d("nt","レスポンスを検知しました2"); | ||||
|         //↓通知の詳細設定的な奴 | ||||
|         NotificationCompat.Builder builder = new NotificationCompat | ||||
| 
 | ||||
|                 .Builder(this, "CHANNEL_ID") | ||||
|                 .setSmallIcon(android.R.drawable.ic_menu_info_details) | ||||
|                 .setContentTitle("通報検知") | ||||
|                 .setContentText("子供の置き去りを検知しました。") | ||||
|                 .setPriority(NotificationCompat.PRIORITY_DEFAULT); | ||||
| 
 | ||||
| 
 | ||||
|         NotificationManager notificationManager = (NotificationManager)context.getSystemService(context.NOTIFICATION_SERVICE); | ||||
|         if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.POST_NOTIFICATIONS) != 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; | ||||
|         } | ||||
|         notificationManager.notify(R.string.app_name, builder.build()); | ||||
| 
 | ||||
|         notificationManager.notify(R.string.app_name, builder.build());//通知の表示 | ||||
|     } | ||||
|     public void NotificationBluetooth(Context context, int time) {//実際に通知を行うメソッド | ||||
|         final String CHANNEL_ID = "my_channel_id"; | ||||
|         // 通知がクリックされたときに送信されるIntent | ||||
|         Intent intent = new Intent(context, MainActivity.class); | ||||
|         intent.setAction("OPEN_ACTIVITY"); | ||||
|         // PendingIntentの作成 | ||||
|         int requestCode = 100; | ||||
|         int flags = 0; | ||||
|         PendingIntent pendingIntent = PendingIntent.getActivity(context, requestCode, intent, flags | PendingIntent.FLAG_IMMUTABLE); | ||||
| 
 | ||||
|         ((Vibrator) getSystemService(Context.VIBRATOR_SERVICE)).vibrate(2000);//バイブレーション | ||||
| 
 | ||||
|         @SuppressLint("NotificationTrampoline") NotificationCompat.Builder builder = new NotificationCompat.Builder(context, "CHANNEL_ID") | ||||
|                 .setSmallIcon(android.R.drawable.ic_menu_info_details) | ||||
|                 .setContentTitle("子供の置き去りをしていませんか?")//通知のタイトル | ||||
|                 .setContentText("Bluetootと車の切断から"+time+"分が経過しました")//通知の本文 | ||||
|                 .setContentIntent(pendingIntent)//通知をタップするとActivityへ移動する | ||||
|                 .setAutoCancel(true)//通知をタップすると削除する | ||||
|                 .setPriority(NotificationCompat.PRIORITY_HIGH) // プライオリティを高く設定 | ||||
|                 .setVisibility(NotificationCompat.VISIBILITY_PUBLIC); // ロック画面に表示する | ||||
| 
 | ||||
|         // NotificationChannelの作成(Android 8.0以降) | ||||
|         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { | ||||
|             NotificationManager notificationManager = context.getSystemService(NotificationManager.class); | ||||
|             if (notificationManager != null) { | ||||
|                 NotificationChannel channel = new NotificationChannel( | ||||
|                         CHANNEL_ID, | ||||
|                         "Channel Name", | ||||
|                         NotificationManager.IMPORTANCE_HIGH | ||||
|                 ); | ||||
| 
 | ||||
|                 channel.setDescription("Channel Description"); | ||||
|                 channel.enableLights(true); | ||||
|                 channel.setLightColor(Color.RED); | ||||
|                 channel.enableVibration(true); | ||||
|                 notificationManager.createNotificationChannel(channel); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         NotificationManager notificationManager = (NotificationManager)context.getSystemService(context.NOTIFICATION_SERVICE); | ||||
|         if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) { | ||||
|             return; | ||||
|         } | ||||
|         notificationManager.notify(R.string.app_name, builder.build());//通知の表示 | ||||
|     } | ||||
|     public class PeriodicTaskManager {//Bluetoothの切断後に乗車状態にならなかった場合に5分毎に通知を送るメソッド | ||||
| 
 | ||||
|         private static final long INTERVAL = 5 *60* 1000; //300秒 | ||||
|         private final Handler handler; | ||||
|         private final Runnable periodicTask; | ||||
| 
 | ||||
|         public PeriodicTaskManager() { | ||||
| 
 | ||||
|             handler = new Handler(Looper.getMainLooper()); | ||||
|             periodicTask = new Runnable() { | ||||
| 
 | ||||
|                 public void run() { | ||||
| 
 | ||||
|                     //共有プリファレンス全体の準備 | ||||
|                     SharedPreferences sharedPreferences = getSharedPreferences("app_situation", MODE_PRIVATE); | ||||
| 
 | ||||
|                     int time=sharedPreferences.getInt("time",0); | ||||
|                     //共有プリファレンス 書き込みの準備 | ||||
|                     SharedPreferences.Editor E = sharedPreferences.edit(); | ||||
|                     if(time==0) {//Bluetoot切断からの時間経過(5分刻み) | ||||
|                         E.putInt("time",5); | ||||
|                         E.apply();; | ||||
|                     }else { | ||||
|                         E.putInt("time",time*2); | ||||
|                         E.apply(); | ||||
|                     } | ||||
| 
 | ||||
|                     // 5分毎に実行される処理 | ||||
|                     NotificationBluetooth(getApplicationContext(),time); | ||||
|                     Log.d("PeriodicTask", "5分後に処理を実行します"); | ||||
| 
 | ||||
|                     handler.postDelayed(this, INTERVAL); | ||||
|                 } | ||||
|             }; | ||||
|         } | ||||
| 
 | ||||
|         public void startPeriodicTask() { | ||||
|             // 最初の実行 | ||||
|             handler.postDelayed(periodicTask,INTERVAL);//一回目は5分後に行う | ||||
|         } | ||||
| 
 | ||||
|         public void stopPeriodicTask() { | ||||
|             // 定期的な処理の停止 | ||||
|             handler.removeCallbacks(periodicTask); | ||||
|         } | ||||
|     } | ||||
|     @Nullable | ||||
|     @Override | ||||
|     public IBinder onBind(Intent intent) { | ||||
| 
 | ||||
| 
 | ||||
|         return null; | ||||
|     } | ||||
| } | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user