Örnek Eşitleme Adaptörü uygulamasını uygulamaya çalışırken yukarıdaki istisnayı aldım. Bu konuyla ilgili çok sayıda gönderi gördüm, ancak tatmin edici bir yanıt yok.
Bu yüzden, başka birinin aynı konuya girmesi durumunda çözümümü buraya yazacağım .
Örnek Eşitleme Adaptörü uygulamasını uygulamaya çalışırken yukarıdaki istisnayı aldım. Bu konuyla ilgili çok sayıda gönderi gördüm, ancak tatmin edici bir yanıt yok.
Bu yüzden, başka birinin aynı konuya girmesi durumunda çözümümü buraya yazacağım .
Yanıtlar:
Bunun gibi sorunlarda hata ayıklamak için başka yararlı ipuçları.
Önce bazı etiketler için ayrıntılı günlük kaydını etkinleştirin:
$ adb shell setprop log.tag.AccountManagerService VERBOSE
$ adb shell setprop log.tag.Accounts VERBOSE
$ adb shell setprop log.tag.Account VERBOSE
$ adb shell setprop log.tag.PackageManager VERBOSE
Günlük kaydını şu şekilde göreceksiniz:
V/AccountManagerService: initiating bind to authenticator type com.example.account
V/Accounts: there is no service connection for com.example.account
V/Accounts: there is no authenticator for com.example.account, bailing out
D/AccountManagerService: bind attempt failed for Session: expectLaunch true, connected false, stats (0/0/0), lifetime 0.002, addAccount, accountType com.example.account, requiredFeatures null
Bu, bu hesap türü için kayıtlı bir kimlik doğrulayıcısı olmadığı anlamına gelir. Hangi doğrulayıcıların kayıtlı olduğunu görmek için paketi yüklerken günlüğü izleyin:
D/PackageManager: encountered new type: ServiceInfo: AuthenticatorDescription {type=com.example.account}, ComponentInfo{com.example/com.example.android.AuthenticatorService}, uid 10028
D/PackageManager: notifyListener: AuthenticatorDescription {type=com.example.account} is added
Kimlik doğrulayıcı xml tanımlayıcısının, kurulum sırasında düzgün bir şekilde çözülmeyen bir dize kaynağına başvurması sorununu yaşadım:
android:accountType="@string/account_type"
Günlükler gösterdi
encountered new type: ServiceInfo: AuthenticatorDescription {type=@2131231194}, ...
Bunu normal bir dizeyle (kaynak değil) değiştirmek sorunu çözdü. Bu, Android 2.1'e özgü görünüyor.
android:accountType="com.example.account"
Öncelikle, bu yazıda açıklanan durumu kontrol edin :
Eğer bir hata görürseniz [...] AccountManagerServiceformun caller uid XXXX is different than the authenticator's uid, biraz yanıltıcı olabilir. Bu mesajdaki 'kimlik doğrulayıcı', kimlik doğrulayıcı sınıfınız değil, Android'in hesap türü için kayıtlı kimlik doğrulayıcı olarak anladığı şeydir. Görünüşte gerçekleşen kontrol AccountManagerServiceşuna benzer:
private void checkCallingUidAgainstAuthenticator(Account account) {
final int uid = Binder.getCallingUid();
if (account == null || !hasAuthenticatorUid(account.type, uid)) {
String msg = "caller uid " + uid + " is different than the authenticator's uid";
Log.w(TAG, msg);
throw new SecurityException(msg);
}
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "caller uid " + uid + " is the same as the authenticator's uid");
}
}
Not hasAuthenticatorUid()alır account.type. Bu benim mahvettiğim yer. AccountBir sabit tarafından belirtilen bir türle kendimi oluşturuyordum :
class LoginTask {
Account account = new Account(userId, AuthenticatorService.ACCOUNT_TYPE);
...
}
class AuthenticatorService extends Service {
public static final String ACCOUNT_TYPE = "com.joelapenna.foursquared";
...
}
ancak bu sabit, doğrulayıcımın XML tanımıyla eşleşmedi:
<account-authenticator xmlns:android="/web/20150729061818/http://schemas.android.com/apk/res/android"
android:accountType="com.joelapenna.foursquared.account" ... />
İkinci olarak, eğer benim gibiyseniz ve örneği test etmek için mevcut uygulamanıza yerleştirmek istiyorsanız Constants, bu örneğin bir parçası olan ve android.provider.SyncStateContractpaketin altında olmayan sınıfı kullandığınızdan emin olun . Çünkü her iki sınıf da nesne ACCOUNT_TYPEoluştururken kullanılan aynı öznitelik adını kullanır Account.
Benim durumumda sorun basitçe ACCOUNTTYPE bir uyumsuzluk ilan çok oldu res/xml/authenticator.xmlkadar android:accountType="com.foo"ama yanlış başvurulan "foo.com"Hesabı oluşturmanın:
Account newAccount = new Account("dummyaccount", "foo.com");
Doh!
Özel hesabı uygulamak için birkaç bölüm var ...
AccountManager'ı Aktivitenizde çağırmak için, zaten uyguladığınız gibi bir şey ...
Account account = new Account(username, ACCESS_TYPE);
AccountManager am = AccountManager.get(this);
Bundle userdata = new Bundle();
userdata.putString("SERVER", "extra");
if (am.addAccountExplicitly(account, password, userdata)) {
Bundle result = new Bundle();
result.putString(AccountManager.KEY_ACCOUNT_NAME, username);
result.putString(AccountManager.KEY_ACCOUNT_TYPE, ACCESS_TYPE);
setAccountAuthenticatorResult(result);
}
Res / xml / authenticator.xml'de AccountAuthenticator verilerinizi tanımlamanız gerekir (Authenticator UID'nizden sorumludur). ACCESS_TYPE, bu xml'de tanımladığınız accountType ile aynı dizge olmalıdır!
<account-authenticator xmlns:android="http://schemas.android.com/apk/res/android"
android:accountType="de.buecherkiste"
android:icon="@drawable/buecher"
android:label="@string/app_name"
android:smallIcon="@drawable/buecher" >
</account-authenticator>
Son olarak hizmetinizi Manifest olarak tanımlamalısınız. Lütfen hesaplarınızı yönetmek için ilgili izinleri unutmayın (AUTHENTICATE_ACCOUNTS / USE_CREDENTIALS / GET_ACCOUNTS / MANAGE_ACCOUNTS)
<service android:name=".AuthenticationService">
<intent-filter>
<action android:name="android.accounts.AccountAuthenticator" />
</intent-filter>
<meta-data android:name="android.accounts.AccountAuthenticator"
android:resource="@xml/authenticator" />
</service>
Hatam, AccountManager getAccounts () yönteminin yalnızca uygulama içeriğimle ilişkili hesapları döndürdüğünü varsaymaktı. -Dan değiştim
AccountManager accountManager = AccountManager.get(context);
Account[] accounts = accountManager.getAccounts();
-e
AccountManager accountManager = AccountManager.get(context);
Account[] accounts = accountManager.getAccountsByType(Constants.ACCOUNT_TYPE);
Manifest'inizdeki niyet filtrelerinize yanlış değerler koyarsanız aynı hata görünecektir. Sync-adapters üzerine android-dev eğitimini inceledim ve "intent-filter / action android: name" için sahte bir değer ve syncadapter / accountauthenticator için "meta-data / android: name" ayarladım. Bu hata aynı hataların günlüklerde görünmesine neden oldu.
Kayıt için doğru değerler şunlardır: {android.content.SyncAdapter, android.accounts.AccountAuthenticator}
Öncelikle, Jan Berkel'in mükemmel hata ayıklama tavsiyesine bir kez daha bakın.
Son olarak, kontrol edilmesi gereken başka bir şey, içerik sağlayıcınızın ve kimlik doğrulama ve senkronizasyon hizmetlerinin applicationetiketin alt öğeleri olarak bildirilmesidir .
<application
...>
<activity
...(Activity)...
</activity>
<provider
...(CP service declaration)/>
<service
...(Authentication service declaration)...
</service>
<service
...(Sync service declaration)...
</service>
</application>
Benim için çok aptalca bir hataydı ve bulması çok zordu.
Authenticator.xml'de yazdım
<account-authenticator xmlns:android="http://schemas.android.com/apk/res/android">
xmlns:android="http://schemas.android.com/apk/res/android"
android:accountType="com.myapp"
android:icon="@drawable/ic_launcher"
android:smallIcon="@drawable/ic_launcher"
android:label="@string/app_name"
/>
onun yerine
<account-authenticator
xmlns:android="http://schemas.android.com/apk/res/android"
android:accountType="com.myapp"
android:icon="@drawable/ic_launcher"
android:smallIcon="@drawable/ic_launcher"
android:label="@string/app_name"
/>
Bu hataya neden olan. Umarım bu birine yardımcı olur!
Benim durumumda sahip olduğum manifest dosyasındaki izinlerdi
<uses-permission android:name="ANDROID.PERMISSION.GET_ACCOUNTS"/>
olarak değiştirdiğimde hepsi büyük harfti
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
sorun gitti
Ayrıca,
AccountType'ı düz eski bir String gibi çok fazla muamele edip etmediğinizi kontrol edin.
Kodumun çoğu com.mycompany.android altında paketlenmiş durumda
Şu AccountType'ı başarıyla kullanıyorum: com.mycompany.android.ACCOUNT .
Artık birden fazla hesap kullanma isteğim var ve hesabımın sonuna ".subType" ekleme yaklaşımını denediğimde,
arayan kullanıcı kimliği xxxxx, kimlik doğrulayıcının kullanıcı kimliğinden farklı
Ancak, "_subType" (nokta yerine alt çizgi) kullanırsam iyi çalışıyor.
Tahminimce Android, kaputun altında bir yerde com.mycompany.android.ACCOUNT hesabını yasal bir paket adı olarak ele almaya çalışıyor, ki bu kesinlikle öyle değil.
Ve yine:
KÖTÜ com.mycompany.android.ACCOUNT.subType
İYİ com.mycompany.android.ACCOUNT_subType
Bu hatayı alıyorsanız ve yukarıdaki tüm çözümler sizin için çalışmıyorsa. Ayrıca, tüm prosedürü uyguladığınızı varsayarsınız. Kimlik Doğrulama Hizmetinin, Hesap Eklemek için kullanmak istediğiniz başka bir geliştirici tarafından geliştirilmiş olma ihtimali olabilir.
Deneyebileceğiniz şey, uygulamanızı bir sürüm anahtar deposu ile imzalamayı denemektir. Şimdi uygulamayı çalıştırın. Sanırım bu senin için çalışmalı.
İşte olası bir çözüm daha.
Bu hatayı, kullanıcım android google hesabıyla aynı e-postayla uygulamama kaydolduğunda aldım.
Yani, denediğimde accountManager.getAccounts() bu e-postayı aramaya aynı e-postaya sahip ancak başka bir hesap türüne sahip bir hesap buldum. Yani, bu (google.com) hesabı kullanmaya çalışırken bu hatayı alıyorum.
Dolayısıyla, bir hesap bulmanın doğru yolu şudur:
public Account findAccount(String accountName) {
for (Account account : accountManager.getAccounts())
if (TextUtils.equals(account.name, accountName) && TextUtils.equals(account.type, "myservice.com"))
return account;
return null;
}
accountManager.getAccountsByType("myservice.com")yerine arayabilirsin .
Ayrıca, AccountAuthenticatorService'inizin kanıtlayıcı niyet filtrelerine sahip olduğundan emin olun;
yani.
<service android:name=".service.AccountAuthenticatorService">
<intent-filter>
<action android:name="android.accounts.AccountAuthenticator" />
</intent-filter>
<meta-data android:name="android.accounts.AccountAuthenticator"
android:resource="@xml/authenticator" />
</service>
Samsung cihazlarında bu istisnayı alırsanız, güvenli modu kullanmadığınızdan emin olun .
Aynı uygulamalar farklı mağazalardan, örneğin amazon uygulama mağazasından ve google oyun mağazasından ise, uygulamaların imzası bu durumda farklı olacağından, sonunda güvenlik istisnası atılacaktır. Aynı kimlik doğrulayıcıyı tek amaçlı oturum açarsanız, uygulamalardan biri kilitlenir. Bu sorunla bir kez karşılaşmıştım. Özellikle amazon app store, güvenlik amacıyla uygulamalarını kendi imzasıyla imzalar.
Not: Burada belirtilen herhangi bir yazım hatası veya diğer yanıtlar yoksa, lütfen tek oturum açma durumunda uygulamaların imzasını kontrol edin.
Hala sorun yaşayanlar için: https://stackoverflow.com/a/37102317/4171098
Benim durumumda, Manifest'te yanlışlıkla AuthenticatorService'i
<application>etiketlerin dışında tanımladım . Beyanı içeriye taşımak<application>sorunu çözdü. Umut birine yardım edecek.