如何从React Module功能(Get Call Log)打印/输出返回的原始文本?

时间:2017-07-28 11:48:40

标签: android react-native native react-native-android

我正在创建一个本机安卓应用程序来访问并打印出日期/日期的部分列表中的Android手机/平板电脑的通话记录(例如,昨天; 26/07/17; 25/07/17等) ;但是当我从模块调用方法时,我仍然停留在react类中的调用日志字符串的实际打印中。显然反应方法只能“回归”无效。

我试图使用promises但却陷入了异步和等待。我不能使用npm 5(具有异步和等待的节点),因为我使用“react native init”为物理设备测试创建了一个项目;并且不支持/稳定npm(在终端上显示)。我使用“sudo npm install -g npm @ latest-4”,所以我可以使用init。

我尝试使用“npm install async --save”和“npm install asyncawait”手动安装async并等待。当我跑到后来它没有任何区别。

我真的只想在我的物理Android设备的屏幕上输出呼叫详细信息作为部分列表。

我试过google;但也许我的关键词不够好;所以我得到了一些帮助。如果你能告诉我是否需要.xml文件,如果是这样的话也会很好;看起来如何。我已经发布了我的java本机模块方法的代码和我从帮助器.js类导入模块的类。我为评论的代码道歉;我尝试了很多方法来打印。

我得到的最新错误;当我真的可以举杯时,'tag'是“未定义的不是一个对象(评估'n.data.length')”。在解决“期望组件类得到对象”和“未定义不是函数”之后。

下面的反应js类:

import React, { Component } from 'react';
import { NativeModules, AppRegistry, SectionList, StyleSheet, Text, View, WebView } from 'react-native';
import { StackNavigator, } from 'react-navigation';
import CallLogAndroid from './RctActivity';


export default class SectionListBasics extends Component {
static navigationOptions = { title: 'Your Call Logs', };
//  CallLog = () =>{
//     const Cllog= CallLogAndroid.getCallDetails();
//     console.log(Cllog+"");
//     return Cllog+"";
// };

// async function getCallLog() {
//     try {
//       var CallDetails = await CallLogAndroid.getCallDetails(100, 100);
//       console.log(CallDetails);
//       return CallDetails;
//     } 
//     catch (e) {
//       console.error(e);
//     }
// }
componentWillMount() {
   const log = CallLogAndroid.getCallDetails().then(function(value) {
    console.log(value); // "Success"
  }, function(value) {
    // not called
  });
}
render() {

// const divStyle = {
//   WebkitTransition: 'all', // note the capital 'W' here
//   msTransition: 'all' // 'ms' is the only lowercase vendor prefix
// };



// var thenProm = resolvedProm.then(function(value){
//   console.log("this gets called after the end of the main stack. the value received and returned is: " + value);
//   return value;
// });
console.log(this.log+"");
//getCallLog();
return (
  <View style={styles.container}>
     <SectionList
      sections={[
        {title: 'Today', data: [ 'pete'{/*this.log*/}] },
        {/* <WebView source={{html: CallLogAndroid.getCallDetails()}} /> */},
        {title: 'Yesterday', data: ['Jackson']},
        {title: 'Date: 1', data: ['water']},
        {title: 'Date: 2', data: ['dance']},
        {title: 'Date: 3', data: ['rain']},
        {title: 'Date: 4', data: ['Mum']},
        {title: 'Date: 5', data: ['Dad']},
      ]}
      renderItem={({item}) => <Text style={styles.item}>{item}</Text>}
      renderSectionHeader={({section}) => <Text style={styles.sectionHeader}>{section.title}</Text>}
    /> 
    {/* <Text>
    console.log(CallLogAndroid.getCallDetails().toString());

    </Text> */}
  </View>
 );
}
}

const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: 22
},
sectionHeader: {
paddingTop: 2,
paddingLeft: 10,
paddingRight: 10,
paddingBottom: 2,
fontSize: 20,
fontWeight: 'bold',
backgroundColor: 'rgba(247,247,247,1.0)',
},
item: {
padding: 10,
fontSize: 18,
height: 44,
},
})

