diff --git a/.idea/misc.xml b/.idea/misc.xml index 0ad17cb..773fe0f 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,7 +1,6 @@ - - + diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a13ea4a..cbdd641 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -10,7 +10,6 @@ - - \ No newline at end of file diff --git a/app/src/main/java/com/example/childguard/GenerateQrFragment.java b/app/src/main/java/com/example/childguard/GenerateQrFragment.java new file mode 100644 index 0000000..ed71a65 --- /dev/null +++ b/app/src/main/java/com/example/childguard/GenerateQrFragment.java @@ -0,0 +1,69 @@ +package com.example.childguard; + +import android.graphics.Bitmap; +import android.graphics.drawable.BitmapDrawable; +import android.os.Bundle; + +import androidx.fragment.app.Fragment; +import androidx.print.PrintHelper; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.Toast; + +/** + * A simple {@link Fragment} subclass. + * Use the {@link GenerateQrFragment#newInstance} factory method to + * create an instance of this fragment. + */ +public class GenerateQrFragment extends Fragment { + + public GenerateQrFragment() { + // Required empty public constructor + } + public static GenerateQrFragment newInstance(String key) { + GenerateQrFragment fragment = new GenerateQrFragment(); + Bundle args = new Bundle(); + args.putString("key", key); + fragment.setArguments(args); + return fragment; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + return inflater.inflate(R.layout.fragment_generate_qr, container, false); + } + + @Override + public void onViewCreated(View view, Bundle savedInstanceState) { + + QrUtils qrUtils = new QrUtils(); + + assert getArguments() != null; + Bitmap result = qrUtils.setContext(getContext()).getBitmap(getArguments().getString("key")); + + ImageView imageView = view.findViewById(R.id.result_bitmap_image_view); + imageView.setImageBitmap(result); + + view.findViewById(R.id.button_print).setOnClickListener( v -> { + PrintHelper photoPrinter = new PrintHelper(requireContext()); + photoPrinter.setScaleMode(PrintHelper.SCALE_MODE_FIT); + photoPrinter.printBitmap("placeholder", result, () -> { + Toast.makeText(getContext(), "印刷完了", Toast.LENGTH_SHORT).show(); + }); + }); + + view.findViewById(R.id.button_cancel).setOnClickListener( v -> { + getParentFragmentManager().popBackStack(); + }); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/childguard/HomeFragment.java b/app/src/main/java/com/example/childguard/HomeFragment.java index 499a8b6..a9358b0 100644 --- a/app/src/main/java/com/example/childguard/HomeFragment.java +++ b/app/src/main/java/com/example/childguard/HomeFragment.java @@ -39,7 +39,6 @@ import java.util.Objects; * create an instance of this fragment. */ public class HomeFragment extends Fragment implements OnEventListener{ - FirebaseFirestore db = FirebaseFirestore.getInstance();//Firebaseとの紐づけ // TODO: Rename parameter arguments, choose names that match // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER @@ -85,95 +84,7 @@ public class HomeFragment extends Fragment implements OnEventListener{ @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - // Log.d("HomeFlagment_cnt", "aaaaa"); - // Inflate the layout for this fragment View view = inflater.inflate(R.layout.fragment_home, container, false); - MainActivity activity = (MainActivity) getActivity(); - //共有プリファレンス全体の準備 - SharedPreferences sharedPreferences = getActivity().getSharedPreferences("app_situation", MODE_PRIVATE); - //QRコード印刷の処理 - Button bt1 = view.findViewById(R.id.QRprinting); - bt1.setOnClickListener(v -> { - //初回起動かを保存する変数 - boolean alreadySaved = sharedPreferences.getBoolean("alreadySaved", false); - //ボタン変数の宣言 - Button parent = view.findViewById(R.id.QRprinting); - Button born = view.findViewById(R.id.QRprinting); - //falseのときにFirebaseへの登録 - if (alreadySaved) { - Log.d("HomeFragment", "already printed"); - //画面遷移&ID受け渡し - Toast.makeText(getActivity(), "再印刷", Toast.LENGTH_SHORT).show(); - QrUtils qrUtils = new QrUtils(); - PrintHelper printHelper = new PrintHelper(requireContext()); - printHelper.setScaleMode(PrintHelper.SCALE_MODE_FIT); - printHelper.printBitmap("QRコード", qrUtils.setContext(getContext()).getBitmap(sharedPreferences.getString("ID", "placeholder")), new PrintHelper.OnPrintFinishCallback() { - @Override - public void onFinish() { - Toast.makeText(getContext(), "印刷完了", Toast.LENGTH_SHORT).show(); - } - }); - return; - } else { - String valueParent = parent.getText().toString();//変数に文字列を代入 - String valueBorn = born.getText().toString();//変数に文字列を代入 - Map user = new HashMap<>();//mapの宣言 - - Log.d("HomeFragment", "onClick is called"); - - //mapに入れる - user.put("parent", valueParent); - user.put("born", valueBorn); - //新しいドキュメントにIDを作って追加 - db.collection("users") - .add(user) - .addOnSuccessListener(new OnSuccessListener() { - @Override - public void onSuccess(DocumentReference documentReference) { - //成功したら - //documentReference.getId()でID取得 - Log.d(TAG, "DocumentSnapshot added with ID: " + documentReference.getId()); - SharedPreferences.Editor e = sharedPreferences.edit(); - // キー"alreadySaved"の値をtrueにする - e.putBoolean("alreadySaved", true); - //確定処理 - e.apply(); - //画面遷移&ID受け渡し - str_key = "" + documentReference.getId(); - Toast.makeText(getActivity(), "初回登録", Toast.LENGTH_SHORT).show(); - QrUtils qrUtils = new QrUtils(); - PrintHelper printHelper = new PrintHelper(requireContext()); - printHelper.setScaleMode(PrintHelper.SCALE_MODE_FIT); - printHelper.printBitmap("QRコード", qrUtils.setContext(getContext()).getBitmap(documentReference.getId()), new PrintHelper.OnPrintFinishCallback() { - @Override - public void onFinish() { - Toast.makeText(getContext(), "印刷完了", Toast.LENGTH_SHORT).show(); - } - }); - } - }) - .addOnFailureListener(new OnFailureListener() { - @Override - public void onFailure(@NonNull Exception e) { - //失敗したら - Log.w(TAG, "Error adding document", e); - } - }); - } - }); - //bluetooth設定ボタンの処理 - Button bt2 = view.findViewById(R.id.Bluetooth_setup); - bt2.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - replaceFragment(new bluetooth_setupFragment()); - } - }); - - //デバック用ボタン - view.findViewById(R.id.bt_debug).setOnClickListener( v -> { - Toast.makeText(getContext(), PreferenceManager.getDefaultSharedPreferences(getContext().getApplicationContext()).getString("bluetooth_device_id", "none"), Toast.LENGTH_SHORT).show(); - }); return view; } @@ -183,7 +94,6 @@ public class HomeFragment extends Fragment implements OnEventListener{ public void onResume() { super.onResume(); Log.d("HomeFragment", "onResume: called"); - updateUiState(getActivity().getSharedPreferences("app_situation", MODE_PRIVATE).getBoolean("car", false)); } //画面遷移メソッド @@ -200,17 +110,22 @@ public class HomeFragment extends Fragment implements OnEventListener{ transaction.commit(); } - private void updateUiState(boolean state) { + private boolean updateUiState(boolean state) { Log.d("HomeFragment", "updateUiState: called"); // Init TextView tv; FrameLayout fl; try { tv = requireView().findViewById(R.id.situation); - fl = getView().findViewById(R.id.situation_bg); + fl = requireView().findViewById(R.id.situation_bg); } catch (NullPointerException e) { Log.d("HomeFragment", "updateUiState: view is null"); - return; + 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); + return false; } String get_on = "\n乗車状態"; String get_off = "\n降車状態"; @@ -223,12 +138,14 @@ public class HomeFragment extends Fragment implements OnEventListener{ fl.setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.frame_style, null)); tv.setText(get_off); } + + return true; } @Override - public void onEvent(boolean state) { + public boolean onEvent(boolean state) { Log.d("HomeFragment", "onEvent: called"); - updateUiState(state); + return updateUiState(state); } } diff --git a/app/src/main/java/com/example/childguard/MainActivity.java b/app/src/main/java/com/example/childguard/MainActivity.java index 0f9c8d4..ccac9c0 100644 --- a/app/src/main/java/com/example/childguard/MainActivity.java +++ b/app/src/main/java/com/example/childguard/MainActivity.java @@ -1,7 +1,11 @@ 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; @@ -19,6 +23,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; import android.graphics.Color; +import android.net.Uri; import android.os.Bundle; import android.os.Vibrator; @@ -49,12 +54,18 @@ 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; public class MainActivity extends AppCompatActivity { BluetoothManager bluetoothManager; BluetoothAdapter bluetoothAdapter; + DocumentReference mDocRef; + private HomeFragment homeFragment; public static final String TAG = "InspirationQuote"; @@ -68,6 +79,25 @@ public class MainActivity extends AppCompatActivity { return df.format(date); } + private final ActivityResultLauncher QrLauncher = registerForActivityResult( + new ScanContract(), + result -> { + String contents = result.getContents(); + if (contents == null) { + Toast.makeText(this, "QRコードが読み取れませんでした", Toast.LENGTH_LONG).show(); + } else if (!contents.contains("https://practicefirestore1-8808c.web.app/")) { + Toast.makeText(this, "Chiled Guardに対応するQRコードではありません", Toast.LENGTH_LONG).show(); + } else { + //URLの表示 + Toast.makeText(this, contents, Toast.LENGTH_SHORT).show(); + //ブラウザを起動し、URL先のサイトを開く + CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder(); + CustomTabsIntent customTabsIntent = builder.build(); + customTabsIntent.launchUrl(this, Uri.parse(contents)); + } + } + ); + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -82,22 +112,35 @@ public class MainActivity extends AppCompatActivity { { if (v.getItemId() == findViewById(R.id.navigation_home).getId()) { + findViewById(R.id.fab_scan_qr_code).setVisibility(FrameLayout.VISIBLE); getSupportFragmentManager().beginTransaction() .replace(findViewById(R.id.fragmentContainerView).getId(), this.homeFragment) .addToBackStack(null) .commit(); - } else if (v.getItemId() == findViewById(R.id.navigation_QR).getId()) { - getSupportFragmentManager().beginTransaction() - .replace(findViewById(R.id.fragmentContainerView).getId(), QRFragment.newInstance("test", "tset")) - .commit(); } else if (v.getItemId() == findViewById(R.id.navigation_notification).getId()) { + findViewById(R.id.fab_scan_qr_code).setVisibility(FrameLayout.VISIBLE); getSupportFragmentManager().beginTransaction() .replace(findViewById(R.id.fragmentContainerView).getId(), NotificationFragment.newInstance("test", "test")) + .addToBackStack(null) + .commit(); + } else if (v.getItemId() == findViewById(R.id.navigation_settings).getId()) { + findViewById(R.id.fab_scan_qr_code).setVisibility(FrameLayout.GONE); + getSupportFragmentManager().beginTransaction() + .replace(findViewById(R.id.fragmentContainerView).getId(), SettingFragment.newInstance()) + .addToBackStack(null) .commit(); } return true; }); + findViewById(R.id.fab_scan_qr_code).setOnClickListener(v -> { + Log.d("QRFragment", "onClick: called"); + //QRリーダ起動 + ScanOptions options = new ScanOptions(); + options.setPrompt("QRコードを読み取ってください"); + QrLauncher.launch(options); + }); + //Bluetooth検知機能 IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED); @@ -116,13 +159,16 @@ public class MainActivity extends AppCompatActivity { @Override protected void onResume() { + 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."); return; } - DocumentReference mDocRef = FirebaseFirestore.getInstance().document("users/" + IdPref);//現在の位置を取得 + mDocRef = FirebaseFirestore.getInstance().document("users/" + IdPref);//現在の位置を取得 + this.flg = false; initNotification(mDocRef); super.onResume(); @@ -164,11 +210,13 @@ public class MainActivity extends AppCompatActivity { E.putBoolean("car", true); E.apply(); } - - HomeFragment fragment = new HomeFragment(); - getSupportFragmentManager().beginTransaction().replace(R.id.fragmentContainerView, fragment).commit(); - - homeFragment.onEvent(!isInCar); + // 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"); + } } } flg = true; @@ -241,15 +289,6 @@ public class MainActivity extends AppCompatActivity { notificationManager.notify(R.string.app_name, builder.build()); - } - - @Override - public void onStop() { - super.onStop(); - Intent intent = new Intent(getApplication(), TestService.class); - startService(intent); - - } //Bluetooth_setupの戻るボタン diff --git a/app/src/main/java/com/example/childguard/OnEventListener.java b/app/src/main/java/com/example/childguard/OnEventListener.java index f093cb4..8bf8757 100644 --- a/app/src/main/java/com/example/childguard/OnEventListener.java +++ b/app/src/main/java/com/example/childguard/OnEventListener.java @@ -2,5 +2,5 @@ package com.example.childguard; public interface OnEventListener { - void onEvent(boolean state); + boolean onEvent(boolean state); } diff --git a/app/src/main/java/com/example/childguard/SettingFragment.java b/app/src/main/java/com/example/childguard/SettingFragment.java new file mode 100644 index 0000000..6fd9aa9 --- /dev/null +++ b/app/src/main/java/com/example/childguard/SettingFragment.java @@ -0,0 +1,116 @@ +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 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 com.google.firebase.firestore.FirebaseFirestore; + +import java.util.HashMap; +import java.util.Map; + +/** + * A simple {@link Fragment} subclass. + * Use the {@link SettingFragment#newInstance} factory method to + * create an instance of this fragment. + */ +public class SettingFragment extends Fragment { + + FirebaseFirestore db; + public SettingFragment() { + // Required empty public constructor + } + + public static SettingFragment newInstance() { + SettingFragment fragment = new SettingFragment(); + Bundle args = new Bundle(); + fragment.setArguments(args); + return fragment; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + return inflater.inflate(R.layout.fragment_setting, container, false); + } + + @Override + public void onViewCreated(View view, Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + + db = FirebaseFirestore.getInstance();//Firebaseとの紐づけ + + view.findViewById(R.id.button_bluetooth_setting).setOnClickListener( v -> { + getParentFragmentManager().beginTransaction().replace(R.id.fragmentContainerView, bluetooth_setupFragment.newInstance("test", "test")).addToBackStack(null).commit(); + }); + + view.findViewById(R.id.button_print_qr).setOnClickListener( v -> { + SharedPreferences sharedPreferences = getActivity().getSharedPreferences("app_situation", MODE_PRIVATE); + boolean alreadySaved = sharedPreferences.getBoolean("alreadySaved", false); + //falseのときにFirebaseへの登録 + if (alreadySaved) { + Log.d("HomeFragment", "already printed"); + //画面遷移&ID受け渡し + 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 user = new HashMap<>();//mapの宣言 + + Log.d("HomeFragment", "onClick is called"); + + //mapに入れる + user.put("parent", valueParent); + user.put("born", valueBorn); + //新しいドキュメントにIDを作って追加 + db.collection("users") + .add(user) + .addOnSuccessListener(documentReference -> { + //成功したら + //documentReference.getId()でID取得 + Log.d(TAG, "DocumentSnapshot added with ID: " + documentReference.getId()); + SharedPreferences.Editor e = sharedPreferences.edit(); + // キー"alreadySaved"の値をtrueにする + e.putBoolean("alreadySaved", true); + //確定処理 + e.apply(); + //画面遷移&ID受け渡し + SharedPreferences sharedPreferences1 = getActivity().getSharedPreferences("app_situation", MODE_PRIVATE); + SharedPreferences.Editor editor = sharedPreferences1.edit(); + editor.putString("ID", documentReference.getId()); + editor.apply(); + + Toast.makeText(getActivity(), "初回登録", Toast.LENGTH_SHORT).show(); + getParentFragmentManager().beginTransaction().addToBackStack(null).replace(R.id.fragmentContainerView, GenerateQrFragment.newInstance(documentReference.getId())).commit(); + }) + .addOnFailureListener(e -> { + //失敗したら + Log.w(TAG, "Error adding document", e); + }); + } + }); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/childguard/TestService.java b/app/src/main/java/com/example/childguard/TestService.java deleted file mode 100644 index 00c9c31..0000000 --- a/app/src/main/java/com/example/childguard/TestService.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.example.childguard; - -import android.app.NotificationChannel; -import android.app.NotificationManager; -import android.app.Service; -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.os.IBinder; -import android.os.Vibrator; -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 { - - public int onStartCommand(Intent intent, int flags, int startId) { - - - audioStart(); - - return START_NOT_STICKY; - - } - - 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); - - - 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()); - - } - - @Nullable - @Override - public IBinder onBind(Intent intent) { - - - return null; - } -} \ No newline at end of file diff --git a/app/src/main/res/drawable/baseline_app_settings_alt_24.xml b/app/src/main/res/drawable/baseline_app_settings_alt_24.xml new file mode 100644 index 0000000..875e221 --- /dev/null +++ b/app/src/main/res/drawable/baseline_app_settings_alt_24.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 80425d1..90b2a97 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -36,5 +36,14 @@ app:layout_constraintRight_toRightOf="parent" app:menu="@menu/bottom_menu" /> + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_generate_qr.xml b/app/src/main/res/layout/fragment_generate_qr.xml new file mode 100644 index 0000000..27933f9 --- /dev/null +++ b/app/src/main/res/layout/fragment_generate_qr.xml @@ -0,0 +1,46 @@ + + + + + + + +