React Native跳转Android原生界面

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了React Native跳转Android原生界面相关的知识,希望对你有一定的参考价值。

摘要:故事发生的起因是RN android因为获取一个验证码cookie的后续问题太麻烦

 

RN注册监听

componentWillMount(){
  InteractionManager.runAfterInteractions(()=>{
      this.passwordListener=DeviceEventEmitter.addListener(‘PassWordMessage‘,this.receiveandroidMessage);
      this.startMyActivity();
    })
}

 

RN监听的回调方法

receiveAndroidMessage = (msg) => {
    console.log("回调-->" + msg);
    if(msg.indexOf(‘,‘)!=-1){
      //从回调消息的字符串根据‘,‘拆分,得到字符串数组passwordMessage
      var passwordMessage = msg.split(",");
      let mId=passwordMessage[0];
      let mToken=passwordMessage[1];
      let mMsg=passwordMessage[2];
      //移除监听
      if(this.passwordListener!=null){
          this.passwordListener.remove();
        }
        //跳转页面
      this.props.navigator.push({
                name: ‘phonerest‘,
                component:PhoneReset,
                params:{
                    id:mId,
                    token:mToken,
                    msg:mMsg
                }
              });
        
    }else{
      if(this.passwordListener!=null){
          this.passwordListener.remove();
        }
      //back
      this._navLeftClick();
    }
  };

RN调用原生Locatfb类的startMyActivity();

startMyActivity = () => {
  NativeModules.Locatfb.startMyActivity();
}

原生Locatfb类

