1

I have an Android app that creates a local HTML file & then displays this to the user in a browser. I have had issues with BrowserActivity not working on different devices, subject to whatever browser is installed. My current code does the following -

    public void displayStats()
{
    String file = produceStats();
    Uri uri = Uri.parse("file://" + file);

    // chrome ??
    Intent intent1 = new Intent(Intent.ACTION_VIEW);        
    intent1.setDataAndType(uri, "multipart/related");

    // default "Internet" browser
    Intent intent2 = new Intent(Intent.ACTION_VIEW, uri);
    intent2.setDataAndType(uri, "text/html");
    intent2.setClassName("com.android.browser", "com.android.browser.BrowserActivity");         

    // any other browser (FireFox) ??
    Intent intent3 = new Intent(Intent.ACTION_VIEW);
    intent3.setDataAndType(uri, "text/html");
    intent3.addCategory(Intent.CATEGORY_BROWSABLE);             

    PackageManager packageManager = getPackageManager();
    List<ResolveInfo> activities1 = packageManager.queryIntentActivities(intent1, 0);
    List<ResolveInfo> activities2 = packageManager.queryIntentActivities(intent2, 0);
    List<ResolveInfo> activities3 = packageManager.queryIntentActivities(intent3, 0);

    boolean isIntentSafe1 = activities1.size() > 0;
    boolean isIntentSafe2 = activities2.size() > 0;
    boolean isIntentSafe3 = activities3.size() > 0;

    List<Intent> targetedShareIntents = new ArrayList<Intent>();

    if (isIntentSafe1)
    {
        unpackResolvedIntents(uri, "multipart/related", activities1, targetedShareIntents);         
    }
    if (isIntentSafe2) {
        unpackResolvedIntents(uri, "text/html", activities2, targetedShareIntents); 
    }
    if (isIntentSafe3) {
        unpackResolvedIntents(uri, "text/html", activities3, targetedShareIntents); 
    } 

    if (targetedShareIntents.isEmpty()) {
        // go to market to install app ????
        Toast.makeText(plink.this, "Please install BROWSER to complete (Chrome)", Toast.LENGTH_LONG).show();
        Intent goToMarket = new Intent(Intent.ACTION_VIEW)
        .setData(Uri.parse("market://details?id=com.android.chrome"));
        startActivity(goToMarket);
    } else if (targetedShareIntents.size() == 1) {
        startActivity(targetedShareIntents.remove(0));          
    } else {
        Intent chooserIntent = Intent.createChooser(targetedShareIntents.remove(0), "Select viewer");
        Intent[] extraIntents = new Intent[targetedShareIntents.size()];
        for (int i = 0; i < targetedShareIntents.size(); i++) {extraIntents[i] = targetedShareIntents.get(i);}
        chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, extraIntents);

        startActivity(chooserIntent);
    }

}

The produceStats() call returns the path to the file, then the rest of this function handles various different browser, and if more than one available it offers the user a Chooser.

My problem is that one user has reported the app crashing when he runs this on a Kindle HD device with the SILK browser. His stack dump is thus -

26 Jan 2014 16:26:09 GMT:Uncaught exception in java.lang.Thread:main(Unable to find explicit activity class {com.android.browser/com.android.browser.BrowserActivity}; have you declared this activity in your AndroidManifest.xml?)
android.content.ActivityNotFoundException: Unable to find explicit activity class {com.android.browser/com.android.browser.BrowserActivity}; have you declared this activity in your AndroidManifest.xml?
at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1624)
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1418)

My question is - how do I launch on a Kindle to display the file in SILK ? Thank you

daveD
  • 869
  • 1
  • 7
  • 24
  • Is there a particular reason you are not just using `ACTION_VIEW` with your `Uri` and `text/html` as the MIME type? Or, why you are not just using `WebView` yourself in your own activity? What do you think that you are gaining from the rest of this code, other than a lot of complexity? – CommonsWare Jan 28 '14 at 19:07
  • @CommonsWare Thanks for the reply. I would like to use all the various browsers available if possible, I've found by trial & error (& searching here) the differences required to keep each browser happy. I can try just ACTION_VIEW with URI & Mimetype as you suggest, I'm just concerned why Kindle threw the error in the stack trace & would it just do the same again ? Thanks. – daveD Jan 29 '14 at 09:41
  • "I've found by trial & error (& searching here) the differences required to keep each browser happy" -- the old AOSP browser is perfectly capable of handling an `ACTION_VIEW` `Intent` without `setClassName()`. Every time you use `setClassName()` (or its equivalents) pointing to some app other than your own, using hardcoded values, `$DEITY` kills a `$CUTEBABYANIMAL`. "I'm just concerned why Kindle threw the error in the stack trace" -- somehow, `PackageManager` thinks your hardcoded `setClassName()` is fine, when in reality it is not, on that device. – CommonsWare Jan 29 '14 at 13:13
  • @CommonsWare - thats kind of my problem "the old AOSP browser is perfectly capable of handling an ACTION_VIEW Intent" - the user having the problem is using KINDLE HD with SILK browser, and its not working with the ACTION_VIEW intent. I did a quick build with just my URI & Mime type set (setClassName removed), it works on my Android devices, & throws the same exception on a Kindle HD. Is this Kindle specific ? – daveD Jan 29 '14 at 18:42
  • "throws the same exception on a Kindle HD" -- the exception you have above specifically states that it is trying to launch `com.android.browser/com.android.browser.BrowserActivity`, which AFAIK should only occur if that's what you specified in the `Intent`. – CommonsWare Jan 29 '14 at 18:45

2 Answers2

2

Slik on a Kindle Fire HD does not seem to support the file:// scheme for HTML, based upon an examination of its manifest. It only appears to support http://, https://, and inline://. I cannot explain the specific crash that you are encountering, as I do not see any sign of the AOSP browser app, and so I do not know why PackageManager would report otherwise.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
1
final Uri uri = Uri.parse(filePath);
Intent browserIntent = new Intent(Intent.ACTION_VIEW, uri);
browserIntent.addCategory(Intent.CATEGORY_BROWSABLE);
context.startActivity(browserIntent);