Yine ve yeniden merhabalar,
Bu derste, Android 6.0 ile gelen çalışma zamanı izinleri Unity‘de nasıl kontrol edebileceğinizi göstereceğim. Böylelikle oyun esnasında belli bir izne sahip olup olmadığınızı kontrol edebilecek ve gerekirse izni kullanıcıdan talep edebileceksiniz.
Hazırsanız başlayalım…
Kurulum
Şu adresteki unitypackage‘ı Assets-Import Package yoluyla projenize import edin: https://github.com/yasirkula/UnityAndroidRuntimePermissions/releases
Alternatif olarak, asset’i Asset Store’dan da import edebilirsiniz: https://assetstore.unity.com/packages/tools/integration/android-runtime-permissions-117803
Burada opsiyonel bir adım daha var. Unity ile yaptığınız Android oyun ilk açılırken, uygulamanın istediği tüm izinleri topluca talep eden bir diyalog gözükür:

Eğer kullandığınız plugin’ler çalışma zamanı izinleri kendi başlarına destekliyorlarsa veya siz ne zaman hangi izni isteyeceğinizi biliyorsanız, bu diyaloğu gizleyerek oyunun başında kullanıcıların kafasının karışmasını önleyebilirsiniz. Bu şekilde, gerekli izinleri sadece gerektiği zaman isteyerek daha kullanıcı dostu bir deneyim oluşturabilirsiniz.
Bunun için, projenizin Assets/Plugins/Android klasöründe bir AndroidManifest.xml dosyası bulunması gerekiyor. Henüz bir AndroidManifest’iniz yoksa C:\Program Files\Unity\Editor\Data\PlaybackEngines\AndroidPlayer konumundaki Unity’nin varsayılan AndroidManifest.xml dosyasını kopyalayıp (dosya Apk gibi bir alt klasörde de olabilir) projenizin Assets/Plugins/Android klasörüne yapıştırın (Plugins veya Android klasörleri yoksa elle oluşturun).
Ardından AndroidManifest’te <application>...</application>
etiketleri arasına şunu yapıştırın:
<meta-data android:name="unityplayer.SkipPermissionsDialog" android:value="true" />

