9

I'm trying to build an Android test application integrated to the SalesForce platform. I have downloaded the SDK from here, and imported it to my workspace. Everything works fine except my test app, even the RestExplorer sample app they have provided along with the SDK work without problem. As a first step, what I tried was to clone the basic features (just login as of now) from the RestExplorer app. The following are my important files.

public class Home extends Activity {

private PasscodeManager passcodeManager;
private RestClient client;
private TokenRevocationReceiver tokenRevocationReceiver;

RestClient getClient() {
    return client;
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    passcodeManager = SalesforceSDKManager.getInstance().getPasscodeManager();
    tokenRevocationReceiver = new TokenRevocationReceiver(this);
    setContentView(R.layout.activity_home);

}

@Override 
public void onResume() {
    super.onResume();
    registerReceiver(tokenRevocationReceiver, new IntentFilter(ClientManager.ACCESS_TOKEN_REVOKE_INTENT));      
    if (passcodeManager.onResume(this)) {   // Bring up passcode screen if needed
        String accountType = SalesforceSDKManager.getInstance().getAccountType();   // Login options
        new ClientManager(this, accountType, SalesforceSDKManager.getInstance().getLoginOptions(), SalesforceSDKManager.getInstance().shouldLogoutWhenTokenRevoked()).getRestClient(this, new RestClientCallback() {    // Get a rest client
            @Override
            public void authenticatedRestClient(RestClient client) {
                if (client == null) {
                    SalesforceSDKManager.getInstance().logout(Home.this);
                    return;
                }
                Home.this.client = client;              
            }
        });
    }
}

@Override
protected void onPause() {
    passcodeManager.onPause(this);
    unregisterReceiver(tokenRevocationReceiver);
    super.onPause();
}
}

I have added the permissions as required

<permission android:name="com.salesforce.samples.restexplorer.C2D_MESSAGE"
    android:protectionLevel="signature" />

<uses-permission android:name="com.salesforce.samples.restexplorer.C2D_MESSAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS"/>
<uses-permission android:name="android.permission.ACCOUNT_MANAGER"/>

And extended the application object to give a call to init();

public class MyApp extends Application {
@Override
public void onCreate() {
    super.onCreate();
    SalesforceSDKManager.initNative(getApplicationContext(), new KeyImpl(), Home.class);
}
}

Now, I'm getting the error in my Android debug log. The log as I see is attached below. It keep the activity restarting till I forcefully kill the application.

11-08 15:56:23.883: I/ClientManager:getRestClient(9334): No account of type com.salesforce.androisdk found
11-08 15:56:23.898: W/AccMgrCallback:run(9334): android.accounts.AuthenticatorException: bind failure
11-08 15:56:23.898: W/AccMgrCallback:run(9334):     at android.accounts.AccountManager.convertErrorToException(AccountManager.java:1726)
11-08 15:56:23.898: W/AccMgrCallback:run(9334):     at android.accounts.AccountManager.access$400(AccountManager.java:144)
11-08 15:56:23.898: W/AccMgrCallback:run(9334):     at android.accounts.AccountManager$AmsTask$Response.onError(AccountManager.java:1572)
11-08 15:56:23.898: W/AccMgrCallback:run(9334):     at android.accounts.IAccountManagerResponse$Stub.onTransact(IAccountManagerResponse.java:69)
11-08 15:56:23.898: W/AccMgrCallback:run(9334):     at android.os.Binder.execTransact(Binder.java:388)
11-08 15:56:23.898: W/AccMgrCallback:run(9334):     at dalvik.system.NativeStart.run(Native Method)

Do anyone have any idea about this isse? It is such a basic app, I was not expecting anything unusual. Did I do anything wrong in my app?

  • I'm sure this can't be it but... should there be another "d" in there? s/androisdk/androidsdk/? – shannonsans Mar 17 '14 at 20:54
  • @shannonsans I could have made a typo, I'm sorry – Subin Sebastian Mar 19 '14 at 5:08
  • Sorry, I wasn't clear -- I was looking at the error message in the log: "11-08 15:56:23.883: I/ClientManager:getRestClient(9334): No account of type com.salesforce.androisdk found". I assumed you pasted straight out of the log and wondered if it might have contributed. – shannonsans Mar 19 '14 at 15:12
  • Any luck on this guys, adding account_type in strings.xml didnt work for me..? – Naz Jan 22 '15 at 1:08
6
+50

The issue is most likely that you've used the (generic) com.salesforce.androisdk account type on more than one app—e.g. one of the sample apps and your new app—on your emulator/device. The Mobile SDK doesn't find the account initially for your new app, but then ends up trying to access the account from the previous app, and so you run into bind failures, security/privileges exceptions, etc.

You should be overriding the account type in your application, with a value that's unique to your particular app. In your app's strings.xml:

    <string name="account_type">com.yourpackage.yourapp.auth.account</string>

That should get past the bind failure. The "No account of type" message is expected the first time you log in.

A future version of the Mobile SDK for Android will make this account flow more robust, so hopefully the issue won't come up.

  • I don't find account_type attribute in my strings.xml file for newly created app... Do I need to add 1? – Braj Mar 18 '14 at 7:20
  • Yes, you should create one, and make the value something that will be unique to your app (package name + app name + optional account key is generally a good example). – KevinH Mar 20 '14 at 22:48
  • I observed that, if u do whole process in right way as in that link(before building created app, building SalesforceSDK etc), even without account_type attribute, app runs smoothly... Earlier, I did not do that building process n all properly so used to get this error. Now everything seems working fine. – Braj May 23 '14 at 9:51
2

I came across this, too when doing a simple example. The "No account of type xyz" isn't really an error, just an informational message from the account manager. The real issue is the "bind error".

For the Authenticator Service to work properly, you need to define it in your AndroidManifest. The easiest way to do this is to just add "manifestmerger.enabled=true" to your project.properties and do a project clean. This way, you will also inherit all the proper permissions and other SDK items such as the LoginActivity, PasscodeActivity, Manage Space Activity, etc, from the SDK.

$ cat project.properties
# Project target.
target=android-17
android.library.reference.1=../SalesforceMobileSDK-Android/libs/SalesforceSDK
manifestmerger.enabled=true
1

I'm not sure this is anything to do with a connectivity issue on Salesforce to be honest, as I don't see any of the usual WSC (Web Service Connector) classes in the stack trace. So the 'account' its referring to is likely something on the device itself. I found this post on StackOverflow, AuthenticatorException: bind failure on, which seems to indicate this might be the cause.

You're getting this error because you don't have any accounts registered on your virtual device.

It may be worth posting something on the forum indicated on the Github readme as well.

  • You're getting this error because you don't have any accounts registered on your virtual device. This is incorrect, because I do the testing on an actual device, where an account is available. One thing, is that the chatter app works perfectly on the same device with the exact same oAuth feature. – Subin Sebastian Nov 12 '13 at 4:45
1

just because oauth works in chatter on android, doesn't mean your app has permissions to utilize the accounts features within the system. without access to your manifest I can't say for sure, but make sure you're positively referencing ACCOUNT_MANAGER as an app permission that you need.

  • I have added permission <uses-permission android:name="android.permission.ACCOUNT_MANAGER"/> and the problem persists. I have updated the question with this change. – Subin Sebastian Nov 17 '13 at 10:18
1

Ok guys, just recently overcome above issue. Turns out I was cloning files from the test apps, rather than creating a specific app with the correct reverse domain URL, using forcedroid. Ie dont just copy files across but create a new app using forecedroid, then integrate you existing code into the newly created app (forcedroid created)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.