[Unity] SNS 공유하기 / Android N 대응 방법
SNS 공유하기 기능은 게임 앱 개발 시 많이 사용하는 기능중에 하나죠.
하지만 예전에 사용하던 코드가 Android N 부터는 정상작동을 하지 않고 에러가 나오더군요.
그래서 공유하기 기능을 fileprovider 방식으로 변경해야 했습니다.
아래는 제가 사용하는 fileprovider 방식으로 변경한 코드 입니다.
private void ShareAndroidImageWithText(string path, string title, string text, Texture2D _textureShareImage)
{
#if UNITY_ANDROID
AndroidJavaClass intentClass = new AndroidJavaClass("android.content.Intent");
AndroidJavaObject intentObject = new AndroidJavaObject("android.content.Intent");
{
intentObject.Call<AndroidJavaObject>("setAction", intentClass.GetStatic<string>("ACTION_SEND"));
intentObject.Call<AndroidJavaObject>("setType", "image/*");
intentObject.Call<AndroidJavaObject>("putExtra", intentClass.GetStatic<string>("EXTRA_SUBJECT"), title);
intentObject.Call<AndroidJavaObject>("putExtra", intentClass.GetStatic<string>("EXTRA_TITLE"), title);
intentObject.Call<AndroidJavaObject>("putExtra", intentClass.GetStatic<string>("EXTRA_TEXT"), text);
AndroidJavaClass unity = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject currentActivity = unity.GetStatic<AndroidJavaObject>("currentActivity");
AndroidJavaObject unityContext = currentActivity.Call<AndroidJavaObject>("getApplicationContext");
AndroidJavaClass uriClass = new AndroidJavaClass("android.support.v4.content.FileProvider");
AndroidJavaClass fileClass = new AndroidJavaClass("java.io.File");
string packageName = unityContext.Call<string>("getPackageName");
string authority = packageName + ".fileprovider";
AndroidJavaObject fileObject = new AndroidJavaObject("java.io.File", path);
AndroidJavaObject uriObject = uriClass.CallStatic<AndroidJavaObject>("getUriForFile", unityContext, authority, fileObject);
bool fileExist = fileObject.Call<bool>("exists");
Debug.Log("[GeneralShare] File exist : " + fileExist);
Debug.Log("[GeneralShare] file path : " + uriObject.Call<string>("getPath"));
// Attach image to intent
if (fileExist)
intentObject.Call<AndroidJavaObject>("putExtra", intentClass.GetStatic<string>("EXTRA_STREAM"), uriObject);
AndroidJavaObject jChooser = intentClass.CallStatic<AndroidJavaObject>("createChooser", intentObject, KW.Get("SYS_SNS_SHARE"));
currentActivity.Call("startActivity", jChooser);
}
#endif
}
가운데 부분에 기존에 사용 하던 이런 형태의 코드에서
AndroidJavaClass uriClass = new AndroidJavaClass("android.net.Uri");
AndroidJavaClass fileClass = new AndroidJavaClass("java.io.File");
AndroidJavaObject fileObject = new AndroidJavaObject("java.io.File", path);
AndroidJavaObject uriObject = uriClass.CallStatic("fromFile", fileObject);
이런식으로 변경합니다.
AndroidJavaClass uriClass = new AndroidJavaClass("android.support.v4.content.FileProvider");
AndroidJavaClass fileClass = new AndroidJavaClass("java.io.File");
string packageName = unityContext.Call("getPackageName");
string authority = packageName + ".fileprovider";
AndroidJavaObject fileObject = new AndroidJavaObject("java.io.File", path);
AndroidJavaObject uriObject = uriClass.CallStatic("getUriForFile", unityContext, authority, fileObject);
코드를 수정했으면
AndroidManifest.xml 파일에 fileprovider 를 사용할 수 있는 내용을 추가해야 합니다.
<application>
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="[패키지 네임].fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" />
</provider>
</application>
내용 중 패키지 네임은 자신이 만든 프로젝트의 패키지 네임을 입력하시면 됩니다.
패키지 네임은 com.xxxxx.xxxxx 이런식으로 되어 있죠.
위 내용을 AndroidManifest.xml 추가 했으면 추가한 해당 AndroidManifest.xml 파일이 있는 곳에
res 폴더를 만든 후(이미 있으면 그냥 사용해도 됩니다.) res 폴더 안에 xml 폴더를 만들고 filepaths.xml 파일을
만들고 아래의 코드를 입력합니다.
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path path="Android/data/com.company.product" name="files_root" />
<external-path path="." name="external_storage_root" />
</paths>
위 경로 예시는 저는AndroidManifest.xml 에 들어가는 fileprovider 내용을
구글 애드몹을 사용하기때문에 애드몹 플러그인에 같이 붙여 놓은 상태입니다.
꼭 이렇게 붙여놓을 필요는 없고 따로 AndroidManifest.xml 만들거나 다른 플러그인에 함께 사용해도 됩니다.
구현 중 또는 후에
android.content.pm.PackageItemInfo.loadXmlMetaData(android.content.pm.PackageManager, java.lang.String)' on a null object reference
이런 오류나
NullPointerException when trying to get URI with FileProvider(Android)
이런식의 오류가 날 경우에는 AndroidManifest.xml 파일의 패키지 명이 정확하게 입력되어 있는지를 확인해보고
xml 파일이 정확한 경로 위치에 있는지 확인합니다.
res - xml - filepaths.xml
'Unity' 카테고리의 다른 글
[Unity] 유니티 애드몹 전면 광고 적용하기 (AdMob Interstitial Ads) v3.17 (0) | 2019.06.02 |
---|---|
[Unity] 애드몹 배너 광고 적용하기 (AdMob Banner) v3.17 (6) | 2019.05.30 |
[Unity] 유니티 2019 버전 업그레이드 후 오류 대응 / IL2CPP 빌드 (4) | 2019.05.27 |
유니티에서 안드로이드폰 디버깅 (로그캣) (0) | 2019.05.21 |
[애드몹] 'GoogleMobileAds.Api.MobileAds' threw an exception 해결 방법 (0) | 2019.05.21 |