본문 바로가기

카테고리 없음

리액트 네이티브 - 유저가 특정 앱을 설치했는지 확인하는 법

728x90

앱을 만들다 보니 다른 사람이 어떤 특정한 앱을 설치하고 있는지 확인해야 할 일이 생겼다.

그래서 일단은 남이 만들어 놓은 라이브러리를 사용하려 했는데 0.60 이상을 지원하지 않는 것 같아서 결국은 코드를 직접 만들어서 쓰게 되었다. 

https://reactnative.dev/docs/native-modules-intro

 

Native Modules Intro · React Native

Sometimes a React Native app needs to access a native platform API that is not available by default in JavaScript, for example the native APIs to access Apple or Google Pay. Maybe you want to reuse some existing Objective-C, Swift, Java or C++ libraries wi

reactnative.dev

iOS 의 경우에는 해당 앱이 제공하는 custom URL Scheme 이 있어서 이를 열 수 있는지 확인하는 로직을 이용하여 Native module 을 구현할 필요 없이 쉽게 구현하였다. (react-native 의 Linking 라이브러리 사용)

// Instagram 이 유저의 기기에 설치되어있는지 확인한다.
export const instagramCheckIOS = async () => {
  try {
    const res = await checkURLScheme('instagram', 'app');
    return res;
  } catch (error) {
    console.warn('instagramCheckIOS FAILED', error);
    return false;
  }
};

const checkURLScheme = (proto, query) => {
  return new Promise((resolve, reject) => {
    Linking.canOpenURL(proto + '://' + query || '')
      .then((isInstalled) => {
        resolve(isInstalled);
      })
      .catch((err) => {
        reject(err);
      });
  });
};

 

Android 의 경우 간단한 java class 를 하나 만들어서 Native Modules 를 이용하여 처리하였는데, 여기에 그 네이티브 모듈을 연결하는 것을 다 기술하는 것은 조금 번거로울 듯 싶어서 해당 코드를 짤 때 주의해야했던 것들만 적고 마친다. 네이티브 모듈을 만들고 이를 리액트 네이티브에 넣는 것은 해볼만한 가치가 있으니 피할 수 없으면 즐기도록 하자.

https://reactnative.dev/docs/native-modules-android

 

Android Native Modules · React Native

Welcome to Native Modules for Android. Please start by reading the Native Modules Intro for an intro to what native modules are.

reactnative.dev

다음은 해당 패키지가 깔려있는지 확인하는 java 코드이다.

package 우리회사.패키지.네임;

import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.Callback;
import java.util.Map;
import java.util.HashMap;
import android.util.Log;

import android.content.pm.PackageManager;
import android.content.Context;

public class AppInstallCheckModule extends ReactContextBaseJavaModule {

    Context ctx;

    AppInstallCheckModule(ReactApplicationContext reactContext) {
        super(reactContext);
        this.ctx = reactContext.getApplicationContext();
    }

    @Override
    public String getName() {
        return "AppInstallCheckModule";
    }

    @ReactMethod
    public void isPackageInstalled(String packageName, Callback cb) {
        PackageManager pm = this.ctx.getPackageManager();

        try {
            pm.getPackageInfo(packageName, PackageManager.GET_ACTIVITIES);
            cb.invoke(true);
        } catch (Exception e) {
            cb.invoke(false);
        }
    }
}

Android 의 PackageManaer 모듈을 이용하면 간단하게 패키지 이름의 앱이 깔려있는지 확인할 수 있다. (예를들어 인스타그램의 패키지 이름인 'com.instagram.android' 같은 스트링을 input 으로 넣으면 확인 가능.)

 

테스트할 때는 정상 동작하는데 막상 실 기기에서는 자꾸 앱 설치가 안되어있다고 하여 당황하였는데 살펴보니 안드로이드 API 버젼 30 이후부터는 AndroidManifest 에 현재 찾고자 하는 패키지의 이름을 따로 명시하지 않으면 그 앱이 깔려있는지 알려주지 않는 보안 정책이 생긴 것 같다. 그래서 Android Manifest 에 필요한 부분을 더 추가해주었다.

 

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="우리회사.패키지.네임">
  ...
  <queries>
    <package android:name="com.kakao.talk" />
    <package android:name="com.instagram.android" />
    <package android:name="com.google.android.youtube" />
  </queries>
  ...

 

 

참고)

https://developer.android.com/training/basics/intents/package-visibility

 

패키지 공개 상태 관리  |  Android 개발자  |  Android Developers

패키지 공개 상태 관리 앱을 만들 때는 기기에 설치된 다른 앱, 즉 내 앱에서 액세스하려는 앱을 표시하는 패키지 집합을 고려하는 것이 중요합니다. 앱이 Android 11(API 수준 30) 이상을 타겟팅한다

developer.android.com