// skip this line if using Create React Native App
//AppRegistry.registerComponent('AwesomeProject', () => SectionListBasics);

这是java类:

package com.workingapp;

import android.widget.Toast;

//to create react bridge
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.common.MapBuilder;
import com.facebook.react.uimanager.IllegalViewOperationException;
import com.facebook.react.bridge.Promise;


//android tools imports
import android.content.Intent;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.app.Activity;
import android.Manifest;
import android.content.ContentValues;
import android.content.pm.PackageManager;
import android.provider.CallLog;
import android.provider.CallLog.Calls;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.database.Cursor;   //import cursor to parse call logs
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.app.LoaderManager;
import android.content.CursorLoader;
import android.content.Loader;
import android.os.Bundle;
import android.text.Html;   //import html to  make *online query to content provider
import android.util.Log;
import android.view.View;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;

import android.widget.ImageView;
import android.view.Gravity;   //import gravity to centre layout
import android.view.ViewGroup;
import android.view.LayoutInflater;


import java.util.Map;
import java.net.*;  //import uri - a Uniform Resource Identifier (URI) is a string of characters used to identify a resource. Such identification enables interaction with representations of the resource over a network
import java.util.Date;
import android.widget.TextView;
import java.util.HashMap;

//Customised versions of loader imported
import android.support.v4.app.FragmentActivity;
//import android.support.v4.app.LoaderManager;
//import android.support.v4.content.Loader;

//Specific imports for inflator in toast
import java.io.UnsupportedEncodingException;
import java.util.zip.DataFormatException;
import java.util.zip.Deflater;
import java.util.zip.Inflater;

public class CallLogModule extends ReactContextBaseJavaModule implements LoaderManager.LoaderCallbacks<Cursor>{
    public static final String REACT_CLASS = "CallLogAndroid";
    private static final String E_LAYOUT_ERROR = "E_LAYOUT_ERROR";
    ReactApplicationContext reactContext;
    private static HashMap<String, String> rowDataCall;
    private static final String TAG = "CallLog";
    private static final int URL_LOADER = 1;

    private static TextView callLogsTextView;

    // @Override
    // public void onCreate(Bundle savedInstanceState) {
    //     super.onCreate(savedInstanceState);
    //     Log.d(TAG, "onCreate()");

    //     setContentView(R.layout.main);
    //     initialize();
    // }

    /**Constructor */
    public CallLogModule(ReactApplicationContext reactContext) {
        super(reactContext);
        this.reactContext= reactContext;
        //(Activity)reactContext.setContentView(R.layout.module_layout);
    }


    /**Loads all calls */
    @Override
    @ReactMethod
    public Loader onCreateLoader(int loaderID, Bundle args) {

    Log.d(TAG, "onCreateLoader() >> loaderID : " + loaderID);

    switch (loaderID) {
        case URL_LOADER:
        // Returns a new CursorLoader
        return new CursorLoader(
        reactContext,   // Parent activity context
        CallLog.Calls.CONTENT_URI,        // Table to query
        null,     // Projection to return
        null,            // No selection clause
        null,            // No selection arguments
        null             // Default sort order
        );

        default:
        return null;
        }
    }