Artık izin diyaloğu oyunun başında gözükmeyecektir.
Kullanım
Permission AndroidRuntimePermissions.CheckPermission( string permission )
permission iznine sahip olup olmadığımızı kontrol eder. Kontrol edilebilecek izin listesine şuradan erişebilirsiniz: https://developer.android.com/guide/topics/permissions/overview#permission-groups
Bu izinlerin başına android.permission da eklemeyi unutmayın. Yani örneğin WRITE_EXTERNAL_STORAGE iznini kontrol etmek istiyorsanız, permission’a android.permission.WRITE_EXTERNAL_STORAGE girin. Ayrıca bu izinleri <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
şeklinde AndroidManifest’e de eklemeyi unutmayın; çünkü AndroidManifest’te tanımlı olmayan izinlere erişemezsiniz.
Bu fonksiyon bir AndroidRuntimePermissions.Permission enum‘u döndürür. Eğer ilgili iznimiz varsa bu enum’un değeri Permission.Granted olurken eğer henüz iznimiz yoksa Permission.ShouldAsk olur. Eğer kullanıcı karşısına gelen izin ekranını “Bir daha sorma” seçili bir şekilde reddederse veya kullanıcının cihazında aktif olan bir ebeveyn kontrol sistemi bu iznin verilmesini engelliyorsa, Permission.Denied döndürülür. Bu durumda kullanıcı izni cihazın ayarlar menüsünden elle vermek zorundadır. Böyle bir durumla baş başa kalırsanız, kullanıcıya ayarlar menüsünden izin vermesini söyleyen bir uyarı penceresi gösterebilir ve(ya) OpenSettings fonksiyonu ile ayarlar menüsünü otomatik olarak açabilirsiniz.
Permission[] AndroidRuntimePermissions.CheckPermissions( params string[] permissions )
Birden çok izni aynı anda kontrol eder. Döndürülen array‘de her bir izin için bir tane Permission değeri tutulur.
Permission AndroidRuntimePermissions.RequestPermission( string permission )
Girilen izni kullanıcıdan talep eder ve sonucu döndürür.
Permission[] AndroidRuntimePermissions.RequestPermissions( params string[] permissions )
Birden çok izni aynı anda kullanıcıdan talep eder. Döndürülen array‘de her bir izin için bir tane Permission değeri tutulur.
void AndroidRuntimePermissions.OpenSettings()
Uygulamanın ayarlar menüsünü otomatik olarak açar. Gerekli olduğu durumda buradan kullanıcı bir izni elle verebilir.
Örnek Kod
Aşağıdaki kod, ekranın sağ alt köşesine dokunduğunuzda kullanıcıdan WRITE_EXTERNAL_PERMISSION iznini talep eder (bu izni önce AndroidManifest’te tanımlamayı unutmayın):
void Update()
{
if( Input.GetMouseButtonDown( 0 ) && Input.mousePosition.x > Screen.width * 0.8f && Input.mousePosition.y < Screen.height * 0.2f )
{
AndroidRuntimePermissions.Permission izin = AndroidRuntimePermissions.RequestPermission( "android.permission.WRITE_EXTERNAL_STORAGE" );
if( izin == AndroidRuntimePermissions.Permission.Granted )
Debug.Log( "WRITE_EXTERNAL_STORAGE iznimiz var!" );
else
Debug.Log( "İzin durumu: " + izin );
// WRITE_EXTERNAL_STORAGE ve CAMERA izinlerini aynı anda talep etmek
//AndroidRuntimePermissions.Permission[] izinler = AndroidRuntimePermissions.RequestPermissions( "android.permission.WRITE_EXTERNAL_STORAGE", "android.permission.CAMERA" );
//if( izinler[0] == AndroidRuntimePermissions.Permission.Granted && izinler[1] == AndroidRuntimePermissions.Permission.Granted )
// Debug.Log( "Tüm izinlere sahibiz!" );
//else
// Debug.Log( "Bazı izinlere sahip değiliz..." );
}
}
Sonraki dersimizde görüşmek üzere, hoşça kalın!
Hocam merhaba. Bende Unity’de Plugins klasörü bomboş, hatta şunu fark ettim yeni proje açınca bu klasör hiç oluşmuyor bile. Ama SDK ve NDK’lar kurulu eminim, daha yeni kurdum ve APK çıktısı alabiliyorum sıkıntısız şekilde. İnternette hiçbir şekilde cevap bulamadım, benden başka bu sorunu yaşayan yok gibi. Şu belirtilen dosya yolu ve civarında da “AndroidManifest.xml” dosyası yok. …Unity\Hub\Editor\2019.4.13f1\Editor\Data\PlaybackEngines\AndroidPlayer
Ne yapabilirim?
SORUN ÇÖZÜLDÜ: Hocam sorunu uğraşa uğraşa çözdüm. Başkaları da belki faydalanır diye yazıyorum.
Unity’de aslında XML’leri merge eden bir sistem varmış. Yani aynı isimde birden çok XML olabiliyor, build alırken Unity bunları tek bir çatı altında birleştiriyor (ortak olan satırları da birleştiriyor).
– Önce normal olarak APK çıktısı aldım.
– Çıktı aldıktan sonra proje dosyalarında “Temp” diye bir klasör oluşacak. Temp klasöründe “AndroidManifest.xml” diye arama yaptırdım.
– Çıkan sonuçlardan en kapsamlı olanı ve içerisinde proje isminin ve yaptığım proje ayarlarının olduğu (bazılarında isim ve ayarlar default) dosyayı kopyalayıp içerisine olması gerektiği gibi gereken yerde izinlerimi yazdım ve bu kopyaladığım dosyayı Unity’de proje dosyalarına attım. Başka hiçbir şeye ellemeden yine APK çıktısı aldım ve çalıştı.
Bir şey daha sorabilir miyim? Gördüğüm kadarıyla izni sorma anında uygulama duruyor yani asenkron değil bu işlem. Peki bunun asenkron olarak yapılan hali var mı, yani asenksron olarak permission request edebiliyor muyuz?
Elinize sağlık. AndroidManifest.xml eğer tam olarak Assets/Plugins/AndroidManifest.xml konumunda değilse, çalışması açıkçası beni şaşırttı =P Asenkron izin isteme için, AndroidRuntimePermissions dosyasındaki RequestPermissionAsync fonksiyonunu public yapıp kullanabilirsiniz. Bu fonksiyon, bir callback fonksiyonu parameter olarak alıyor.
Hocam ben söylemeyi unuttum kendi oluşturduğum yeni AndroidManifest.xml dosyasını projede yeni kendi oluşturduğum Plugins>Android klasörüne attım. Yani direkt Assets’in içine bırakmadım.
Async konusunda verdiğiniz cevap için de teşekkür ederim.
merhaba kolay gelsin google play store bir oyun atmaya çalışıyorum androidmanifest de izinlerin arasında android.permission.RECORD_AUDIO olduğundan yayınlanmıyor bu izni siliyorum kaydediyorum ama yinede hala bu izin var olduğu söyleniyor silmeme rağmen sildiğim izin bir süre sonra tekrar oraya otomatik ekleniyor silemiyorum manifest dosyasının yanında küçük bir kilit simgesi gibi bir resim var acaba dosyamı kilitli ondan mı düzenliyemiyorum yardımcı olursanız çok sevinirim
AndroidManifest’iniz Window-Package Manager ile kurulan bir asset’in parçası olabilir. AndroidManifest’in hangi package’ın içinde yer aldığını bulup onu Window-Package Manager’dan silmeyi (Remove) deneyebilirsiniz. Son çare olarak da, Build Settings’teki Export Project seçeneğini seçip build aldıktan sonra, oluşan klasörü Android Studio’da açıp AndroidManifest’in içeriğini oradan düzenleyebilir, ardından Android Studio’dan build alarak APK’yı oluşturabilirsiniz.
hangi paket isminde olabilir acaba bir tahmininiz var mı ona göre bakayım
https://i.hizliresim.com/8lxavB.jpg
İzni hangi AndroidManifest.xml dosyasından elle siliyorsunuz?
android.permission.RECORD_AUDIO
https://i.hizliresim.com/xznt9s.jpg buradan bu izni siliyorum kaydediyorum oyunu build ediyorum ama tekrar bu yazı buraya otomatik ekleniyor
son çare olarak belirttiğiniz 2.yöntem android studio sayesinde hallettim bu fikri paylaştığınız için teşekkür ederim
Elinize sağlık. Sıkıntılı AndroidManifest’in hangi package’a ait olduğu, içinde bulunduğu klasörlerin birisinin isminden belli olur.
Hocam elinize sağlık. Opensettingste uygulama ayarlarının değilde telefonun ayarlarını nasıl açabiliriz.(Ağlar,konum gibi?) Birde iOS için kaynak linki paylaşabilir misiniz.
Bunun için plugin yazmanız lazım gibi duruyor: https://stackoverflow.com/a/19517448/2373034
Plugin dersim için: https://yasirkula.com/2015/10/14/unity-androide-eclipse-adt-ile-basit-bir-plugin-yazmak/
iOS’ta her izin farklı bir şekilde isteniyor, o yüzden aynı işi yapan bir iOS plugin’i bulabileceğinizi sanmıyorum. Buna ihtiyaç duyacağınızı da düşünmüyorum çünkü bir plugin iOS’un belli bir iznini gerektiriyorsa, büyük olasılıkla zaten bu izni otomatik olarak istiyordur.
merhabalar, udemy üzerinden böyle bir ders aldım. C# dili için yeterli bir kaynakmıdır sizce?
kurs linki: https://www.udemy.com/mobiloyunyapimi/
Resim: https://i.hizliresim.com/RgnVOa.png
Şimdiden hayırlı olsun. Ben dersi kendim almadığım için bir şey diyemiyorum ama muhakkak size faydası olacaktır. Takıldığınız nokta olursa da dersi veren hocaya Udemy üzerinden soru sormanız mümkün diye biliyorum.
Merhabalar hocam benim sorunum oyunumu google play store yükledim fakat telefonumda test ettiğimde açılmıyor çöküyor bunun izinlerle alakası var mıdır acaba? çünkü uygulama ayarlarına baktığımda herhangi bir izin istemiyor yazmasına rağmen 3 adet izin gerektiriyor tam çözemedim kilitlenmesinin sebebini bir yardımcı olur musunuz teşekkürler şimdiden
O 3 izin ufak izinlerse ayarlarda bahsi geçmeyebilir. Uygulamanızda Admob reklamları var mı? Varsa AndroidManifest’e uygulama kimliğinizi eklediniz mi? Ayrıca logcat ile uygulamanızı debug edip bir hata alıyor musunuz kontrol edebilirsiniz: https://yasirkula.com/2015/10/13/unity-android-oyunlarinizi-debug-etmek/
Evet dediğiniz gibi ufak izinlerdi. Teşekkür ederim deniyeceğim dediklerinizi. iyi günler
hocam uygulamanın açılışında izinlerin istenmesini nasıl yapabiliriz? Ayrıca play store’da uygulamanın istediği izinleri nasıl listeleyebiliriz?
Siz bir değişiklik yapmazsanız, uygulama açıldığında izinler otomatik olarak istenir. Play Store’daki izinler de AndroidManifest.xml dosyasından otomatik olarak çekilip listelenir, yani elle bir ayar yapacaksanız AndroidManifest’te yapmanız lazım.
Benim projede GPGS kendisi android manifest oluşturmuş fakat dediğiniz konumda değil. Ben sizin dediğiniz konuma unity’nin android manifestini kopyaladım fakat build alırken merge hatası verdi. Birde android manifest içine bunu ekledikten sonra örnek kod gibi bir adımı uygulamazsak uygulama kendisi otomatik oyun başında mı izini çağırıyor ?
Manifest değişikliğini direkt GPGS’in kendi AndroidManifest’ine uygulamayı deneyebilirsiniz. Bu değişiklikten sonra, siz örnek kod gibi adım uygulamasanız dahi oyunun başında izin çağrılmaz. Bir izin gerekeceği zaman, o izni o esnada kod ile istemeniz lazım.
Hocam öncelikle cevabınız için teşekkürler, dediğiniz şekilde de hata verdi ama daha sağlıklı bir yol buldum. Bu güzel siteyi ziyaret edenler için linki aşağıya bırakıyorum.
https://docs.unity3d.com/ScriptReference/Android.Permission.html