我可以分享到我的 NativeScript 应用程序吗?

Can I share to my NativeScript app?

在 NativeScript 的当前状态下是否可以创建一个应用来侦听 Android 上的共享意图?

例如,我想要实现的是在 Android 上在我的网络浏览器中打开一个网站,点击共享并在共享目标列表中查看我的 NativeScript 应用程序。

我确实在本机 Android 应用程序上完成了此操作,但无法在 NativeScript 应用程序中使用它。我搞砸了 AndroidManifest.xml 添加

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

进入 intent-filter 但这没有帮助。我的应用没有出现在共享目标列表中。

NativeScript 应该开箱即用地支持这种情况。这是默认引导应用程序 app/App_resources/Android 中我的 AndroidManifest 的样子:

<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>

编辑: 将意图发送到我的任何其他应用程序的非常简单的实现:

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);
                }
            }
        });

除了 intent-filter 之外,您还必须在 AppManifest.xml 中添加 确保重建您的应用程序(实时同步选项可能无法反映 AppManifest.xml 中的更改)

这是基本共享的 NativeScript 实现

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;

首先在 app/App_Resources/AndroidManifest 中更新您的 AndroidManifest.xml。xml

添加如下意图过滤器

<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>

然后在 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);
        }
    });

现在您可以将您的内容从第 3 方应用分享到您的应用。

我自己一直在寻找这个问题的解决方案,发现这里的所有其他答案都非常有帮助。

然而,我是 NativeScript 的菜鸟(才接触了两天),无法真正了解在哪里以及如何实现所有代码位一起工作。

通过使用此处的答案,我可以继续搜索并找到 完成的 GITHUB 示例NickIliev/nativescript-receiving-shared-content

对于寻找已完成示例的其他新生(或新生),请转到存储库并浏览 /demo/app/ 目录中的代码。对我很有帮助,希望对你也有帮助。

如果有人正在寻找最新的 NS7 和 NS8 兼容版本,这对我和 Android 都适用。这是在 NS8 的抽屉模板应用程序上测试的。 Javascript 部分用于 home-page.js ,只需将其内容替换为下面的代码即可。

NS7 和 NS8 的导入不同,这让人感到困惑。

编辑您的 AndroidManifest.xml

App_Resources/Android/src/main/AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="__PACKAGE__"
    android:versionCode="10000"
    android:versionName="1.0">

    <supports-screens
        android:smallScreens="true"
        android:normalScreens="true"
        android:largeScreens="true"
        android:xlargeScreens="true"/>

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

    <application
        android:name="com.tns.NativeScriptApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme">

        <activity
            android:name="com.tns.NativeScriptActivity"
            android:label="@string/title_activity_kimera"
            android:configChanges="keyboard|keyboardHidden|orientation|screenSize|smallestScreenSize|screenLayout|locale|uiMode"
            android:theme="@style/LaunchScreenTheme">

            <meta-data android:name="SET_THEME_ON_LAUNCH" android:resource="@style/AppTheme" />

            <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="image/*" />
            </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>
            <intent-filter>
                <action android:name="android.intent.action.SEND_MULTIPLE" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="image/*" />
            </intent-filter>
        </activity>
        <activity android:name="com.tns.ErrorReportActivity"/>
    </application>
</manifest>

Javascript

home/home-page.js

    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    const Observable = require("@nativescript/core").Observable;
    const application = require("@nativescript/core/application");

    import { Application } from '@nativescript/core'
    import { HomeViewModel } from './home-view-model'

    var vm = new Observable();

    export function onNavigatingTo(args) {
    const page = args.object
    page.bindingContext = new HomeViewModel();
    page.bindingContext = vm;
    vm.set("sharedText", "Waiting for intent...");
    if (application.android) {
        application.android.on(application.AndroidApplication.activityCreatedEvent, function (args) {
            var activity = args.activity;
            console.log(activity);
            vm.set("sharedText", "Intend data received");
            // Get intent, action and MIME type
            var intent = activity.getIntent();
            var action = intent.getAction();
            var type = intent.getType();
            if (android.content.Intent.ACTION_SEND === action && type != null) {
                if (type.startsWith("text/")) {
                    handleSendText(intent); // Handle text being sent
                }
                else if (type.startsWith("image/")) {
                    handleSendImage(intent); // Handle single image being sent
                }
            }
            else if (android.content.Intent.ACTION_SEND_MULTIPLE === action && type != null) {
                if (type.startsWith("image/")) {
                    handleSendMultipleImages(intent); // Handle multiple images being sent
                }
            }
            else {
                // Handle other intents, such as being started from the home screen
            }
        });
    }
    }

    function handleSendText(intent) {
    if (application.android) {
        var sharedText = intent.getStringExtra(android.content.Intent.EXTRA_TEXT);
        if (sharedText != null) {
            // Update UI to reflect text being shared
            console.log("sharedText: ", sharedText);
            console.log("Text received!");
            // set timeout - enough to update UI after app loading
            setTimeout(func, 1000);
            function func() {
                vm.set("sharedText", sharedText);
            }
        }
    }
    }
    function handleSendImage(intent) {
    if (application.android) {
        var imageUri = intent.getParcelableExtra(android.content.Intent.EXTRA_STREAM);
        if (imageUri != null) {
            // Update UI to reflect image being shared
            console.log("Image received!");
            var appContext = application.android.context;
            var bitmap = android.provider.MediaStore.Images.Media.getBitmap(appContext.getContentResolver(), imageUri);
            console.log("bitmap: ", bitmap);
            vm.set("bitmap", bitmap);
        }
    }
    }
    function handleSendMultipleImages(intent) {
    if (application.android) {
        var imageUris = intent.getParcelableArrayListExtra(android.content.Intent.EXTRA_STREAM);
        if (imageUris != null) {
            // Update UI to reflect multiple images being shared
            console.log("imageUris: ", imageUris);
            console.log("Multiple images received!");
        }
    }
    }

    export function onDrawerButtonTap(args) {
    const sideDrawer = Application.getRootView()
    sideDrawer.showDrawer()
    }