Разрешаването на намерение за URL понякога е нула, хвърля NullPointerException

Имам приложение за Android, което прави това:

    PackageManager pm = getApplicationContext().getPackageManager();
    Intent browserIntent = new Intent();
    browserIntent.setAction(Intent.ACTION_VIEW);
    browserIntent.addCategory(Intent.CATEGORY_BROWSABLE);
    browserIntent.setData(Uri.parse("http://www.google.com"));

    ResolveInfo resolveInfo = pm.resolveActivity(browserIntent, PackageManager.MATCH_DEFAULT_ONLY);
    try {
        String browserType = nutent.activityInfo.packageName;
    } catch (NullPointerException npe) {
        npe.printStackTrace();
    }

Тествах това на 4 различни телефона и много различни конфигурации на емулатор. Всички те работят добре. Но получавам доклади за сривове от внедрени приложения в дивата природа, хвърлящи NPE, тъй като resolveInfo понякога е нула.

Незабавното решение е да хвана NPE и да се справя с него, преди да срине приложението ми (както е направено по-горе). Но се опитвах с дни да възпроизведа това сам и не успях. На емулатор с инсталиран единствен браузър по подразбиране, той се разрешава на com.android.browser.BrowserActivity:

ResolveInfo{411ef228 com.android.browser.BrowserActivity p=0 o=0 m=0x208000}

По същия начин, на телефон с инсталирани множество браузъри, това се разрешава малко по-различно...до com.android.internal.app.ResolverActivity:

ResolveInfo{415c13b8 com.android.internal.app.ResolverActivity p=0 o=0 m=0x0}

Документите resolveActivity() тук посочете:

Връща ResolveInfo, съдържащ окончателното намерение за дейност, което е определено като най-доброто действие. Връща нула, ако не е намерена съответстваща дейност. Ако бъдат открити множество съвпадащи дейности и няма набор по подразбиране, връща ResolveInfo, съдържащ нещо друго, като например преобразувателя на дейността.

Така че разгледах първия сценарий, този на намерение за дейност, определено като най-доброто действие. Също последният сценарий, този на множество съвпадащи дейности без действие по подразбиране, връщащ ResolverActivity.

Наистина бих искал да възпроизведа сценария на resolveActivity(), който ми дава нула при искане на активността на URL. Някой има ли идеи как може да стане това без, да речем, рутване на устройството?


person AWT    schedule 21.12.2012    source източник
comment
Като настрана, да ядете изключението, както правите, е лоша практика. Изключенията се хвърлят по основателна причина и тъй като имате достъп до външен ресурс, има множество причини, поради които той може да се провали и вашият код трябва да се справи с тях.   -  person Simon    schedule 21.12.2012
comment
Това всъщност е само фиктивно намерение, което се използва само за извличане на типа и версията на браузъра (ако е налично), никога не се използва за извличане на уеб страници или за извършване на нещо друго. Вярвам, че в този случай изяждането на изключението и задаването на низовете за тип и версия на браузъра на неизвестни е адекватно. Няма нищо друго, което бих искал да направя с изключение.   -  person AWT    schedule 21.12.2012
comment
Добър въпрос. И аз не знам със сигурност, но предполагам, че може би не сте покрили последния сценарий, този на множество съвпадащи дейности без действие по подразбиране, въпреки че смятате, че сте го направили, защото посочвате MATCH_DEFAULT_ONLY. Не съм разбил изходния код на PackageManager (добра следваща стъпка), но се чудя какво прави, ако му кажете да съответства на подразбиране, а няма подразбиране, връща нула? Тествали ли сте на устройство или емулатор с множество браузъри и НЯМА настройка ПО ПОДРАЗБИРАНЕ? (Уверете се, че инструментът за избор се показва, ако щракнете върху връзка и т.н.)   -  person Charlie Collins    schedule 22.12.2012
comment
Добри идеи, ще ги обработя тази вечер и ще видя как ще е.   -  person AWT    schedule 22.12.2012
comment
Може би тези доклади за срив идват от телефон без браузър? Когато руутнете телефона си, можете да премахнете дори системни приложения, така че можете да премахнете дори вградения браузър за Android. Също така това може да се дължи на персонализиран фърмуер. Знаете ли, има стотици китайски телефони, работещи с Android с предварително инсталиран персонализиран фърмуер. Често някои Android приложения на тези телефони се заменят с персонализирани. Така че може би има персонализирани браузъри, които не отговарят на вашите намерения.   -  person s.maks    schedule 28.02.2013
comment
@s.maks това наистина е проблемът, потвърдих го, като руутнах телефона си и премахнах всички браузъри. Ако искате да го напишете като отговор, ще го приема.   -  person AWT    schedule 01.03.2013


Отговори (1)


Наистина бих искал да възпроизведа сценария на resolveActivity(), който ми дава нула при искане на активността на URL. Някой има ли идеи как може да стане това без, да речем, рутване на устройството?

  1. Отидете в Настройки> Приложения> ВСИЧКИ> Намерете браузъра(ите) (на Nexus 4 със стандартен ROM, който би бил Chrome)> Деактивиране
  2. Започнете да хващате NPE :)
person ozbek    schedule 18.03.2013