    /**On completing load, return/output formatted string*/
    @Override
    @ReactMethod
    public void onLoadFinished(Loader loader, Cursor managedCursor) {
        Log.d(TAG, "onLoadFinished()");

        StringBuilder sb = new StringBuilder();

        int number = managedCursor.getColumnIndex(CallLog.Calls.NUMBER);
        int type = managedCursor.getColumnIndex(CallLog.Calls.TYPE);
        int date = managedCursor.getColumnIndex(CallLog.Calls.DATE);
        int duration = managedCursor.getColumnIndex(CallLog.Calls.DURATION);

        sb.append("<h4>Call Log Details <h4>");
        sb.append("\n");
        sb.append("\n");

        sb.append("<table>");

        while (managedCursor.moveToNext()) {
            String phNumber = managedCursor.getString(number);
            String callType = managedCursor.getString(type);
            String callDate = managedCursor.getString(date);
            //Date callDayTime = new Date(Long.valueOf(callDate));
            Date callDayTime= null;
            if( (!callDate.trim().equals("") ) && (callDate != null)) {    
                callDayTime = new Date(Long.valueOf(callDate));  //if value of long is null
            }
            String callDuration = managedCursor.getString(duration);
            String dir = null;

            int callTypeCode = Integer.parseInt(callType);
            switch (callTypeCode) {
                case CallLog.Calls.OUTGOING_TYPE:
                    dir = "Outgoing";
                    break;

                case CallLog.Calls.INCOMING_TYPE:
                    dir = "Incoming";
                    break;

                case CallLog.Calls.MISSED_TYPE:
                    dir = "Missed";
                    break;
            }

            sb.append("<tr>")
                    .append("<td>Phone Number: </td>")
                    .append("<td><strong>")
                    .append(phNumber)
                    .append("</strong></td>");
            sb.append("</tr>");
            sb.append("<br/>");
            sb.append("<tr>")
                    .append("<td>Call Type:</td>")
                    .append("<td><strong>")
                    .append(dir)
                    .append("</strong></td>");
            sb.append("</tr>");
            sb.append("<br/>");
            sb.append("<tr>")
                    .append("<td>Date & Time:</td>")
                    .append("<td><strong>")
                    .append(callDayTime)
                    .append("</strong></td>");
            sb.append("</tr>");
            sb.append("<br/>");
            sb.append("<tr>")
                    .append("<td>Call Duration (Seconds):</td>")
                    .append("<td><strong>")
                    .append(callDuration)
                    .append("</strong></td>");
            sb.append("</tr>");
            sb.append("<br/>");
            sb.append("<br/>");
        }
        sb.append("</table>");

        managedCursor.close();

        callLogsTextView.setText(Html.fromHtml(sb.toString()),TextView.BufferType.SPANNABLE);
    }

    @Override
    @ReactMethod
    public void onLoaderReset(Loader<Cursor> loader) {
        Log.d(TAG, "onLoaderReset()");
        // do nothing
    }

    /**Method to obtain name of the class */
    @Override
    public String getName() {
        return REACT_CLASS;
    }


    /**Method to get entire call log */
    // @ReactMethod
    // public void getCallLog(String phone,int duration) {
    //     //Checking if permission was denied
    //     if (ActivityCompat.checkSelfPermission(getCurrentActivity(), Manifest.permission.READ_CALL_LOG) != PackageManager.PERMISSION_GRANTED){
    //         ActivityCompat.requestPermissions(getCurrentActivity(), new String[]{Manifest.permission.READ_CALL_LOG}, 101);
    //     }

    //     //uses a cursor to get all calls
    //    else{
    //         Uri allCalls = Uri.parse("content://call_log/calls");
    //         Cursor c = managedQuery(allCalls, null, null, null, null);

    //         //separates calls according to number; name; duration and Call type
    //         String num= c.getString(c.getColumnIndex(CallLog.Calls.NUMBER));// for  number
    //         String name= c.getString(c.getColumnIndex(CallLog.Calls.CACHED_NAME));// for name
    //         String duration = c.getString(c.getColumnIndex(CallLog.Calls.DURATION));// for duration
    //         int type = Integer.parseInt(c.getString(c.getColumnIndex(CallLog.Calls.TYPE)));// for call type, Incoming or out-going.

    //         //Print calls in a certain format

    //     }
    // }

