-->

Can I share to my NativeScript app?

2020-07-13 10:55发布

问题:

Is it possible in current state of NativeScript to create an app which listens for share intents on Android?

What I would like to achieve is for example having a website opened in my web browser on Android, tap on share and see my NativeScript app on the list of share targets.

I did accomplish this on a native Android app but can't get it to work in a NativeScript app. I've messed with the AndroidManifest.xml to add

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

into intent-filter but this did not help. My app does not show up in the list of share targets.

回答1:

NativeScript should support this scenario out of the box. Here's what my AndroidManifest in app/App_resources/Android of a default bootstrapped application looks like:

<activity
        android:name="com.tns.NativeScriptActivity"
        android:label="@string/title_activity_kimera"
        android:configChanges="keyboardHidden|orientation|screenSize">

        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
        <intent-filter> 
            <action android:name="android.intent.action.SEND" />
            <category android:name="android.intent.category.DEFAULT" />
            <data android:mimeType="text/plain" />
       </intent-filter>
</activity>

edit: Very simple implementation to send intent to any of my other application:

FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent sendIntent = new Intent(Intent.ACTION_SEND);
                sendIntent.setType("text/plain");
                sendIntent.putExtra("string", "the data Im sending you");

                Intent chooser = Intent.createChooser(sendIntent, "Share with ");

                if (sendIntent.resolveActivity(getPackageManager()) != null) {
                    startActivity(chooser);
                }
            }
        });


回答2:

In addition to the intent-filter you have to add in your AppManifest.xml make sure that you rebuild your app (livesync option may not reflect changes in AppManifest.xml)

Here is an NativeScript implementation for basic share

var app = require("application");

function onShare() {

    var sharingIntent = new android.content.Intent(android.content.Intent.ACTION_SEND);
    sharingIntent.setType("text/plain");
    var shareBody = "Here is the share content body";

    sharingIntent.addFlags(android.content.Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
    sharingIntent.addFlags(android.content.Intent.FLAG_ACTIVITY_NEW_TASK | android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK);

    sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "Subject Here");
    sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, shareBody);

    app.android.context.startActivity(sharingIntent);
}
exports.onShare = onShare;


回答3:

First update your AndroidManifest.xml in app/App_Resources/AndroidManifest.xml

Add following intent-filter like below

<application        android:name="com.tns.NativeScriptApplication"      android:allowBackup="true"      android:icon="@drawable/icon"       android:label="@string/app_name"
                android:theme="@style/AppTheme">        <activity           android:name="com.tns.NativeScriptActivity"
                        android:label="@string/title_activity_kimera"           android:configChanges="keyboardHidden|orientation|screenSize">

                        <intent-filter>
                <action android:name="android.intent.action.MAIN" />                                
                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>                        
                        <intent-filter>
                                <action android:name="android.intent.action.SEND" />
                                <category android:name="android.intent.category.DEFAULT" />
                                <category android:name="android.intent.category.APP_BROWSER" />
                                <data android:mimeType="text/plain" /> 
                                <data android:mimeType="image/*" />
                        </intent-filter>
                        <intent-filter>
                            <action android:name="android.intent.action.SEND_MULTIPLE" />
                            <category android:name="android.intent.category.DEFAULT" />
                            <category android:name="android.intent.category.APP_BROWSER" />
                            <data android:mimeType="image/*" />
                        </intent-filter>
                                </activity>         <activity android:name="com.tns.ErrorReportActivity"/>  </application>

Then Add following lines of code in your app.js

application.android.on(application.AndroidApplication.activityResumedEvent, function (args) {
        console.log("Event: " + args.eventName + ", Activity: " + args.activity);
        var a = args.activity;
        try {
            var Intent_1 = android.content.Intent;
            var actionSend = Intent_1.ACTION_SEND;
            var actionSendMultiple = Intent_1.ACTION_SEND_MULTIPLE;
            var argIntent = a.getIntent();
            var argIntentAction = argIntent.getAction();
            var argIntentType = argIntent.getType();
            console.log(" ~~~~ Intent is ~~~~ :" + new String(argIntent.getAction()).valueOf());
            String.prototype.startsWith = function (str) {
                return this.substring(0, str.length) === str;
            };
            if (new String(argIntentAction).valueOf() === new String(Intent_1.ACTION_SEND).valueOf()) {
                if (new String(argIntentType).valueOf() === new String("text/plain").valueOf()) {
                    console.dump(cbParseTextAndUrl(argIntent));
                }
                else if (argIntentType.startsWith("image/")) {
                    console.log(cbParseImageUrl(argIntent));
                }
            }
            else if (new String(argIntentAction).valueOf() === new String(Intent_1.ACTION_SEND_MULTIPLE).valueOf()) {
                if (argIntentType.startsWith("image/")) {
                    var Uri = cbParseMultipleImageUrl(argIntent);
                    if (Uri !== null) {
                        var Uris = JSON.parse(Uri);
                        console.log(Uris);
                    }
                }
            }
            function cbParseTextAndUrl(argIntent) {
                var Patterns = android.util.Patterns;
                //let Matcher = java.util.regex.Matcher;
                var ListUrl = [];
                var text = argIntent.getStringExtra(Intent_1.EXTRA_TEXT);
                if (new String().valueOf() !== "null") {
                    var Matcher = Patterns.WEB_URL.matcher(text);
                    while (Matcher.find()) {
                        var url = Matcher.group();
                        ListUrl.push(url);
                    }
                    return { "text": text, "listUrl": ListUrl };
                }
            }
            function cbParseImageUrl(argIntent) {
                var imageUri = argIntent.getParcelableExtra(Intent_1.EXTRA_STREAM);
                if (imageUri != null) {
                    // Update UI to reflect image being shared
                    return imageUri;
                }
            }
            function cbParseMultipleImageUrl(argIntent) {
                var imageUris = argIntent.getParcelableArrayListExtra(Intent_1.EXTRA_STREAM);
                if (imageUris != null) {
                    // Update UI to reflect image being shared
                    return JSON.stringify(imageUris.toString());
                }
            }
        }
        catch (e) {
            console.log(e);
        }
    });

Now you can share your content from 3rd party app to your app.



回答4:

I've been searching for a solution to this question myself and found all of the others answers here very helpful.

Yet, I'm a noob (only two days in) for NativeScript and couldn't actually get where and how to implement all the code bits together to work.

By using the answers here I could continue my search and found a finished GITHUB EXAMPLE: NickIliev/nativescript-receiving-shared-content

For other freshmen (or freshwoman) looking for a finished example go to the repo and explore the code in /demo/app/ directory. It was helpful for me and I'll hope it will help you too.