Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feat/permission]: special permission 허용 요청 기능 구현 #26

Merged
merged 16 commits into from
Jan 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

23 changes: 21 additions & 2 deletions feature/onboarding/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,10 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">

<uses-permission
android:name="android.permission.PACKAGE_USAGE_STATS"
tools:ignore="ProtectedPermissions" />

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

<application>
<activity
android:name=".OnBoardingActivity"
android:exported="false" />
</application>

<service
android:name=".OnBoardingAccessibilityService"
android:exported="true"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>

<meta-data
android:name="android.accessibilityservice"
android:resource="@xml/accessibility_service_config" />
</service>
</application>
</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.hmh.hamyeonham.feature.onboarding

import android.accessibilityservice.AccessibilityService
import android.util.Log
import android.view.accessibility.AccessibilityEvent
import com.hmh.hamyeonham.common.context.toast

class OnBoardingAccessibilityService : AccessibilityService() {
override fun onAccessibilityEvent(event: AccessibilityEvent) {
if (event.eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
val packageName = event.packageName ?: return
Log.d("AccessibilityService", "현재 실행 중인 앱 패키지: $packageName")
}
}

override fun onInterrupt() {

}
}
Original file line number Diff line number Diff line change
@@ -1,21 +1,106 @@
package com.hmh.hamyeonham.feature.onboarding

import android.app.usage.UsageStatsManager
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.provider.Settings
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import com.hmh.hamyeonham.common.context.toast
import com.hmh.hamyeonham.feature.onboarding.databinding.ActivityOnBoardingBinding

class OnBoardingActivity : AppCompatActivity() {

private lateinit var binding: ActivityOnBoardingBinding

private val accessibilitySettingsLauncher: ActivityResultLauncher<Intent> =
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

별견 아니지만 onCreate같은 퍼블릭 메소드가 먼저 나오는 게 좋을 것 같아요!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

변수라서 해당 부분이 컨벤션상 먼저 있는게 맞습니당~!!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아 그렇군요 감사합니다!

registerForActivityResult(
ActivityResultContracts.StartActivityForResult(),
) {
if (isAccessibilityServiceEnabled()) {
toast("접근성 서비스가 활성화되었습니다.")
} else {
toast("접근성 서비스가 활성화되지 않았습니다.")
}
}

override fun onCreate(savedInstanceState: Bundle?) {
binding = ActivityOnBoardingBinding.inflate(layoutInflater)
super.onCreate(savedInstanceState)
setContentView(binding.root)
clickRequireAccessibilityBtn()
}

binding.run {
numberPicker.npCustomHours.minValue = 1
numberPicker.npCustomHours.maxValue = 6
numberPicker.npCustomMinutes.minValue = 1
numberPicker.npCustomMinutes.maxValue = 59
private fun clickRequireAccessibilityBtn() {
binding.btnAccessibility.setOnClickListener {
openAccessibilitySettingsIfNeeded()
}
binding.btnUsage.setOnClickListener {
requestUsageAccessPermission()
}
binding.btnDrawOnOthers.setOnClickListener {
if (!hasOverlayPermission()) {
requestOverlayPermission()
} else {
toast("다른 앱 위에 그리기 권한이 이미 허용되어 있습니다.")
}
}
}

private fun requestUsageAccessPermission() {
if (!hasUsageStatsPermission()) {
try {
val packageUri = Uri.parse("package:$packageName")
val intent = Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS, packageUri)
startActivity(intent)
} catch (e: Exception) {
val intent = Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS)
startActivity(intent)
}
} else {
toast("사용 정보 접근 권한이 이미 허용되어 있습니다.")
}
}

private fun requestOverlayPermission() {
val packageUri = Uri.parse("package:$packageName")
val intent = Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, packageUri)
startActivity(intent)
}

private fun hasOverlayPermission(): Boolean {
return Settings.canDrawOverlays(this)
}

private fun isAccessibilityServiceEnabled(): Boolean {
val service = packageName + "/" + OnBoardingAccessibilityService::class.java.canonicalName
val enabledServicesSetting = Settings.Secure.getString(
contentResolver,
Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
)
return enabledServicesSetting?.contains(service) == true
}

private fun openAccessibilitySettingsIfNeeded() {
if (!isAccessibilityServiceEnabled()) {
val intent = Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS)
accessibilitySettingsLauncher.launch(intent)
} else {
toast("접근성 권한이 이미 허용되어 있습니다.")
}
}

private fun hasUsageStatsPermission(): Boolean {
val usageStatsManager = getSystemService(Context.USAGE_STATS_SERVICE) as UsageStatsManager
val time = System.currentTimeMillis()
val stats = usageStatsManager.queryUsageStats(
UsageStatsManager.INTERVAL_DAILY,
time - 1000 * 60,
time,
)
return stats != null && stats.isNotEmpty()
}
}
34 changes: 28 additions & 6 deletions feature/onboarding/src/main/res/layout/activity_on_boarding.xml
Original file line number Diff line number Diff line change
@@ -1,16 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".OnBoardingActivity">

<include
android:id="@+id/numberPicker"
layout="@layout/dialog_numberpicker_custom"
app:layout_constraintBottom_toBottomOf="parent"
<Button
android:id="@+id/btn_accessibility"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="접근성 허용하러 가기"
app:layout_constraintBottom_toTopOf="@+id/btn_usage"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
android:layout_marginBottom="30dp"/>

<Button
android:id="@+id/btn_usage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="사용 정보접근 허용하러 가기"
app:layout_constraintBottom_toTopOf="@+id/btn_draw_on_others"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginBottom="30dp"/>

<Button
android:id="@+id/btn_draw_on_others"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="30dp"
android:text="다른 앱 위에 그리기허용하러 가기"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
android:id="@+id/np_custom_hours"
android:layout_width="50dp"
android:layout_height="100dp"
android:theme="@style/AppTheme.NumberPicker"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
Expand Down
4 changes: 3 additions & 1 deletion feature/onboarding/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
<resources></resources>
<resources>
<string name="accessibility_service_description">화면 동작 감지</string>
</resources>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
android:accessibilityEventTypes="typeWindowStateChanged"
android:accessibilityFeedbackType="feedbackSpoken"
android:accessibilityFlags="flagDefault"
android:canRetrieveWindowContent="true"
android:notificationTimeout="100" />

This file was deleted.