Why does Intent.createChooser() need a BroadcastReceiver and how to implement?

前端 未结 2 1802
盖世英雄少女心
盖世英雄少女心 2020-12-10 13:07

The following snippet, called from my implementation of onOptionsItemSelected(), works nicely to carry the user from my app to a mail client with email address,

相关标签:
2条回答
  • 2020-12-10 13:14

    I see this as well on my Galaxy Nexus with 4.0.4, but only if there's only one option and the chooser doesn't appear.

    This is a bug in Android source - not much you can do about it. Their ResolverActivity registers a BroadcastReceiver, but doesn't always unregister it.

    More detail:

    Intent.createChooser() will start a ResolverActivity. In onCreate(), the activity calls

    mPackageMonitor.register(this, false);
    

    mPackageMonitor is a BroadcastReceiver and within register() it registers itself on the activity. Normally, the receiver is unregistered in onStop(). However, later in onCreate() the code checks how many options the user can choose from. If there's only one it calls finish(). Since finish() is called in onCreate() the other lifecycle methods are never called and it jumps straight to onDestroy() - leaking the receiver.

    I didn't see a bug for this in the Android issues database, so I created one.

    For more info you can see this in code:

    • ResolverActivity
    • PackageMonitor

    As a side note, Google uses email as an example of when you wouldn't want to use a chooser so you may consider just launching the intent normally. See the javadocs for Intent#ACTION_CHOOSER.

    0 讨论(0)
  • 2020-12-10 13:23

    Simple resolution of problem.

    More info here: https://developer.android.com/training/basics/intents/sending.html

    Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California");
    Intent mapIntent = new Intent(Intent.ACTION_VIEW, location);
    
    PackageManager pkManager = getPackageManager();
    List<ResolveInfo> activities = pkManager.queryIntentActivities(mapIntent, 0);
    
    if (activities.size() > 1) {
        // Create and start the chooser
        Intent chooser = Intent.createChooser(mapIntent, "Open with");
        startActivity(chooser);
    
      } else {
        startActivity( mapIntent );
    }
    
    0 讨论(0)
提交回复
热议问题