package com.xxxxxx
import
android.Manifest; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.location.Criteria; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.Bundle; import android.support.v4.app.ActivityCompat; import android.widget.Toast; import com.facebook.react.bridge.ActivityEventListener; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContextBaseJavaModule; import com.facebook.react.bridge.ReactMethod; import com.facebook.react.modules.core.DeviceEventManagerModule; public class Locatfb extends ReactContextBaseJavaModule implements ActivityEventListener { //private String locationProvider; private ReactApplicationContext mContext; public Locatfb(ReactApplicationContext reactContext) { super(reactContext); mContext=reactContext; } @Override public String getName() { return "Locatfb"; } @ReactMethod public void startMyActivity(){ Intent intent = new Intent(mContext,ResetPassword.class); //intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); Bundle bundle=new Bundle(); mContext.addActivityEventListener(this);//增加监听 让当前类的onActivityResult来处理 mContext.startActivityForResult(intent,100,bundle); } @Override public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent intent) { switch (requestCode) { case 100: if (resultCode == 101) { String backActivity = intent.getStringExtra("message"); sendPassWordMessage(backActivity); } if (resultCode == 102) { String passwordMessage = intent.getStringExtra("message"); sendPassWordMessage(passwordMessage); } break; default: } } @Override public void onNewIntent(Intent intent) { } //将消息msg发送给RN侧 public void sendPassWordMessage(String passwordStr){ mContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit("PassWordMessage",passwordStr); } }

原生展示的Activity

package com.xxxxxx;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;

import com.lzy.okhttputils.OkHttpUtils;
import com.lzy.okhttputils.callback.BitmapCallback;
import com.lzy.okhttputils.callback.StringCallback;

import org.json.JSONException;
import org.json.JSONObject;

import java.text.SimpleDateFormat;
import java.util.Date;

import okhttp3.Call;
import okhttp3.Response;

public class ResetPassword extends Activity{

    private EditText phoneText,verifyText;
    private ImageView verifyImg;
    private String API_HOME="https://www.xxxxxxxxxx.com";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_reset_password);
        verifyImg= (ImageView) findViewById(R.id.verifyImg);
        phoneText= (EditText) findViewById(R.id.phoneText);
        verifyText= (EditText) findViewById(R.id.verifyText);
        Intent intent = getIntent();
        this.fetch();
    }

    private void fetch() {
        String time=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date());
        Log.d("formatter------->",time);
     //获取验证码图片
        OkHttpUtils.get(API_HOME+"xxxxxxxxxxx"+"?date="+time)//
                .tag(this)//
                .execute(new BitmapCallback() {
                    @Override
                    public void onSuccess(Bitmap bitmap, Call call, Response response) {
                        Log.d("bitmap------->",bitmap+"");
                        verifyImg.setImageBitmap(bitmap);
                    }

                    @Override
                    public void onError(Call call, Response response, Exception e) {
                        super.onError(call, response, e);
                        Log.d("response------->",response+"");
                    }
                });
    }

  //提交相关数据
    public void buttonClick(View view){
        String phone=phoneText.getText().toString();
        String identify=verifyText.getText().toString();
        OkHttpUtils.post(API_HOME+"xxxxxxxxxxxx")//
                .tag(this)//
                .params("phone", phone)
                .params("numcode", identify)
                .execute(new StringCallback() {
                    @Override
                    public void onSuccess(String s, Call call, Response response) {
                        Log.d("s------->",s);
                        try {
                            JSONObject jsonObject =new JSONObject(s);
                            String statusCode=jsonObject.getString("statusCode");
                            String msg=jsonObject.getString("msg");
                            if(statusCode=="0"){
                                String id=jsonObject.getString("id");
                                String token=jsonObject.getString("token");

                                String passwordMessage=id+","+token+","+msg;
                                //Log.d("passwordMessage------->",passwordMessage);
                   //intent携带所需数据回传
                                Intent intent = new Intent();
                                intent.putExtra("message",passwordMessage);
                                setResult(102, intent);
                   //当前界面干掉 finish(); }
else{ Toast.makeText(ResetPassword.this,msg,Toast.LENGTH_SHORT).show(); } } catch (JSONException e) { e.printStackTrace(); } } @Override public void onError(Call call, Response response, Exception e) { super.onError(call, response, e); Log.d("response------->",response+""); } }); }      //直接点击返回键,intent携带数据回传 public void backClick(View view){ Intent intent = new Intent(); intent.putExtra("message","backActivity"); setResult(101, intent); finish(); }   //更换验证码 public void verifyImageClick(View v){ fetch(); } }

原生引用的网络框架app/build.gradle

 

dependencies {
   。。。
    compile ‘com.lzy.net:okhttputils:+‘  //版本号使用 + 可以自动引用最新版
}

 

okhttputils在onCreate()相关设置

package com.xxxxxx;

import android.app.Application;

import com.RNFetchBlob.RNFetchBlobPackage;
import com.beefe.picker.PickerViewPackage;
import com.blueprintalpha.rnandroidshare.RNAndroidSharePackage;
import com.cboy.rn.splashscreen.SplashScreenReactPackage;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.shell.MainReactPackage;
import com.facebook.soloader.SoLoader;
import com.geektime.rnonesignalandroid.ReactNativeOneSignalPackage;
import com.github.alinz.reactnativewebviewbridge.WebViewBridgePackage;
import com.imagepicker.ImagePickerPackage;
import com.lzy.okhttputils.OkHttpUtils;
import com.lzy.okhttputils.cookie.store.MemoryCookieStore;
import com.lzy.okhttputils.cookie.store.PersistentCookieStore;
import com.lzy.okhttputils.model.HttpHeaders;
import com.lzy.okhttputils.model.HttpParams;
import com.oblador.vectoricons.VectorIconsPackage;
import com.rota.rngmaps.RNGMapsPackage;
import com.syarul.rnalocation.RNALocation;

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

import cl.json.RNSharePackage;

public class MainApplication extends Application implements ReactApplication {

  private static final AnExampleReactPackage myReactPackage=new AnExampleReactPackage();

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

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

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

  @Override
  public void onCreate() {
    super.onCreate();
    SoLoader.init(this, /* native exopackage */ false);
    HttpHeaders headers = new HttpHeaders();
    headers.put("commonHeaderKey1", "commonHeaderValue1");    //所有的 header 都 不支持 中文
    headers.put("commonHeaderKey2", "commonHeaderValue2");
    HttpParams params = new HttpParams();
    params.put("commonParamsKey1", "commonParamsValue1");     //所有的 params 都 支持 中文
    params.put("commonParamsKey2", "这里支持中文参数");

    //必须调用初始化
    OkHttpUtils.init(this);
    //以下都不是必须的,根据需要自行选择
    OkHttpUtils.getInstance()//
            .debug("OkHttpUtils")                                              //是否打开调试
            .setConnectTimeout(OkHttpUtils.DEFAULT_MILLISECONDS)               //全局的连接超时时间
            .setReadTimeOut(OkHttpUtils.DEFAULT_MILLISECONDS)                  //全局的读取超时时间
            .setWriteTimeOut(OkHttpUtils.DEFAULT_MILLISECONDS)                 //全局的写入超时时间
            .setCookieStore(new MemoryCookieStore())                           //cookie使用内存缓存(app退出后,cookie消失)
            .setCookieStore(new PersistentCookieStore())                       //cookie持久化存储,如果cookie不过期,则一直有效
            .addCommonHeaders(headers)                                         //设置全局公共头
            .addCommonParams(params);

  }
}

原生模块管理

package com.xxxxxx;
import com.facebook.react.ReactActivity;
import com.facebook.react.ReactPackage;
import com.facebook.react.shell.MainReactPackage;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.javascriptModule;
import com.facebook.react.uimanager.UIManagerModule;
import com.facebook.react.uimanager.ViewManager;
import android.app.Activity;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Collections;
class AnExampleReactPackage implements ReactPackage {
  
  //添加原生模块
  @Override
  public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
    List<NativeModule> modules = new ArrayList<>();
    modules.add(new Locatfb(reactContext));
    return modules;
  }

  @Override
  public List<Class<? extends JavaScriptModule>> createJSModules() {
    return Collections.emptyList();
  }
//添加原生组件
  @Override
  public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
    return Collections.emptyList();
  }


 }

AndroidManifest.xml文件

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

    <uses-sdk
        android:minSdkVersion="16"
        android:targetSdkVersion="22" />

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <!-- Approximate location - If you want to use promptLocation for letting OneSignal know the user location. -->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <!-- Precise location If you want to use promptLocation for letting OneSignal know the user location. -->
    <uses-permission android:name="android.permission.ACCESS_LOCATION" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.USE_CREDENTIALS" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />

    <application
     //调用Application必须添加 android:name
=".MainApplication" 。。。。。。> <activity android:name=".MainActivity" android:configChanges="keyboard|keyboardHidden|orientation|screenSize" android:label="@string/app_name" android:launchMode="singleTop"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />   //原生新增页面必须注册 <activity android:name=".ResetPassword"></activity> </application> </manifest>

 




以上是关于React Native跳转Android原生界面的主要内容,如果未能解决你的问题,请参考以下文章

react-native 跳转到ios/android 权限设置界面

React-Native个人信息界面

react native通过组件props的navigation实现界面跳转

React Native Android原生模块开发实战|教程|心得|怎样创建React Native Android原生模块

React Native Android原生模块开发实战|教程|心得|如何创建React Native Android原生模块

React Native:Android 原生模块