当前位置: 代码迷 >> Android >> react-native和安装时的引用者
  详细解决方案

react-native和安装时的引用者

热度:44   发布时间:2023-08-04 10:22:25.0

您可以将引荐来源添加到Play商店链接。

https://play.google.com/store/apps/details?id=com.myapp&referrer=foobar

如何在应用程序首次启动时在react-native应用程序中收到此推荐人?

编辑:主要问题的详细信息

要获得安装引用非常简单,只有一种方法:在安装后接收意图。 在此事件发生时,您遇到了一个问题:如何从本机Java获取值以对JavaScript做出反应? 如果你很幸运,ui是开放的,你可以发送一个无声通知或另一个已经存在的包捕获的意图。 但意图是一只孤独的狼,同时没有ui跑。

因此,您必须在JavaScript可以读取的存储中写入此值。 嗯,简单的方法是在线商店; 发送带有值的请求,并在ui的开头使用相同的标识识别和查询设备。 但是有离线方式吗?

是的,但是“重型代码”。 Java和JavaScript没有共同的存储系统,因此我将问题转移到了唯一的Java问题。 快速解决方案:查找使用本机存储系统的react-native软件包,并将本机代码克隆到接收器中以写入值。 这是我对上述问题的评论的解决方案。 它很简单,只需几行代码。

但它增加了一种不可预测的依赖性。 应用程序增长到我需要一个Android服务和其他本机函数,所以我自己写了一个react-native模块。 为了存储服务的选项,我使用了一个非常简单的键值存储,我也用它来保存安装引用。 所以我在意图接收器中将引用者写入此存储器,并且JavaScript在本地新娘身上查询了这个值。

也许有人会用这个来制作一个包。 或者有一个更简单的解决方案; 毕竟我只是一个Android初学者。


具有自己的RN模块的解决方案

我发布了我的解决方案的简短示例,因为@jeevana要求它。 我在这个问题上的评论是一个更具反应本土的答案。 这是我在原始应用中使用的解决方案,但仅限于必需品。 我的“FooModule”有更多的代码,所以我试图提取特定的代码。

JavaScript部分非常简单, App.js

const FooModule = require('react-native').NativeModules.FooModule;

import React, {
    Component,
} from 'react';

export default class FooApp extends Component {
    componentDidMount () {
        FooModule.getInstallReferrer().then(value => {
            FooModule.showShortToast("INSTALL_REFERRER JS: " + String(value));
            if (value) {
                FooModule.clearInstallReferrer();
            }
        });

    }
    render() {
        return null;
    }
}

这里是所有Java部分。 MainApplication.java

package tld.example.fooapp;

import android.app.Application;
import android.util.Log;

import com.facebook.react.ReactApplication;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.shell.MainReactPackage;

import java.util.Arrays;
import java.util.List;

public class MainApplication extends Application implements ReactApplication {

  private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
    @Override
    protected boolean getUseDeveloperSupport() {
      return BuildConfig.DEBUG;
    }

    @Override
    protected List<ReactPackage> getPackages() {
      return Arrays.<ReactPackage>asList(
          new MainReactPackage(),
          new FooPackage()
      );
    }
  };

  @Override
  public ReactNativeHost getReactNativeHost() {
      return mReactNativeHost;
  }
}

FooPackage.java

package tld.example.fooapp;

import com.facebook.react.bridge.ReactApplicationContext;

import java.util.*;

import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.uimanager.ViewManager;

public class FooPackage implements ReactPackage {
    @Override
    public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
        List<NativeModule> modules = new ArrayList<>();
        modules.add(new FooModule(reactContext));
        return modules;
    }

    public List<Class<? extends JavaScriptModule>> createJSModules() {
        return Collections.emptyList();
    }

    public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
        return Collections.emptyList();
    }
}

现在是系统意图的接收器,在FooReceiver.java

package tld.example.fooapp;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

import static android.R.attr.data;

public class FooReceiver extends BroadcastReceiver {
    private static final String TAG = "FooReceiver";
    public static String REFERRER = "";

    public FooReceiver() {

    }

    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (action.equals("com.android.vending.INSTALL_REFERRER")) {
            String referrer = intent.getStringExtra("referrer");
            Log.d(TAG, "INSTALL_REFERRER: " + referrer);
            new FooTrayPreferences(context).put(FooTrayPreferences.INSTALL_REFERRER, referrer);
        }
    }
}

本地部分的“存储类”,用于在接收器和反应原生新娘FooTrayPreferences.java的同一存储器上进行写入和读取:

package tld.example.fooapp;

import android.content.Context;
import net.grandcentrix.tray.TrayPreferences;

public class FooTrayPreferences extends TrayPreferences {

    public static String INSTALL_REFERRER = "INSTALL_REFERRER";

    public FooTrayPreferences(final Context context) {
        super(context, "FooContent", 1);
    }
}

最后一个文件是本机Java和ReactNative, FooModule.java之间的新娘:

package tld.example.fooapp;

import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableArray;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.WritableNativeArray;
import com.facebook.react.bridge.WritableNativeMap;

import android.content.Intent;
import android.content.Context;
import android.widget.Toast;

import java.util.Arrays;
import java.util.Set;
import android.util.Log;


public class FooModule extends ReactContextBaseJavaModule {
    private static final String TAG = "FooModule";
    ReactApplicationContext reactContext;
    private static String prefFile = "serviceSettings";
    private FooTrayPreferences mTrayPreferences;

    public FooModule(ReactApplicationContext reactContext) {
        super(reactContext);
        this.reactContext = reactContext;
        mTrayPreferences = new FooTrayPreferences(reactContext);
    }

    @Override
    public String getName() {
        return "FooModule";
    }

    @ReactMethod
    public void getInstallReferrer(Promise promise) {
        String installReferrer = mTrayPreferences.getString(FooTrayPreferences.INSTALL_REFERRER, "");
        promise.resolve(installReferrer);
    }

    @ReactMethod
    public void clearInstallReferrer() {
        mTrayPreferences.remove(FooTrayPreferences.INSTALL_REFERRER);

    }

    @ReactMethod
    public void showShortToast(String text) {
        Toast.makeText(reactContext, text, Toast.LENGTH_SHORT).show();
    }

    @ReactMethod
    public void showLongToast(String text) {
        Toast.makeText(reactContext, text, Toast.LENGTH_LONG).show();
    }
}

AndroidManifest.xml还需要接收器条目:

...
        <receiver
            android:name=".FooReceiver"
            android:enabled="true"
            android:process=":remotereceiver"
            android:exported="true">
            <intent-filter>
                <action android:name="com.android.vending.INSTALL_REFERRER" />
            </intent-filter>
        </receiver>
...

所以它可以工作,但它主要是本机代码。 在非常非常慢的设备上,应用程序的ui启动速度比引用者意图被激活的速度快。 关闭应用程序并重新打开它后,可以访问安装引荐来源。

这不是你无法直接用React Native获得的东西,你必须编写一些本机代码。

所以这里是交易:

  • 您可以在线程中实现自己的Jonny优秀方法版本,但不幸的是已经弃用(但在我说话的时候仍在工作)
  • 要么你应该创建一个react native插件,它会将名为Install Referrer Library的新android库的方法暴露给javascript。

现在,NPM react-native-referrer模块正在以安全的方式(用于生产)实现第一个版本,并将很快在最新的实现中迁移

  相关解决方案