앱상에서 권한을 준항목들이

오레오 버전 부터는 몇몇 특정 권한들이 권한이 빠지고 다시 사용자에게 권한허용을 받아야합니다.

만약 오레오 이전 버전에 잘 동작하던게 오레오 버전에서 동작하지 않는다면

권한으로 인해 먼가 동작하지 않는지 의심해 봐야합니다.

아래는 Xamarin.Android 에서 권한을 체크하고 권한이 없는 항목에 대해서

권한 허용을 요청하는 코드입니다.

(제가 문제가 되었던 권한는 android.permission.READ_SMS,  android.permission.WRITE_EXTERNAL_STORAGE,android.permission.SEND_SMS 입니다.)

// 권한이 없어 권한허용을 물어볼 항목들
List<string> permissions = new List<string>();

// 권한이 있는지 확인할 항목들
List<string> checkPermissions = new List<string>();
checkPermissions.Add(Manifest.Permission.AccessNetworkState);
checkPermissions.Add(Manifest.Permission.Internet);
checkPermissions.Add(Manifest.Permission.WriteSms);
checkPermissions.Add(Manifest.Permission.BroadcastSms);
checkPermissions.Add(Manifest.Permission.BroadcastWapPush);
checkPermissions.Add(Manifest.Permission.ReceiveBootCompleted);
checkPermissions.Add(Manifest.Permission.ReceiveMms);
checkPermissions.Add(Manifest.Permission.ReceiveSms);
checkPermissions.Add(Manifest.Permission.SendSms);
checkPermissions.Add(Manifest.Permission.WriteExternalStorage);
checkPermissions.Add(Manifest.Permission.ReadSms);

// 권한이 있는지 확인하고 없다면 체크할 목록에 추가합니다.
foreach (var checkPermission in checkPermissions)
{
    if (ContextCompat.CheckSelfPermission(this, checkPermission) != (int)Permission.Granted)
    {
        permissions.Add(checkPermission);
    }
}

// 권한없는 항목에 대해서 추가 허용을 할지 물어보는 팝업을 띄웁니다.
ActivityCompat.RequestPermissions(this, permissions.ToArray(), 1);

위 코드를 추가하면 앱 실행시 아래처럼 허용을 묻는 팝업이 뜹니다.

 

없던 권한이 3가지 인데 알아서 권한을 묶을수 있는것 들은 묶어서 팝업이 뜨는것 같네요

다시 말하지만 기존에 AndroidManifest.xml 에 권한이 포함되있더라도

오레오버전부터는 문제가 되는 권한들이 있으므로 위 작업이 필요합니다.

 

참고

https://developer.android.com/about/versions/oreo/android-8.0-changes?hl=ko

 

심각도 코드 설명 프로젝트 파일 줄 비표시 오류(Suppression) 상태
오류  /Users/mac/Library/Caches/Xamarin/mtbs/builds/MiGong.iOS/c10cbd8fd317519d3dd23b704514d419/bin/iPhone/Release/MiGong.iOS.app: errSecInternalComponent MiGong.iOS   

위과 같은 오류가 발생

mac 이 잠자기 모드이거나 로그인 활성화가 풀린경우 발생된다.

mac 으로 들어가 로그인하면 위 오류는 사라진다.

error MT1006: Could not install the application '/Users/mac/Library/Caches/Xamarin/mtbs/builds/MiGong.iOS/c10cbd8fd317519d3dd23b704514d419/bin/iPhone/Debug/MiGong.iOS.app' on the device 'Jun의 iPhone': AMDeviceSecureInstallApplicationBundle returned: 0xe8000087 (kAMDIncorrectArchitectureError).    0 

프로젝트 속성의 iOS 빌드 탭에서 지원되는 아키텍처를 ARM7+ARM64 으로 변경하면 오류가 해결된다.

 

 

심각도 코드 설명 프로젝트 파일 줄 비표시 오류(Suppression) 상태
오류  Can't write [C:\Users\kjun\AppData\Local\Temp\tad3j0pm.d2m.jar] (Can't read [C:\Users\kjun\AppData\Local\Xamarin\Xamarin.GooglePlayServices.Base\25.0.0\embedded\classes.jar(;;;;;;!META-INF/MANIFEST.MF)] (Duplicate zip entry [classes.jar:com/google/android/gms/common/annotation/KeepName.class])) MiGong.Android D:\[01]Source\KJunDev\MiGong\MiGong\MiGong.Android\CREATEMULTIDEXMAINDEXCLASSLIST  

갑자기 위와같은 에러가 발생되었다. nuget 패키지를 이것 저것 깔다 먼가 충돌이 발생해 지웠는데

저런 에러가.;;;

구글링 하니 이런 저런 방법이 있었는데 난 아래 처럼 하니 해결되었다.

도구>Android>Android SDK Manager 클릭

 

도구 탭에서 Google Play services 를 체크 해제하여 변경 내용 적용 을 하고

다시 체크하여 변경 내용 적용을 하여 재설치를 진행한다.

이러니 에러가 해결되었다.

 

아래 다른 방법.
https://forums.xamarin.com/discussion/55601/in-a-xamarin-android-project-how-can-i-remove-warnings-duplicate-zip-entry-classes-jar

네이버 아이디 로그인 후 아래와 같은 에러가 발생되었다.

디버그 모드에서는 발생안했던 에러가 릴리즈 모드에서 발생되었는데

