앱ID 1086991
nextjs, react-native 환경이고 앱은 구글플레이를 통해 베타테스트를 배포해둔 상태입니다.
공유 메세지 클릭시 앱을 실행시키기 위한 설정 과 관련 로직은 구현이 되어있습니다.
ios에서는 카톡 공유 메세지 클릭시 앱이 실행되고 원하는 페이지로 이동까지 잘 되고 있습니다. 문제는 제목과 같이 안드로이드에서는 메세지 클릭시 앱이 설치됐음에도 구글플레이가 실행되며 앱설치 화면으로 넘어갑니다. 이미 설치되어있기 때문에 열기 버튼이 존재하고 열기 버튼을 누르면 앱이 실행됩니다…
react-native의 app.json에서 android 설정은 아래와 같습니다.
{
"expo": {
"android": {
"exported": true,
"permissions": [
"android.permission.INTERNET",
],
"intentFilters": [
{
"action": "VIEW",
"autoVerify": true,
"data": [
{
"scheme": "https",
"host": "web.development.example.im",
"pathPrefix": "/example"
},
{
"scheme": "kakao${테스트 어플리케이션의 네이티브 앱 키}”,
"host": "kakaolink"
},
{
"scheme": "kakao${실제 어플리케이션의 네이티브 앱 키}",
"host": "kakaolink"
}
],
"category": ["BROWSABLE", "DEFAULT"]
}
],
"package": "com.nation.app.example",
"queries": {
"packages": ["com.kakao.talk"]
}
},
}
}
react-native에서 android intent uri를 다음과 같이 처리하고 있습니다. 아래 로직을 통해 카카오톡을 실행시키고 있습니다.
import { Linking, Platform } from 'react-native';
import { ShouldStartLoadRequest } from 'react-native-webview/lib/WebViewTypes';
const shouldStartLoadWithRequest = (request: ShouldStartLoadRequest): boolean => {
const { url } = request;
if (url.startsWith('http') || url.startsWith('https')) {
return true;
}
// NOTE: 안드가 웹뷰에서 외부앱을 실행시킬려면 intent URI를 사용해야 함. 카카오 JS SDK는 카톡 실행을 위한 intent URI를 생성해 호출함. 이 intent를 파싱해서 해당 activity를 실행시켜야 한다
if (Platform.OS === 'android' && url.startsWith('intent')) {
const kakaoLinkUrl = url.replace('intent://', 'kakaolink://');
console.log('kakaoLinkUrl', kakaoLinkUrl);
Linking.canOpenURL(kakaoLinkUrl)
.then((canOpen) => {
if (canOpen) {
return Linking.openURL(kakaoLinkUrl);
}
throw new Error('카카오톡을 열 수 없습니다.');
})
.then(() => {
// console.log('카카오톡이 성공적으로 열렸습니다.');
})
.catch((error) => {
alert(`error (${error.message})`);
});
return false;
}
return false;
};
export default shouldStartLoadWithRequest;
그리고 구글 플레이 콘솔에서 SHA-1 인증서 지문을 가져와 Base64로 인코딩하여 플랫폼-안드로이드-키 해시에도 등록해두었습니다!
원인이 무엇인지 알 수 없어 답답하네요…
안녕하세요.
빌드된 후의 AndroidManifest.xml 파일 내용 공유 부탁드립니다.
여기 있습니다!
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.GALLERY"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<queries>
<intent>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="https"/>
</intent>
</queries>
<application android:name=".MainApplication" android:label="@string/app_name" android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round" android:allowBackup="true" android:theme="@style/AppTheme" android:requestLegacyExternalStorage="true">
<meta-data android:name="expo.modules.updates.ENABLED" android:value="false"/>
<meta-data android:name="expo.modules.updates.EXPO_UPDATES_CHECK_ON_LAUNCH" android:value="ALWAYS"/>
<meta-data android:name="expo.modules.updates.EXPO_UPDATES_LAUNCH_WAIT_MS" android:value="0"/>
<activity android:name=".MainActivity" android:configChanges="keyboard|keyboardHidden|orientation|screenSize|screenLayout|uiMode" android:launchMode="singleTask" android:windowSoftInputMode="adjustResize" android:theme="@style/Theme.App.SplashScreen" android:exported="true" android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="example"/>
<data android:scheme="com.nation.app.example"/>
</intent-filter>
<intent-filter android:autoVerify="true" data-generated="true">
<action android:name="android.intent.action.VIEW"/>
<data android:scheme="https" android:host="web.development.example.im" android:pathPrefix="/share"/>
<data android:scheme="kakao${native app key}" android:host="kakaolink"/>
<category android:name="android.intent.category.BROWSABLE"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND"/>
<data android:mimeType="text/*"/>
<data android:mimeType="image/*"/>
<data android:mimeType="video/*"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND_MULTIPLE"/>
<data android:mimeType="text/*"/>
<data android:mimeType="image/*"/>
<data android:mimeType="video/*"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" android:exported="false"/>
</application>
</manifest>
androidExecutionParams를 사용하셨을까요?
사용하지 않으셨다면 파라미터 전달 부탁드립니다.
androidExecutionParams는 따로 사용하지 않고 메세지 템플릿에서 파라미터를 템플릿 args로 전달되도록 해놨습니다!
아래 코드를 보시면 웹에서 공유 기능을 실행할 때 템플릿 args에 parameter가 전달되고 있습니다.
import { useCallback, useEffect } from 'react';
import type { KakaoShareResult } from './types';
declare global {
interface Window {
Kakao: any;
}
}
export function useKakaoShare(): KakaoShareResult {
useEffect(() => {
if (!window.Kakao.isInitialized()) {
window.Kakao.init(process.env.NEXT_PUBLIC_KAKAO_CLIENT_ID);
}
}, []);
const handleKakaoShare = useCallback(
async (imageUrl: string, documentID: string) => {
const { Kakao } = window;
const TEMPLATE_ID =
process.env.NODE_ENV === 'production' ? 110073 : 110074;
Kakao.Share.sendScrap({
requestUrl: 'https://web.development.example.im',
templateId: TEMPLATE_ID,
templateArgs: {
THUMB: imageUrl,
PATH: `share/${documentID}`,
PARAMETER: `documentID=${documentID}`,
},
});
},
[window],
);
return { handleKakaoShare };
}
++ 추가로 prebuild 이후 AndroidManifest.xml 파일을 보고 <package android:name="com.kakao.talk" />
가 빠진 것을 알게됐습니다. 아래와 같이 직접 입력해주고 aab 파일을 빌드해서 해당 파일로 구글 플레이에서 배포해도 똑같은 문제가 발생하고 있습니다!
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.GALLERY"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<queries>
<package android:name="com.kakao.talk"/>
<intent>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="https"/>
</intent>
</queries>
<application android:name=".MainApplication" android:label="@string/app_name" android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round" android:allowBackup="true" android:theme="@style/AppTheme" android:requestLegacyExternalStorage="true">
<meta-data android:name="expo.modules.updates.ENABLED" android:value="false"/>
<meta-data android:name="expo.modules.updates.EXPO_UPDATES_CHECK_ON_LAUNCH" android:value="ALWAYS"/>
<meta-data android:name="expo.modules.updates.EXPO_UPDATES_LAUNCH_WAIT_MS" android:value="0"/>
<activity android:name=".MainActivity" android:configChanges="keyboard|keyboardHidden|orientation|screenSize|screenLayout|uiMode" android:launchMode="singleTask" android:windowSoftInputMode="adjustResize" android:theme="@style/Theme.App.SplashScreen" android:exported="true" android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="example"/>
<data android:scheme="com.nation.app.example"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND"/>
<data android:mimeType="text/*"/>
<data android:mimeType="image/*"/>
<data android:mimeType="video/*"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND_MULTIPLE"/>
<data android:mimeType="text/*"/>
<data android:mimeType="image/*"/>
<data android:mimeType="video/*"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND"/>
<data android:mimeType="text/*"/>
<data android:mimeType="image/*"/>
<data android:mimeType="video/*"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND_MULTIPLE"/>
<data android:mimeType="text/*"/>
<data android:mimeType="image/*"/>
<data android:mimeType="video/*"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
<intent-filter android:autoVerify="true" data-generated="true">
<action android:name="android.intent.action.VIEW"/>
<data android:scheme="https" android:host="web.development.example.im" android:pathPrefix="/share"/>
<data android:host="kakaolink" android:scheme="kakao${테스트 어플리케이션의 native app key}"/>
<data android:host="kakaolink" android:scheme="kakao${실제 배포 어플리케이션의 native app key}"/>
<category android:name="android.intent.category.BROWSABLE"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND"/>
<data android:mimeType="text/*"/>
<data android:mimeType="image/*"/>
<data android:mimeType="video/*"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND_MULTIPLE"/>
<data android:mimeType="text/*"/>
<data android:mimeType="image/*"/>
<data android:mimeType="video/*"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" android:exported="false"/>
</application>
</manifest>
tim.l
8월 16, 2024, 12:05오전
8
안녕하세요.
하이브리드앱에서 띄우는 공유하기 재현해볼 수 있는 페이지 URL 알려주시면 어떤 상황인지 확인해보겠습니다.