    /**Method to get full list of call logs */
    @ReactMethod
    private void getCallDetails(Promise promise) {

            try{


            StringBuffer sb = new StringBuffer();
            Uri contacts = CallLog.Calls.CONTENT_URI;
            Cursor managedCursor = (reactContext.getCurrentActivity()).getContentResolver().query(contacts, null, null, null, null);
            int number = managedCursor.getColumnIndex(CallLog.Calls.NUMBER);
            int type = managedCursor.getColumnIndex(CallLog.Calls.TYPE);
            int date = managedCursor.getColumnIndex(CallLog.Calls.DATE);
            int duration = managedCursor.getColumnIndex(CallLog.Calls.DURATION);
            //sb.append("Call Details :");

            sb.append("<h1>Call Log Details </h1>");  //tried to print out with react syntax contrary to code commented below
            sb.append("\n");
            sb.append("\n");

            sb.append("<table>");

            while (managedCursor.moveToNext()) {

                rowDataCall = new HashMap<String, String>();

                String phNumber = managedCursor.getString(number);
                String callType = managedCursor.getString(type);
                String callDate = managedCursor.getString(date);
                String callDayTime = new Date(Long.valueOf(callDate)).toString();
                // long timestamp = convertDateToTimestamp(callDayTime);
                String callDuration = managedCursor.getString(duration);
                String dir = null;
                int dircode = Integer.parseInt(callType);
                switch (dircode) {
                case CallLog.Calls.OUTGOING_TYPE:
                    dir = "OUTGOING";
                    break;

                case CallLog.Calls.INCOMING_TYPE:
                    dir = "INCOMING";
                    break;

                case CallLog.Calls.MISSED_TYPE:
                    dir = "MISSED";
                    break;
                }
                // sb.append("\nPhone Number:--- " + phNumber + " \nCall Type:--- " + dir + " \nCall Date:--- " + callDayTime + " \nCall duration in sec :--- " + callDuration);
                // sb.append("\n----------------------------------");

                sb.append("<tr>")
                        .append("<td>Phone Number: </td>")
                        .append("<td><strong>")
                        .append(phNumber)
                        .append("</strong></td>");
                sb.append("</tr>");
                sb.append("<br/>");
                sb.append("<tr>")
                        .append("<td>Call Type:</td>")
                        .append("<td><strong>")
                        .append(dir)
                        .append("</strong></td>");
                sb.append("</tr>");
                sb.append("<br/>");
                sb.append("<tr>")
                        .append("<td>Date & Time:</td>")
                        .append("<td><strong>")
                        .append(callDayTime)
                        .append("</strong></td>");
                sb.append("</tr>");
                sb.append("<br/>");
                sb.append("<tr>")
                        .append("<td>Call Duration (Seconds):</td>")
                        .append("<td><strong>")
                        .append(callDuration)
                        .append("</strong></td>");
                sb.append("</tr>");
                sb.append("<br/>");
                sb.append("<br/>");
            }
            sb.append("</table>");

            managedCursor.close();
            String clLog=sb.toString();

            promise.resolve(clLog);
            }

            catch (IllegalViewOperationException e) { promise.reject(E_LAYOUT_ERROR, e); }
            //System.out.println(sb.toString());
            // callLogsTextView.setText(Html.fromHtml(sb.toString()));
            // WebView webview = new WebView(reactContext.getCurrentActivity());
            // webview.loadData(sb.toString(), "text/html", "utf-8");
            //Toast.makeText(reactContext, sb.toString(), Toast.LENGTH_LONG).show();


//            LayoutInflater inflater = reactContext.getCurrentActivity().getLayoutInflater();
//            View layout = inflater.inflate(R.layout.module_layout,
//                    (ViewGroup) reactContext.getCurrentActivity().findViewById(R.id.custom_toast_container));
//
//            ImageView image = (ImageView) layout.findViewById(R.id.image);
//            image.setImageResource(R.drawable.android);
//            TextView text = (TextView) layout.findViewById(R.id.text);
//            text.setText(sb.toString());
//
//            Toast toast = new Toast(reactContext.getCurrentActivity());
//            toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
//            toast.setDuration(Toast.LENGTH_LONG);
//            toast.setView(layout);
//            toast.show();
    }
}

1 个答案:

答案 0 :(得分:0)

我明白了。我混淆了承诺和回调代码。 我再次使用了promises,它起作用了。

const log = CallLogAndroid.getCallDetails()。then(function(value){     的console.log(值);

“。then(function(...”用于解析回调。它不应该被添加,并且必须使用异步函数。使用promises;只需调用该函数就应该返回数据。< / p>