원인은 인코딩 문제였다

 

Authentication Error e.Exception = Encoding 51949 data not be found...

 

iOS

Android

 

아래 그림과 같이 프로젝트 속성에서 인코딩에서 CJK 를 추가해야한다.

iOS (국제화)

Android (추가 지원 인코딩)

 

오류  Error loading '/Users/mac/Library/Caches/Xamarin/mtbs/builds/MiGong.iOS/c10cbd8fd317519d3dd23b704514d419/iTunesArtwork': Unknown image format. MiGong.iOS 

배포를 위해 빌드하는데 위와 같은 에러가 났다.

info.plist 의 iTunes 아트워크 부분의 이미지가 정상적이지 않아서 에러가 발생된다.

이미지를 크기를 맞춰 다시 넣어주면 정상적으로 동작한다.

근데 저게 머하는 놈이지;;;

visual studio 에서 apple accounts 로 로그인 하는데 아래처럼 에러가 발생되었다.

authentication failure. Reason : {"authType" : "hsa2" }

이중 인증 키까지 잘 패스가 되었는데 떠서 먼가했는데

아래 사이트에서 한번더 인증 절차를 또 거쳐야한다.;;

https://appleid.apple.com

위사이트에서 한번더 로그인 한다 이중 인증을 다시;;

그러면 사이트에서 아래처럼 나오고

 

다시 로그인하면 로그인이 성공한다.

 

이제 프로비저닝 프로파일을 다운받으러....ㅠㅜ

WebView 를 사용해 보니 cache 때문에 반영된 최신 정보를 못가져오는 경우가 있다

아래 코드를 이용하면 항상 cache 를 clear 하고 가져오므로 이런 현상을 막을수 있다.

 

PCL

namespace Project.Controls
{
    public class NoCachedWebView : WebView
    {
    }
}

 

Android

[assembly: ExportRenderer(typeof(NoCachedWebView), typeof(NoCachedWebViewRenderer))]
namespace Project.Droid.Renderer
{
    class NoCachedWebViewRenderer : WebViewRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<WebView> e)
        {
            base.OnElementChanged(e);
            if (Control == null) return;

            Control.ClearCache(true);
            Control.Settings.SetAppCacheEnabled(false);
            Control.Settings.CacheMode = Android.Webkit.CacheModes.NoCache;
        }
    }
}

 

iOS

[assembly: ExportRenderer(typeof(NoCachedWebView), typeof(NoCachedWebViewRenderer))]
namespace Project.iOS.Renderer
{
    class NoCachedWebViewRenderer : WebViewRenderer
    {
        protected override void OnElementChanged(VisualElementChangedEventArgs e)
        {
            base.OnElementChanged(e);
            if (Element == null) return;

            NSUrlCache.SharedCache.RemoveAllCachedResponses();
            NSUrlCache.SharedCache.MemoryCapacity = 0;
            NSUrlCache.SharedCache.DiskCapacity = 0;
        }
    }
}

기기별로 유일한 키를 사용하고 싶을때 아래 코드를 이용하면

기기별로 유일한 키를 얻어 사용할수있다.

앱을 삭제했다 다시깔아도 동일한 키가 추출된다.

 

PCL

namespace Project
{
    public interface IDevice
    {
        string GetIdentifier();
    }
}

 

Android

[assembly: Xamarin.Forms.Dependency(typeof(AndroidDevice))]
namespace Project.Droid
{
    public class AndroidDevice : IDevice
    {
        public string GetIdentifier()
        {
            return Secure.GetString(Forms.Context.ContentResolver, Secure.AndroidId);
        }
    }
}

 

iOS

[assembly: Xamarin.Forms.Dependency(typeof(IOSDevice))]
namespace Project.iOS
{
    public class IOSDevice : IDevice
    {
        [DllImport("/System/Library/Frameworks/IOKit.framework/IOKit")]
        private static extern uint IOServiceGetMatchingService(uint masterPort, IntPtr matching);

        [DllImport("/System/Library/Frameworks/IOKit.framework/IOKit")]
        private static extern IntPtr IOServiceMatching(string s);

        [DllImport("/System/Library/Frameworks/IOKit.framework/IOKit")]
        private static extern IntPtr IORegistryEntryCreateCFProperty(uint entry, IntPtr key, IntPtr allocator, uint options);

        [DllImport("/System/Library/Frameworks/IOKit.framework/IOKit")]
        private static extern int IOObjectRelease(uint o);

        public string GetIdentifier()
        {
            string serial = string.Empty;
            uint platformExpert = IOServiceGetMatchingService(0, IOServiceMatching("IOPlatformExpertDevice"));
            if (platformExpert != 0)
            {
                NSString key = (NSString)"IOPlatformSerialNumber";
                IntPtr serialNumber = IORegistryEntryCreateCFProperty(platformExpert, key.Handle, IntPtr.Zero, 0);
                if (serialNumber != IntPtr.Zero)
                {
                    serial = NSString.FromHandle(serialNumber);
                }

                IOObjectRelease(platformExpert);
            }

            return serial;
        }
    }
}

Could not find any available provisioning profiles for iOS. WorkingWithMaps.iOS   

프로젝트 속성의 iOS 번들 서명에서 아래 처럼 자동 프로비저닝 으로 변경하면 된다.

 

+ Recent posts