Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handle download intents in my app

My webview app already handles external URL's fine (opens links from external apps like viber, browsers, etc) like this- (i got this code from here)

// get URL from browsable intent filter
    TextView uri = (TextView) findViewById(R.id.urlField);
    // get the url
    url = getIntent().getDataString();
    Uri data = getIntent().getData();
    if (data == null) {
        uri.setText("");
    } else {
        uri.setText(getIntent().getData().toString());
        fadeout();
    }
    // }

in my webview settings

// Load URL from Browsable intent filter if there is a valid URL pasted
    if (uri.length() > 0)
        webView.loadUrl(url);
    else
        // dont load

this is how i handle downloads within my webview

// download manager
    webView.setDownloadListener(new DownloadListener() {
        @Override
        public void onDownloadStart(String url, String userAgent,
                String contentDisposition, String mimeType,
                long contentLength) {
            DownloadManager.Request request = new DownloadManager.Request(
                    Uri.parse(url));
            request.setMimeType(mimeType);
            String cookies = CookieManager.getInstance().getCookie(url);
            request.addRequestHeader("cookie", cookies);
            request.addRequestHeader("User-Agent", userAgent);
            request.setDescription("Downloading file...");
            request.setTitle(URLUtil.guessFileName(url, contentDisposition,
                    mimeType));
            request.allowScanningByMediaScanner();
            request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
            request.setDestinationInExternalPublicDir(
                    Environment.DIRECTORY_DOWNLOADS, URLUtil.guessFileName(
                            url, contentDisposition, mimeType));
            DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
            dm.enqueue(request);
            Toast.makeText(getApplicationContext(), "Downloading File",
                    Toast.LENGTH_LONG).show();
        }
    });
    // download manager

However, I'd like to handle that download intents passed by other apps as well. How do i do that?

This is what i use to open the system default app chooser from another app.(my app is listed here)-

   // download via...
    webView.setDownloadListener(new DownloadListener() {
        public void onDownloadStart(String url, String userAgent,
                String contentDisposition, String mimetype,
                long contentLength) {
            Intent i = new Intent(Intent.ACTION_VIEW);
            i.setData(Uri.parse(url));
            startActivity(i);
            Toast.makeText(getApplicationContext(), "don't choose our app as it can't handle download intents, i have posted a question on stackoverflow though.",
                    Toast.LENGTH_SHORT).show();
        }
    });
    // download via..

Whenever i click a download link, my app opens, but just sits still instead of opening the url. I want it to act like a downloader app

like image 877
MaggotSauceYumYum Avatar asked Jul 04 '16 01:07

MaggotSauceYumYum


2 Answers

you have to solve issues to

  • (a) always show the chooser
  • (b) tell android that your app should become part of the chooser
  • (c) process the "download"

(a) always show the chooser

replace

startActivity(i);

with

startActivity(Intent.createChooser(i, "caption of the choser"));

(b) tell android that your app should become part of the chooser

In the manifest you have to declare that you have an activity that can handle the relevant content

<manifest ... >
    <application ... >
        <activity android:name=".MyDownloadActivity" ...>
            <intent-filter >
                <action android:name="android.intent.action.VIEW" />
                <action android:name="android.intent.action.SEND" />
                <action android:name="android.intent.action.SENDTO" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data
                    android:mimeType="*/*"
                    android:scheme="file" />
            </intent-filter>
            <intent-filter > <!-- mime only SEND(_TO) -->
                <action android:name="android.intent.action.SEND" />
                <action android:name="android.intent.action.SENDTO" />
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
                <category android:name="android.intent.category.CATEGORY_OPENABLE" />

                <!--
                these do not work :-(
                <data android:scheme="content" android:host="*"  />
                <data android:scheme="content" 
                    android:host="media" 
                    android:pathPattern="/external/images/media/.*" />
                <data android:host="*" android:scheme="content" 
                    android:mimeType="image/*" />
                -->
                <data android:mimeType="*/*" />
            </intent-filter>
        </activity>
    </application>

</manifest>

* (c) process the "download"

MyDownloadActivity Your MyDownloadActivity.onCreate() will receive all mime-types * / * for SEND, SENDTO, VIEW. For Details see @Vickyexpert-s answer

intent-intercept is a free android tool to analyse intents. it can intercept nearly every intent. you can look at the sourcecode to see how this is done.

I use sendtosd as my general purpose download handler. It-s sourcecoder is available on github

like image 84
k3b Avatar answered Sep 19 '22 05:09

k3b


You need to put below code in your activity which response the intent,

void onCreate(Bundle savedInstanceState) {
    // Get intent, action and MIME type
    Intent intent = getIntent();
    String action = intent.getAction();
    String type = intent.getType();

    if (Intent.ACTION_VIEW.equals(action))
    {
        */if (type.startsWith("image/“))
          {*/
            downloadImage(intent); // Download image being sent
        }
    }

void downloadImage(Intent intent) {
    Uri imageUri = (Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM);
    if (imageUri != null) {
        // Write Your Download Code Here
    }
}
like image 27
Vickyexpert Avatar answered Sep 20 '22 05:09

Vickyexpert