getlaunchintentforpackage возвращает значение null

#android #android-package-managers

#Android #android-менеджеры пакетов

Вопрос:

Может кто-нибудь сказать мне, пожалуйста, почему это дает мне значение null для переменной intent ?

 public class MainActivity extends AppCompatActivity {
    private static String action = "com.google.android.youtube";


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

    @Override
    public void onResume() {
        super.onResume();
        this.launch();
    }

    public void launch() {
        PackageManager pm = getPackageManager();
        Intent intent = pm.getLaunchIntentForPackage(action);
        System.out.println("debug: "   intent);
        //startActivity(intent);
    }
}
  

я тестирую это на pixel 4 и никогда не удаляю youtube. кроме того, sidequest перечисляет приложение и выдает мне пакет com.google.android.YouTube

Комментарии:

1. Ваш Pixel 4 обновлен до Android 11? Если это так, возможно, вас поймал developer.android.com/about/versions/11/privacy /.

2. @CommonsWare Вот и все. На устройстве Android 10 у меня нет этой проблемы. Итак, теперь я знаю, что делать для Android 11. Спасибо

3. @CommonsWare Я занимался этой проблемой в течение нескольких дней. Это сводило меня с ума, почему мое намерение всегда null было. Спасибо за ссылку. Не могли бы вы опубликовать это в качестве ответа?

Ответ №1:

Для многих (возможно, большинства) PackageManager методов на Android 11 и выше вам необходимо учитывать правила видимости пакета и добавлять <queries> элемент в свой манифест, чтобы указать, какие сторонние приложения вы заинтересованы в обнаружении или анализе.

Комментарии:

1. <запросы> элементы исправлены для меня. Спасибо!

2. Это не работает для меня, пожалуйста, помогите мне

Ответ №2:

Добавьте приведенный ниже код в манифест на уровне ниже, надеюсь, он будет работать с вами.

 <manifest
    <application
            >
        </application>

        <queries>
        <intent>
         <action android:name="com.google.android.youtube.api.service.START"/>
        </intent>
        </queries>
    </manifest>
  

Ответ №3:

Если вы знаете имя пакета приложения, которое хотите запустить во время сборки, ознакомьтесь с ответом CommonsWare, поскольку это будет работать на Android 11 . В моем случае я не знаю имя пакета во время сборки, потому что мы получаем его из вызова сервера, поэтому я не могу указать это в своем манифесте. Мне пришлось использовать другой подход.

Если вы знаете имя действия пакета, который пытаетесь запустить, вам не нужно вызывать getLaunchIntentForPackage , поскольку вы можете самостоятельно воспроизвести его поведение. Если вы посмотрите на источник for getLaunchIntentForPackage , PackageManager то используется только для получения имени класса activity для запускаемого пакета.

Итак, вот моя повторная реализация, которая работает на Android 11 , если вы уже знаете имя класса activity:

 // you have String variables packageName and className (fully-qualified)
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
intent.setPackage(packageName);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setClassName(packageName, className);
startActivity(intent);
  

PS: Если вы знаете имя пакета приложения, но не знаете имя действия, вероятно, лучший способ получить имя действия — это просто запустить getLaunchIntentForPackage более раннюю версию Android (версия 10 или ниже), где установлено это приложение, и получить имя действия из результирующего намерения ( intent.getComponent().getClassName() ).

Например, для YouTube значения будут:

  • packageName = "com.google.android.youtube"
  • className = "com.google.android.youtube.app.honeycomb.Shell$HomeActivity"