본문 바로가기
개발/Android

[Kotlin] 안드로이드 설치된 어플 목록 가져오기(+Notification) with Package Manager

by jeomn 2022. 3. 10.

0. 휴대폰에 설치된 어플들 목록 가져오기

  • PackageManager 사용
  • 설치된 패키지 이름, 앱 이름, 앱 카테고리 가져오기

 

1. PackageManager

  • PackageManagerActivity.kt 생성
    • 별도로 파일 목록을 불러오는 Activity를 만들어서 확인해줄 목적
class PackageManagerActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_package_manager)

        btn_back.setOnClickListener{    //돌아가기 버튼
            finish()
        }

        val result : List<PackageInfo> = getPackageManager().getInstalledPackages(0)    //특별한 경우 제외하곤 거의 0
        val appData = arrayListOf<String>()
        if(result != null){
            for(info in result){
                val packageName = info.packageName
                val appName = info.applicationInfo.loadLabel(packageManager)
                val category = ApplicationInfo.getCategoryTitle(this, info.applicationInfo.category)
                appData.add(packageName+"   ::"+appName+" <"+category+">\n")
            }
        }

        tv_app_data.setText(appData.toString())
    }
}
  • activity_package_manager.xml

package manager 액티비티 생성

 

2. 결과

  • virtual Device  

Virtual 디바이스 확인

  • actual Device
    • 실제 휴대폰 연결하니까... 시스템 앱들밖에 안뜬다.
    • Noti 받아오는 곳에도 연결하니까 카카오어플 패키지(`com.kakao.talk`)를 못찾는 문제가 발생함
    • API 30레벨 부터는 Permission이 변경됐다!(내 휴대폰은 API 31)
    • 시스템 어플이 아닌 타 어플에 접근해야할 경우, manifest.xml에 queries로 패키지 이름을 명시해줘야 함.
    • 전체 어플에 접근해야 할 경우 Permission을 추가해줘야 함

 

3. 추가 작업(Permission, Notification)

  • 권장하지 않는 것같아 보이지만...Permission을 추가해서 확인해보기로
    • 우리 어플은 필요에 따라 모든 어플리케이션의 정보를 가져와야 하고
    • API 레벨 26~30을 대상으로 하기 때문
    •  
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.notilistenstudy">
    <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/>
    ...
</manifest>
  • Notification이 올 때 앱 정보를 불러와야 하니까, Notification 코드도 수정
class MyNotificationListener : NotificationListenerService(){
    ...
    override fun onNotificationPosted(sbn: StatusBarNotification?) {
        ...
        val notification = sbn?.notification

        val title = notification?.extras?.getString(Notification.EXTRA_TITLE)   //제목
        val bigTitle = notification?.extras?.getString(Notification.EXTRA_TITLE_BIG)    //큰 Noti 제목

        val content = notification?.extras?.getString(Notification.EXTRA_TEXT)  //내용
        val bigContent = notification?.extras?.getString(Notification.EXTRA_BIG_TEXT)   //큰 Noti 내용

        val additionalInfo = notification?.extras?.getString(Notification.EXTRA_INFO_TEXT)  //Noti 추가 정보

        //val message = notification?.extras?.getString(Notification.EXTRA_MESSAGES?:"None")    //메세지...메세지가 없을 때 출력하지 않도록 하는 코드 필요
        val category = notification?.category   //알림 카테고리
        val from = sbn?.packageName     //알림을 보낸 어플 패키지 명
        val group = notification?.group     //알림이 속한 그룹명
        val conversationTitle = notification?.extras?.getString(Notification.EXTRA_CONVERSATION_TITLE)  //알림의 대화 제목
        val subText = notification?.extras?.getString(Notification.EXTRA_SUB_TEXT)  //알림의 third party 내용(카카오톡의 경우 단체톡방 이름)
        val largeIcon = notification?.getLargeIcon()    //알림 큰 아이콘
        val smallIcon = notification?.smallIcon     //알림 작은 아이콘
        
        //로그로 확인
        Log.d("noti", "category: "+category+" | title: "+title+", content: "+content+
                " | bigTitle: "+bigTitle+", bigContent: "+bigContent+" | info: "+additionalInfo+//" | message: "+message+
                " | from: "+from+" | group: "+group+" | conversationTitle: "+conversationTitle+
                " | subText: "+subText)

        println("large: "+largeIcon)
        println("small: "+smallIcon)

        //로그로 package 정보 확인
        val pm = applicationContext.packageManager
        val info : ApplicationInfo = packageManager.getApplicationInfo(from!!, 0)
        Log.d("appInfo", "app name: "+info.loadLabel(packageManager).toString()+    //어플 이르
            " | category: "+ApplicationInfo.getCategoryTitle(this, info.category))  //어플 카테고리
        ...
    }
    ...
}

 

4. 결과

  • 실제 휴대폰에서도 전체 어플 목록 불러오기 성공

  • Noti에서 어플 정보 가져오기 성공  
어플 정보 Log
  • 어플에 설정된 카테고리로 어플 종류를 나누는 건 불가능...
    • 거의 대다수의 어플에서 카테고리를 지정하지 않음
    • 우리가 생각하는 카테고리가 아님
      • Mattermost는 협업 툴이지만...메신저 기능이니까 소셜/커뮤니케이션일 거라 생각했지만 생산성 카테고리
    • 카카오톡은 메신저, 인스타그램은 SNS로 분류되어야 하지만 둘은 같은 카테고리
카카오톡, 인스타그램 어플 manifest 설정 카테고리 비교

 

5. 참조

댓글