From ef9beff05857e013854502684ba1d7f30ed1753f Mon Sep 17 00:00:00 2001 From: dingdoong <113041115+dingdoong@users.noreply.github.com> Date: Fri, 31 May 2024 16:31:44 +0900 Subject: [PATCH 1/2] add afterAction1.0 add afterAction layout, afterAction activity. change order bottom sheet list --- moti/app/src/main/AndroidManifest.xml | 1 + .../ui/addMemo/AddLocationMemoFragment.kt | 9 + .../moti/ui/afterAction/AfterAction.kt | 57 +++++ .../main/res/layout/activity_after_action.xml | 216 ++++++++++++++++++ .../src/main/res/layout/fragment_add_memo.xml | 155 ++++++++----- 5 files changed, 387 insertions(+), 51 deletions(-) create mode 100644 moti/app/src/main/java/com/example/moti/ui/afterAction/AfterAction.kt create mode 100644 moti/app/src/main/res/layout/activity_after_action.xml diff --git a/moti/app/src/main/AndroidManifest.xml b/moti/app/src/main/AndroidManifest.xml index ea822d0..3a89398 100644 --- a/moti/app/src/main/AndroidManifest.xml +++ b/moti/app/src/main/AndroidManifest.xml @@ -67,6 +67,7 @@ android:exported="false" /> + + if (isChecked) { + // 스위치가 켜진 상태일 때 + silentDetailTextView.text = "켜짐" + } else { + // 스위치가 꺼진 상태일 때 + silentDetailTextView.text = "꺼짐" + } + } + + // 스위치 상태 변화 감지 + silentActionSwitch.setOnCheckedChangeListener { _, isChecked -> + if (isChecked) { + // 스위치가 켜진 상태일 때 + silentDetailTextView.text = "켜짐" + + } else { + // 스위치가 꺼진 상태일 때 + silentDetailTextView.text = "없음" + } + } + } + + + +} \ No newline at end of file diff --git a/moti/app/src/main/res/layout/activity_after_action.xml b/moti/app/src/main/res/layout/activity_after_action.xml new file mode 100644 index 0000000..a34d0bd --- /dev/null +++ b/moti/app/src/main/res/layout/activity_after_action.xml @@ -0,0 +1,216 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/moti/app/src/main/res/layout/fragment_add_memo.xml b/moti/app/src/main/res/layout/fragment_add_memo.xml index 6183642..c6a572f 100644 --- a/moti/app/src/main/res/layout/fragment_add_memo.xml +++ b/moti/app/src/main/res/layout/fragment_add_memo.xml @@ -452,58 +452,7 @@ android:layout_marginStart="20dp" android:layout_marginEnd="20dp"/> - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + From f13c43167b4f2b106591635a0508629f09021365 Mon Sep 17 00:00:00 2001 From: dingdoong <113041115+dingdoong@users.noreply.github.com> Date: Sun, 2 Jun 2024 16:19:59 +0900 Subject: [PATCH 2/2] add after action --- moti/app/src/main/AndroidManifest.xml | 10 + .../com/example/moti/alarm/AlarmShooter.kt | 104 ++++++++-- .../com/example/moti/data/MotiDatabase.kt | 3 +- .../com/example/moti/data/entity/Alarm.kt | 26 ++- .../ui/addMemo/AddLocationMemoFragment.kt | 49 ++++- .../moti/ui/afterAction/AfterAction.kt | 187 ++++++++++++++++-- .../com/example/moti/ui/main/MainActivity.kt | 38 +++- .../main/res/layout/activity_after_action.xml | 11 +- .../app/src/main/res/layout/activity_main.xml | 5 + .../app/src/main/res/layout/app_list_item.xml | 19 ++ .../main/res/layout/dialog_app_chooser.xml | 12 ++ .../src/main/res/layout/fragment_add_memo.xml | 8 - moti/app/src/main/res/layout/item_app.xml | 20 ++ .../app/src/main/res/layout/item_app_info.xml | 23 +++ 14 files changed, 468 insertions(+), 47 deletions(-) create mode 100644 moti/app/src/main/res/layout/app_list_item.xml create mode 100644 moti/app/src/main/res/layout/dialog_app_chooser.xml create mode 100644 moti/app/src/main/res/layout/item_app.xml create mode 100644 moti/app/src/main/res/layout/item_app_info.xml diff --git a/moti/app/src/main/AndroidManifest.xml b/moti/app/src/main/AndroidManifest.xml index 3a89398..1b97353 100644 --- a/moti/app/src/main/AndroidManifest.xml +++ b/moti/app/src/main/AndroidManifest.xml @@ -16,6 +16,16 @@ + + + + + + + + + = alarm.radius && !alarm.whenArrival) { val now = LocalDateTime.now() val lastNoti = alarm.lastNoti val intervalMinutes = alarm.interval ?: 1440 if (lastNoti == null || ChronoUnit.MINUTES.between(lastNoti, now) >= intervalMinutes) { - - if(alarm.hasBanner){ - //배너 설정 on -> 배너 알림 + if (alarm.hasBanner) { + // 배너 설정 on -> 배너 알림 sendNotification(alarm) - } - else{ - //전체화면알림 + } else { + // 전체화면알림 sendFullScreenAlarm(context, alarm) } alarm.lastNoti = now database?.alarmDao()?.update(alarm) } - } + if (alarm.isSilentMode) { + Log.d("AlarmShooter", "Silent mode is enabled. Performing silent mode action.") + setSilentMode() + } + + if (alarm.isOnAppMode) { + Log.d("AlarmShooter", "App mode is enabled. Launching app.") + openApp(alarm.appPackageName) + } + if (alarm.phoneNumber != null && alarm.message != null) { + Log.d("AlarmShooter", "Sending SMS to ${alarm.phoneNumber}") + sendSMS(alarm.phoneNumber!!, alarm.message!!) + } + } } } } } + private fun sendFullScreenAlarm(context: Context, alarm: Alarm) { Log.e("aa", "sendFullScreenAlarm22") acquireWakeLock(context) @@ -255,4 +275,58 @@ class AlarmShooter(private val context: Context) { notificationManager.notify(alarm.alarmId.toInt() + 1024, notification) } + fun setSilentMode() { + val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager + val audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (!notificationManager.isNotificationPolicyAccessGranted) { + // 권한이 없는 경우 권한 설정 화면으로 이동 + val intent = Intent(Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS) + intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK + context.startActivity(intent) + return + } + } + + try { + audioManager.ringerMode = AudioManager.RINGER_MODE_SILENT + Log.d("AlarmShooter", "Phone set to silent mode") + } catch (e: SecurityException) { + Log.e("AlarmShooter", "Could not change ringer mode", e) + } + } + + fun openApp(packageName: String?) { + if (packageName.isNullOrEmpty()) { + Log.e("AlarmShooter", "Package name is null or empty") + return + } + + val packageManager = context.packageManager + val launchIntent = packageManager.getLaunchIntentForPackage(packageName) + + if (launchIntent != null) { + launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + context.startActivity(launchIntent) + Log.d("AlarmShooter", "Launched app: $packageName") + } else { + Log.e("AlarmShooter", "Cannot find app with package name: $packageName") + } + } + + fun sendSMS(phoneNumber: String, message: String) { + if (ContextCompat.checkSelfPermission(context, Manifest.permission.SEND_SMS) == PackageManager.PERMISSION_GRANTED) { + try { + val smsManager = SmsManager.getDefault() + smsManager.sendTextMessage(phoneNumber, null, message, null, null) + Log.d("AlarmShooter", "SMS sent to $phoneNumber") + } catch (e: Exception) { + Log.e("AlarmShooter", "Failed to send SMS", e) + } + } else { + Log.e("AlarmShooter", "SMS permission not granted") + } + } + } diff --git a/moti/app/src/main/java/com/example/moti/data/MotiDatabase.kt b/moti/app/src/main/java/com/example/moti/data/MotiDatabase.kt index f7e24b4..fa052fb 100644 --- a/moti/app/src/main/java/com/example/moti/data/MotiDatabase.kt +++ b/moti/app/src/main/java/com/example/moti/data/MotiDatabase.kt @@ -11,12 +11,11 @@ import com.example.moti.data.dao.RecentLocationDao import com.example.moti.data.dao.TagDao import com.example.moti.data.entity.Alarm import com.example.moti.data.entity.AlarmAndTag -import com.example.moti.data.entity.Location import com.example.moti.data.entity.RecentLocation import com.example.moti.data.entity.Tag @Database(entities = [Alarm::class, AlarmAndTag::class, RecentLocation::class, Tag::class], - version = 7) + version = 8) @TypeConverters(Converters::class) abstract class MotiDatabase :RoomDatabase(){ abstract fun alarmDao():AlarmDao diff --git a/moti/app/src/main/java/com/example/moti/data/entity/Alarm.kt b/moti/app/src/main/java/com/example/moti/data/entity/Alarm.kt index 17da370..f2aa6e9 100644 --- a/moti/app/src/main/java/com/example/moti/data/entity/Alarm.kt +++ b/moti/app/src/main/java/com/example/moti/data/entity/Alarm.kt @@ -1,6 +1,5 @@ package com.example.moti.data.entity -import android.graphics.Bitmap import android.net.Uri import androidx.room.Embedded import androidx.room.Entity @@ -29,7 +28,14 @@ data class Alarm ( @TypeConverters(AlarmtoneConverter::class) var alarmtone: Alarmtone?, var useVibration : Boolean, - var isSleep : Boolean + var isSleep : Boolean, + var isOnAppMode: Boolean, //앱열기 상태 저장 + var isMessageMode: Boolean, //메시지 상태 저장 + var isSilentMode: Boolean, // 무음 모드 상태 저장 + var phoneNumber: String?, // 전화번호 저장 + var message: String?, // 문자 내역 저장 + var appPackageName: String? // 앱 패키지명 저장 + ) { constructor( title : String, @@ -46,7 +52,13 @@ data class Alarm ( image : Uri?, alarmtone: Alarmtone?, useVibration : Boolean, - isSleep: Boolean + isSleep: Boolean, + isOnAppMode: Boolean, + isMesaageMode: Boolean, + isSilentMode: Boolean, + phoneNumber: String?, + message: String?, + appPackageName: String? ) : this( 0, title, @@ -63,6 +75,12 @@ data class Alarm ( image, alarmtone, useVibration, - isSleep + isSleep, + isOnAppMode, + isMesaageMode, + isSilentMode, + phoneNumber, + message, + appPackageName ) } \ No newline at end of file diff --git a/moti/app/src/main/java/com/example/moti/ui/addMemo/AddLocationMemoFragment.kt b/moti/app/src/main/java/com/example/moti/ui/addMemo/AddLocationMemoFragment.kt index 28aa119..fd4fc46 100644 --- a/moti/app/src/main/java/com/example/moti/ui/addMemo/AddLocationMemoFragment.kt +++ b/moti/app/src/main/java/com/example/moti/ui/addMemo/AddLocationMemoFragment.kt @@ -103,6 +103,14 @@ class AddLocationMemoFragment : BottomSheetDialogFragment(), private var alarmtone : Alarmtone? = Alarmtone.Default; private var useVibration : Boolean = true; + private var onAppMode : Boolean = false + private var messageMode : Boolean = false + private var silentMode : Boolean = false + private var phoneNum : String? = null + private var messageText : String? = null + private var appPackage : String? = null + private var contactName: String? = null + private var appName: String? = null private var repeatChecked = false private var tagChecked = true @@ -120,7 +128,6 @@ class AddLocationMemoFragment : BottomSheetDialogFragment(), private const val ARG_LNG = "lng" private const val ARG_id = "id" private const val REQUEST_CODE_ALARM_CATEGORY = 1 - private const val ALARM_CATEGORY_REQUEST_CODE = 1001 fun newInstance(name: String, lat: Double, lng: Double,id:Long?): AddLocationMemoFragment { val fragment = AddLocationMemoFragment() val args = Bundle().apply { @@ -142,6 +149,24 @@ class AddLocationMemoFragment : BottomSheetDialogFragment(), private val reverseGeocoding = ReverseGeocoding(this) + private val startForResult = + registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> + if (result.resultCode == Activity.RESULT_OK) { + result.data?.let { + phoneNum = it.getStringExtra("contactPhone") + messageMode = it.getBooleanExtra("messageSwitchOn", false) + messageText = it.getStringExtra("messageText") + onAppMode = it.getBooleanExtra("onAppSwitchOn", false) + appPackage = it.getStringExtra("selectedAppPackageName") + silentMode = it.getBooleanExtra("silentSwitchOn", false) + contactName = it.getStringExtra("contactName") + appName = it.getStringExtra("appName") + } + } + } + + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) if (requestCode == REQUEST_CODE_ALARM_CATEGORY && resultCode == Activity.RESULT_OK) { @@ -215,6 +240,7 @@ class AddLocationMemoFragment : BottomSheetDialogFragment(), override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) initUi() + binding.inOrOutRadioGroup.setOnCheckedChangeListener { radioGroup, i -> when(i) { binding.inRadioBtn.id -> { @@ -310,7 +336,13 @@ class AddLocationMemoFragment : BottomSheetDialogFragment(), image = imageUri, alarmtone = alarmtone, useVibration = useVibration, - isSleep = false + isSleep = false, + isOnAppMode = onAppMode, + isMesaageMode = messageMode, + isSilentMode = silentMode, + phoneNumber = phoneNum, + message = messageText, + appPackageName = appPackage ) if (alarmId != null) { alarm.alarmId = alarmId as Long @@ -358,9 +390,20 @@ class AddLocationMemoFragment : BottomSheetDialogFragment(), val afterActionLinearLayout: LinearLayout = view.findViewById(R.id.afterActionLinearLayout) afterActionLinearLayout.setOnClickListener { val intent = Intent(activity, AfterAction::class.java) - startActivity(intent) + intent.putExtra("silentSwitchOn", silentMode) + intent.putExtra("contactPhone", phoneNum) + intent.putExtra("messageSwitchOn", messageMode) + intent.putExtra("messageText", messageText) + intent.putExtra("onAppSwitchOn", onAppMode) + intent.putExtra("selectedAppPackageName", appPackage) + intent.putExtra("contactName", contactName) + intent.putExtra("appName", appName) + startForResult.launch(intent) } + + + } private fun initUi() { diff --git a/moti/app/src/main/java/com/example/moti/ui/afterAction/AfterAction.kt b/moti/app/src/main/java/com/example/moti/ui/afterAction/AfterAction.kt index 4de6806..5b46e24 100644 --- a/moti/app/src/main/java/com/example/moti/ui/afterAction/AfterAction.kt +++ b/moti/app/src/main/java/com/example/moti/ui/afterAction/AfterAction.kt @@ -1,18 +1,51 @@ package com.example.moti.ui.afterAction +import android.Manifest +import android.app.Activity +import android.content.Context +import android.content.Intent +import android.content.pm.ApplicationInfo +import android.content.pm.PackageManager +import android.graphics.drawable.Drawable import android.os.Bundle +import android.provider.ContactsContract +import android.util.Log +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ArrayAdapter +import android.widget.EditText import android.widget.ImageButton +import android.widget.ImageView import android.widget.TextView +import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.widget.SwitchCompat +import androidx.core.app.ActivityCompat +import androidx.core.content.ContextCompat import com.example.moti.R class AfterAction : AppCompatActivity() { - private lateinit var silentDetailTextView: TextView private lateinit var silentActionSwitch: SwitchCompat private lateinit var openAppTextView: TextView private lateinit var openAppSwitch: SwitchCompat + private lateinit var messageTextView: TextView + private lateinit var messageSwitch: SwitchCompat + private lateinit var messageEditText: EditText + private var contactName: String? = null + private var silentSwitchOn: Boolean = false + private var contactPhone: String? = null + private var messageSwitchOn: Boolean = false + private var messageText: String? = null + private var onAppSwitchOn: Boolean = false + private var selectedAppPackageName: String? = null + private var appName: String? = null + + companion object { + private const val PERMISSION_REQUEST_READ_CONTACTS = 100 + private const val PICK_CONTACT_REQUEST = 1 + } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -20,38 +53,166 @@ class AfterAction : AppCompatActivity() { val btnBack: ImageButton = findViewById(R.id.btnBack) btnBack.setOnClickListener { + val resultIntent = Intent().apply { + messageText = messageEditText.text.toString() + putExtra("contactPhone", contactPhone) + putExtra("messageSwitchOn", messageSwitchOn) + putExtra("messageText", messageText) + putExtra("onAppSwitchOn", onAppSwitchOn) + putExtra("selectedAppPackageName", selectedAppPackageName) + putExtra("silentSwitchOn", silentSwitchOn) + putExtra("contactName", contactName) + putExtra("appName", appName) + } + setResult(Activity.RESULT_OK, resultIntent) finish() } + // 스위치와 텍스트뷰 초기화 + messageTextView = findViewById(R.id.messageDetailTextView) + messageSwitch = findViewById(R.id.messageAction) silentDetailTextView = findViewById(R.id.silentDetailTextView) silentActionSwitch = findViewById(R.id.silentAction) openAppTextView = findViewById(R.id.openAppDetailTextView) openAppSwitch = findViewById(R.id.openAppAction) + messageEditText = findViewById(R.id.messageEditText) + + // Intent에서 데이터를 가져옴 + silentSwitchOn = intent.getBooleanExtra("silentSwitchOn", false) + contactPhone = intent.getStringExtra("contactPhone") + messageSwitchOn = intent.getBooleanExtra("messageSwitchOn", false) + messageText = intent.getStringExtra("messageText") + onAppSwitchOn = intent.getBooleanExtra("onAppSwitchOn", false) + selectedAppPackageName = intent.getStringExtra("selectedAppPackageName") + appName = intent.getStringExtra("appName") + contactName = intent.getStringExtra("contactName") + + // 초기 UI 상태 설정 + silentDetailTextView.text = if (silentSwitchOn) "켜짐" else "꺼짐" + silentActionSwitch.isChecked = silentSwitchOn + + messageSwitch.isChecked = messageSwitchOn + messageTextView.text = if (messageSwitchOn) "$contactName, $contactPhone" else "없음" + messageEditText.setText(messageText) + messageEditText.visibility = if (messageSwitchOn) View.VISIBLE else View.GONE + + openAppSwitch.isChecked = onAppSwitchOn + openAppTextView.text = if (onAppSwitchOn) appName else "없음" // 스위치 상태 변화 감지 silentActionSwitch.setOnCheckedChangeListener { _, isChecked -> + silentDetailTextView.text = if (isChecked) "켜짐" else "꺼짐" + silentSwitchOn = isChecked + } + + openAppSwitch.setOnCheckedChangeListener { _, isChecked -> if (isChecked) { - // 스위치가 켜진 상태일 때 - silentDetailTextView.text = "켜짐" + showAppList() + onAppSwitchOn = true } else { - // 스위치가 꺼진 상태일 때 - silentDetailTextView.text = "꺼짐" + openAppTextView.text = "없음" + onAppSwitchOn = false } } - // 스위치 상태 변화 감지 - silentActionSwitch.setOnCheckedChangeListener { _, isChecked -> + messageSwitch.setOnCheckedChangeListener { _, isChecked -> if (isChecked) { - // 스위치가 켜진 상태일 때 - silentDetailTextView.text = "켜짐" - + messageTextView.text = "켜짐" + sendSMS() + messageEditText.visibility = EditText.VISIBLE + messageSwitchOn = true } else { - // 스위치가 꺼진 상태일 때 - silentDetailTextView.text = "없음" + messageTextView.text = "없음" + messageEditText.visibility = EditText.GONE + messageEditText.text.clear() + messageSwitchOn = false + messageText = null } } } + private fun showAppList() { + val pm = packageManager + val apps = pm.getInstalledApplications(PackageManager.GET_META_DATA) + .filter { it.flags and ApplicationInfo.FLAG_SYSTEM == 0 } + + val appNames = apps.map { pm.getApplicationLabel(it).toString() } + val appIcons = apps.map { pm.getApplicationIcon(it) } + val appPackages = apps.map { it.packageName } + val builder = AlertDialog.Builder(this) + builder.setTitle("앱 선택") + + val appList = appNames.mapIndexed { index, name -> + name to appIcons[index] + } + + val adapter = AppListAdapter(this, appList) + builder.setAdapter(adapter) { _, which -> + val selectedAppName = appNames[which] + selectedAppPackageName = appPackages[which] + appName = appNames[which] + openAppTextView.text = selectedAppName + } -} \ No newline at end of file + builder.setNegativeButton("취소", null) + builder.show() + } + + private fun sendSMS() { + val status = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) + if (status == PackageManager.PERMISSION_GRANTED) { + Log.d("test", "permission granted") + val intent = Intent(Intent.ACTION_PICK, ContactsContract.CommonDataKinds.Phone.CONTENT_URI) + startActivityForResult(intent, PICK_CONTACT_REQUEST) + } else { + ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.READ_CONTACTS), PERMISSION_REQUEST_READ_CONTACTS) + Log.d("test", "permission denied") + } + } + + override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults) + if (requestCode == PERMISSION_REQUEST_READ_CONTACTS) { + if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) { + sendSMS() + } else { + Log.d("Permission", "Permission denied to read contacts") + } + } + } + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, resultCode, data) + if (requestCode == PICK_CONTACT_REQUEST && resultCode == RESULT_OK) { + data?.data?.let { contactUri -> + val projection = arrayOf(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER) + contentResolver.query(contactUri, projection, null, null, null)?.use { cursor -> + if (cursor.moveToFirst()) { + val nameIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME) + val numberIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER) + contactName = cursor.getString(nameIndex) + contactPhone = cursor.getString(numberIndex) + Log.d("Contact Info", "Name: $contactName, Phone: $contactPhone") + messageTextView.text = "$contactName, $contactPhone" + } + } + } + } + } +} + +class AppListAdapter(context: Context, private val appList: List>) : + ArrayAdapter>(context, R.layout.app_list_item, appList) { + override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { + val view = convertView ?: LayoutInflater.from(context).inflate(R.layout.app_list_item, parent, false) + val appName = view.findViewById(R.id.appName) + val appIcon = view.findViewById(R.id.appIcon) + + val (name, icon) = appList[position] + appName.text = name + appIcon.setImageDrawable(icon) + + return view + } +} diff --git a/moti/app/src/main/java/com/example/moti/ui/main/MainActivity.kt b/moti/app/src/main/java/com/example/moti/ui/main/MainActivity.kt index d381c74..f67d651 100644 --- a/moti/app/src/main/java/com/example/moti/ui/main/MainActivity.kt +++ b/moti/app/src/main/java/com/example/moti/ui/main/MainActivity.kt @@ -1,6 +1,7 @@ package com.example.moti.ui.main import android.Manifest +import android.app.NotificationManager import android.content.Context import android.content.Intent import android.content.pm.PackageManager @@ -30,6 +31,8 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import java.time.LocalDateTime +import android.provider.Settings + class MainActivity : AppCompatActivity() { @@ -39,6 +42,7 @@ class MainActivity : AppCompatActivity() { private lateinit var combinedVibration: CombinedVibration private var currentFragmentTag: String? = null private var dataSaved = false + private val PERMISSION_REQUEST_CODE = 1 companion object { private const val LOCATION_PERMISSION_REQUEST_CODE = 321 @@ -79,7 +83,33 @@ class MainActivity : AppCompatActivity() { vibrator = getSystemService(Context.VIBRATOR_MANAGER_SERVICE) as VibratorManager vibrationEffect = VibrationEffect.createOneShot(5L, VibrationEffect.DEFAULT_AMPLITUDE) combinedVibration = CombinedVibration.createParallel(vibrationEffect) + checkAndRequestPermissions() + } + private fun checkAndRequestPermissions() { + val requiredPermissions = arrayOf( + Manifest.permission.READ_CONTACTS, + Manifest.permission.SEND_SMS + ) + + val permissionsToRequest = requiredPermissions.filter { + ContextCompat.checkSelfPermission(this, it) != PackageManager.PERMISSION_GRANTED + } + + if (permissionsToRequest.isNotEmpty()) { + ActivityCompat.requestPermissions(this, permissionsToRequest.toTypedArray(), PERMISSION_REQUEST_CODE) + } + + // Notification Policy Access 권한 확인 + val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (!notificationManager.isNotificationPolicyAccessGranted) { + val intent = Intent(Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS) + intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK + startActivity(intent) + } + } } + override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) // 현재 표시된 프래그먼트의 태그를 저장 @@ -240,7 +270,13 @@ class MainActivity : AppCompatActivity() { image = null, alarmtone= null, useVibration =false, - isSleep = false + isSleep = false, + isOnAppMode = false, + isMesaageMode = false, + isSilentMode = false, + phoneNumber = null, + message = null, + appPackageName = null ) val list: List = listOf() CoroutineScope(Dispatchers.IO).launch { diff --git a/moti/app/src/main/res/layout/activity_after_action.xml b/moti/app/src/main/res/layout/activity_after_action.xml index a34d0bd..07baa1d 100644 --- a/moti/app/src/main/res/layout/activity_after_action.xml +++ b/moti/app/src/main/res/layout/activity_after_action.xml @@ -23,7 +23,7 @@ @@ -205,6 +205,15 @@ style="@style/category_toggle"/> + + + + \ No newline at end of file diff --git a/moti/app/src/main/res/layout/app_list_item.xml b/moti/app/src/main/res/layout/app_list_item.xml new file mode 100644 index 0000000..647f6e7 --- /dev/null +++ b/moti/app/src/main/res/layout/app_list_item.xml @@ -0,0 +1,19 @@ + + + + + + + diff --git a/moti/app/src/main/res/layout/dialog_app_chooser.xml b/moti/app/src/main/res/layout/dialog_app_chooser.xml new file mode 100644 index 0000000..82159a7 --- /dev/null +++ b/moti/app/src/main/res/layout/dialog_app_chooser.xml @@ -0,0 +1,12 @@ + + + + + + diff --git a/moti/app/src/main/res/layout/fragment_add_memo.xml b/moti/app/src/main/res/layout/fragment_add_memo.xml index c6a572f..b3220c2 100644 --- a/moti/app/src/main/res/layout/fragment_add_memo.xml +++ b/moti/app/src/main/res/layout/fragment_add_memo.xml @@ -766,14 +766,6 @@ android:layout_weight="1" android:text="알람이 울린 뒤 할 일" /> - + + + + + + \ No newline at end of file diff --git a/moti/app/src/main/res/layout/item_app_info.xml b/moti/app/src/main/res/layout/item_app_info.xml new file mode 100644 index 0000000..6c7144d --- /dev/null +++ b/moti/app/src/main/res/layout/item_app_info.xml @@ -0,0 +1,23 @@ + + + + + + + +