简体   繁体   中英

Android No Activity found to handle intent

I am basing my app off the foursquare-oAuth-sample app posted at Foursquare oAuth sample

Have made changes to MyActivity pretty much similar to the sample code but still getting this, can someone point out what I need to change, the code is as below

public class MyActivity extends FragmentActivity {


private static final int REQUEST_CODE_FSQ_CONNECT = 200;
private static final int REQUEST_CODE_FSQ_TOKEN_EXCHANGE = 201;

/**
 * Obtain your client id and secret from:
 * https://foursquare.com/developers/apps
 */
private static final String CLIENT_ID = "";
private static final String CLIENT_SECRET = "";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_my);
    ensureUi();
}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.my, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();
    if (id == R.id.action_settings) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}

/**
 * Update the UI. If we already fetched a token, we'll just show a success
 * message.
 */
private void ensureUi() {
    boolean isAuthorized = !TextUtils.isEmpty(ExampleTokenStore.get().getToken());

    TextView tvMessage = (TextView) findViewById(R.id.tvMessage);
    tvMessage.setVisibility(isAuthorized ? View.VISIBLE : View.GONE);

    Button btnLogin = (Button) findViewById(R.id.btnLogin);
    btnLogin.setVisibility(isAuthorized ? View.GONE : View.VISIBLE);
    btnLogin.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // Start the native auth flow.
            Intent intent = FoursquareOAuth.getConnectIntent(MyActivity.this, CLIENT_ID);

            // If the device does not have the Foursquare app installed, we'd
            // get an intent back that would open the Play Store for download.
            // Otherwise we start the auth flow.
            if (FoursquareOAuth.isPlayStoreIntent(intent)) {
                toastMessage(MyActivity.this, getString(R.string.app_not_installed_message));
                startActivity(intent);
            } else {
                startActivityForResult(intent, REQUEST_CODE_FSQ_CONNECT);
            }
        }


    });
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch (requestCode) {
        case REQUEST_CODE_FSQ_CONNECT:
            onCompleteConnect(resultCode, data);
            break;

        case REQUEST_CODE_FSQ_TOKEN_EXCHANGE:
            onCompleteTokenExchange(resultCode, data);
            break;

        default:
            super.onActivityResult(requestCode, resultCode, data);
    }

}

private void onCompleteConnect(int resultCode, Intent data) {
    AuthCodeResponse codeResponse = FoursquareOAuth.getAuthCodeFromResult(resultCode, data);
    Exception exception = codeResponse.getException();

    if (exception == null) {
        // Success.
        String code = codeResponse.getCode();
        performTokenExchange(code);

    } else {
        if (exception instanceof FoursquareCancelException) {
            // Cancel.
            toastMessage(this, "Canceled");

        } else if (exception instanceof FoursquareDenyException) {
            // Deny.
            toastMessage(this, "Denied");

        } else if (exception instanceof FoursquareOAuthException) {
            // OAuth error.
            String errorMessage = exception.getMessage();
            String errorCode = ((FoursquareOAuthException) exception).getErrorCode();
            toastMessage(this, errorMessage + " [" + errorCode + "]");

        } else if (exception instanceof FoursquareUnsupportedVersionException) {
            // Unsupported Fourquare app version on the device.
            toastError(this, exception);

        } else if (exception instanceof FoursquareInvalidRequestException) {
            // Invalid request.
            toastError(this, exception);

        } else {
            // Error.
            toastError(this, exception);
        }
    }
}

private void onCompleteTokenExchange(int resultCode, Intent data) {
    AccessTokenResponse tokenResponse = FoursquareOAuth.getTokenFromResult(resultCode, data);
    Exception exception = tokenResponse.getException();

    if (exception == null) {
        String accessToken = tokenResponse.getAccessToken();
        // Success.
        toastMessage(this, "Access token: " + accessToken);

        // Persist the token for later use. In this example, we save
        // it to shared prefs.
        ExampleTokenStore.get().setToken(accessToken);

        // Refresh UI.
        ensureUi();

    } else {
        if (exception instanceof FoursquareOAuthException) {
            // OAuth error.
            String errorMessage = ((FoursquareOAuthException) exception).getMessage();
            String errorCode = ((FoursquareOAuthException) exception).getErrorCode();
            toastMessage(this, errorMessage + " [" + errorCode + "]");

        } else {
            // Other exception type.
            toastError(this, exception);
        }
    }
}

/**
 * Exchange a code for an OAuth Token. Note that we do not recommend you
 * do this in your app, rather do the exchange on your server. Added here
 * for demo purposes.
 *
 * @param code
 *          The auth code returned from the native auth flow.
 */
private void performTokenExchange(String code) {
    Intent intent = FoursquareOAuth.getTokenExchangeIntent(this, CLIENT_ID, CLIENT_SECRET, code);
    startActivityForResult(intent, REQUEST_CODE_FSQ_TOKEN_EXCHANGE);
}

