7

I'm working on an app and I want to integrate the Last.fm app into it. Basically, when someone is looking at an artist in my app, I would like to have a button that they can tap to open up Last.fm application with the artist's information.

This intent works, but it loads a menu asking which app I would like to use (Browser or Last.fm):

Intent i = new Intent();
i.setData(Uri.parse("http://last.fm/music/" + headliner));
i.setAction("android.intent.action.VIEW");
startActivity(i);

However, I just want to start the Last.fm app and skip the dialog asking which app to use, I thought maybe using the setPackage() method would work like this:

i.setPackage("fm.last.android");

But it causes the app to crash:

android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW dat=http://last.fm/music/Rihanna pkg=fm.last.android }

Is it possible to just start the Last.fm app? Here's a copy of Last.fm's AndroidManifest.xml for reference.

Thanks for reading, Tony

tonyc
  • 832
  • 2
  • 11
  • 23

1 Answers1

14

Yes, it's possible but you need to know the correct component name. Launch the last.fm app regularly and check the logfile for the cmp=... information that's been used when the app is started. Use this as well in your app then.

I start the Z-DeviceTest app from the market from within my app without a problem like this:

final Intent intentDeviceTest = new Intent("android.intent.action.MAIN");                
intentDeviceTest.setComponent(new  ComponentName("zausan.zdevicetest","zausan.zdevicetest.zdevicetest"));
startActivity(intentDeviceTest);

in my case the info I took from the logcat was:

// dat=content://applications/applications/zausan.zdevicetest/zausan.zdevicetest.zdevicetest

// cmp=zausan.zdevicetest/.zdevicetest

in order to know how to start the app with the right component/class... do the same for the last.fm app

Edit: I've tested to launch Last.fm from my own app, and this works fine without any errors:

final Intent intentDeviceTest = new Intent("android.intent.action.MAIN");                
intentDeviceTest.setComponent(new ComponentName("fm.last.android","fm.last.android.LastFm"));
startActivity(intentDeviceTest);
Community
  • 1
  • 1
Mathias Conradt
  • 28,420
  • 21
  • 138
  • 192
  • This is a hack and not considered the proper way to call applications. Thiis a sure way to make sure all kinds of errors will show up – Falmarri Aug 19 '10 at 09:29
  • can you explain why this is a hack? you're using the regular Intent of the app that's been called by the App Launcher as well, i.e. when you click on the app icon on the home screen? Anyway, so what's the proper way then that you'd suggest instead? – Mathias Conradt Aug 19 '10 at 12:50
  • Maybe I misunderstood. If you're calling the activity that the launcher calls, then I guess that should be fine. I understood the question as calling an INTERNAL activity of a different package. This is prone to breaking because that activity could require intent extras that could cause a crash, or something like that. Without seeing the code, it's not possible to tell if it's 100% safe – Falmarri Aug 19 '10 at 17:11
  • This worked just like I wanted it to. It is worth noting that Falmarri brings up a good point, this kind of functionality isn't really encouraged and you should really check if the application is installed to avoid a force close. – tonyc Aug 19 '10 at 20:19
  • Ok, I see your point. But such eventual force close should be possible to catch in your app I assume. I haven't tried it but wouldn't a try/catch do? Ok, agree, it's kind of hacky maybe, but I don't know of any other approach if the other app doesn't offer an official 'public' custom intent. – Mathias Conradt Aug 20 '10 at 00:16
  • @tonyc Wrap `startActivity` in a try block and catch `android.content.ActivityNotFoundException` which will be thrown if the package doesn't exist. That way, your app will not be terminated. – Brent Faust Mar 28 '14 at 02:10
  • 1
    @Brent Foust, the docs actually recommend doing if (intent.resolveActivity(getPackageManager()) != null) { startActivity(intent); } to avoid ActivityNotFound exception. – The_Martian Nov 19 '15 at 06:04
  • 1
    @The_Martian that sounds good, too. As far as the "recommended" Android way, it can be quite a mess to read through all that error handling, just to launch an activity. if the common case is that it will succeed, try/catch reads a bit cleaner. +1 for the mention of this alternative. – Brent Faust Nov 19 '15 at 06:58
  • I have followed this solution to call third party app activity, but I am getting: android.content.ActivityNotFoundException: Unable to find explicit activity class {fm.last.android/fm.last.android.LastFm}; have you declared this activity in your AndroidManifest.xml? And If I use try-catch blog or if (intent.resolveActivity(getPackageManager()) != null) { startActivity(intent); } to avoid ANF exception then its not showing exception, but still unable to call an activity – Sonali Mar 16 '16 at 07:31
  • here is my updated code and post: http://stackoverflow.com/questions/36026860/call-third-party-app-activity-from-own-app – Sonali Mar 16 '16 at 07:59
  • @Sonali Do you have LastFM installed? Maybe the package name of the app has changed? Did you check the manifest or the LastFm app version, to make sure you are calling the right activity? If it's still the app that they have on Github, it should still be valid though. https://github.com/lastfm/lastfm-android/blob/master/app/AndroidManifest.xml – Mathias Conradt Mar 16 '16 at 08:03