public static void toastMessage(Context context, String message) {
    Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
}

public static void toastError(Context context, Throwable t) {
    Toast.makeText(context, t.getMessage(), Toast.LENGTH_SHORT).show();
}

Error Log

Here is the exception i am getting, can someone please point out why is it not able to find the activity to handle intent? Thank you

08-13 23:15:23.137    2754-2754/com.example.panaceatechnologysolutions.farhansfoursquareapp E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.example.panaceatechnologysolutions.farhansfoursquareapp, PID: 2754
android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW dat=market://details?id=com.example.panaceatechnologysolutions.farhansfoursquareapp&referrer=utm_source=foursquare-android-oauth&utm_term=CLIENT_ID }
        at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1691)
        at android.app.Instrumentation.execStartActivity(Instrumentation.java:1482)
        at android.app.Activity.startActivityForResult(Activity.java:3711)
        at android.app.Activity.startActivityForResult(Activity.java:3669)
        at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:840)
        at android.app.Activity.startActivity(Activity.java:3914)
        at android.app.Activity.startActivity(Activity.java:3882)
        at com.example.panaceatechnologysolutions.farhansfoursquareapp.MyActivity$1.onClick(MyActivity.java:90)
        at android.view.View.performClick(View.java:4598)
        at android.view.View$PerformClick.run(View.java:19268)
        at android.os.Handler.handleCallback(Handler.java:738)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5070)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:836)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:631)

08-13 23:15:30.157 2754-2765/com.example.panaceatechnologysolutions.farhansfoursquareapp I/art﹕ Heap transition to ProcessStateJankImperceptible took 7.253732ms saved at least 72KB

Ok so based on Rohans reply I checked, since I was doing this on the Emulator, this snippet from the Foursquare oAuth library I have in my project cannot create the intent based on the context and client Id. I am not sure why it returns null and as a result redirects me to the Google play store to install foursquare on my emulator. I have registered my app with foursquare and am using the registered client Id and the rest of the parameters used by this function are the ones in Foursquare oAuth Java class. If someone has worked with this library or can point out why it can't find the intent please let me know as I have been stuck on this for a couple of days.

This is the line of code like Rohan pointed out calling the Foursquare oAuth Java class in MyActivity class

    Intent intent = FoursquareOAuth.getConnectIntent(MyActivity.this, CLIENT_ID);

And this is the getConnectIntent method in the Foursquare oAuth Java Class

    public static Intent getConnectIntent(Context context, String clientId) {
    Uri.Builder builder = new Uri.Builder();
    builder.scheme(URI_SCHEME);
    builder.authority(URI_AUTHORITY);
    builder.appendQueryParameter(PARAM_CLIENT_ID, clientId);
    builder.appendQueryParameter(PARAM_VERSION, String.valueOf(LIB_VERSION));
    builder.appendQueryParameter(PARAM_SIGNATURE, getSignatureFingerprint(context));

    Intent intent = new Intent(Intent.ACTION_VIEW, builder.build());
    if (isIntentAvailable(context, intent)) {
        return intent;
    }

    return getPlayStoreIntent(clientId);
}

it redirects you to play store becuase "isIntentAvailable is false" and it calls "getPlayStoreIntent" which redirects you to play store. inside isIntentAvailable method

private static boolean isIntentAvailable(Context context, Intent intent) {
     PackageManager packageManager = context.getPackageManager();
     List<ResolveInfo> resolveInfo = packageManager.queryIntentActivities(
    intent, PackageManager.MATCH_DEFAULT_ONLY);
    return resolveInfo.size() > 0;
 }

this method return true if a suitable package is found. also check your client id is not null and is correct

Yes Rohan...you are right it is false because the intent wasnt returning anything from isIntentAvailable, but the real reason why that was not returning an intent back was because since I am using the emulator, the package manager is apparently looking for a foursquare.apk package installed which it didnt find. I didnt Foursquare anywhere indicate that their apk has to be installed which is not included as part of the oAuth Library which they provide in the link above on the sample project. I guess they assume you are using an Android device for testing and not the emulator. These are the steps to use oAuth from Foursquare on Android emulator from Android studio or Eclipse im guessing as well.

1) Download the Foursquare APK http://www.apk4fun.com/apk/6395/

2) As a pre-requisite open Android SDK Manager in Android studio and make sure Google API's are downloaded and installed, these are needed by Foursquare

3) copy the foursquare.apk file in the /Applications/sdk/platform-tools folder

4) install the apk using the adb tool in the folder like shown in this link How to install an apk on the emulator in Android Studio?

5) and now your app can use the emulator to contact foursquare and you will not be redirected to install the app on the emulator!

-Note, I noticed I had to reinstall the "foursquare.apk" when i closed down Android studio and the emulator the next day. But was easy since i knew what to do, Hopefully this saves someone else the frustration as it took me a couple of days to figure this out :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM