morenoh149 / react-native-contacts

React Native Contacts
MIT License
1.64k stars 560 forks source link

View contacts - React Native Android #676

Closed yanivbs closed 2 years ago

yanivbs commented 2 years ago

I am trying to view the contacts in Android Emulator,

I manage to get the permission, but for some reason the compiler is unable to access contacts and displays this error :

image

image

I have implemented all the installation requirements for working with contacts.

// App.js

import React, { useState, Component } from 'react';
import { Appbar } from 'react-native-paper';
import { View, StyleSheet, Header, StatusBar, Image, Text, SafeAreaView, ImageBackground, Button, Platform, PermissionsAndroid, requestMultiple  } from 'react-native';
import Contacts from 'react-native-contacts';

class App extends Component {

   async requestContactsPermission() {
    if (Platform.OS === 'ios') {
      return true
    } else {
      const granted = await PermissionsAndroid.requestMultiple([PermissionsAndroid.PERMISSIONS.READ_CONTACTS, PermissionsAndroid.PERMISSIONS.WRITE_CONTACTS]);
      if (granted['android.permission.READ_CONTACTS'] === PermissionsAndroid.RESULTS.GRANTED && granted['android.permission.WRITE_CONTACTS'] === PermissionsAndroid.RESULTS.GRANTED)
      {
        return true
      } else {
        return false
      }
    }
  }

  getContaxt = () => {
    this.requestContactsPermission().then((didGetPermission) => {
      if (didGetPermission) {           
        Contacts.getAll()
          .then((contacts) => {
            //loadContacts();        
           //alert("rich to here")
            console.warn(Contacts)     // <--  Goes in here but is unable to access contacts
          }).catch((e) => { alert('no permission') })  
      } 
    })

  }
  render() {
    return (
      <View style={styles.container}>
        <Button title="Load contacts" onPress={this.getContaxt}/>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center",
    backgroundColor: '#F5FCFF'
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin:10
  }
})

export default App;`

// build.gradle dependencies

dependencies { implementation project(':react-native-contacts')

implementation fileTree(dir: "libs", include: ["*.jar"])

//noinspection GradleDynamicVersion
implementation "com.facebook.react:react-native:+"  // From node_modules

implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"

debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") {
    exclude group:'com.facebook.fbjni'
}

debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
    exclude group:'com.facebook.flipper'
    exclude group:'com.squareup.okhttp3', module:'okhttp'
}

debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") {
    exclude group:'com.facebook.flipper'
}

if (enableHermes) {
    def hermesPath = "../../node_modules/hermes-engine/android/";
    debugImplementation files(hermesPath + "hermes-debug.aar")
    releaseImplementation files(hermesPath + "hermes-release.aar")
} else {
    implementation jscFlavor
}

}`

//MainApplication.java

`package com.mytest;

import android.app.Application;
import android.content.Context;
import com.facebook.react.PackageList;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.config.ReactFeatureFlags;
import com.facebook.soloader.SoLoader;
import com.mytest.newarchitecture.MainApplicationReactNativeHost;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import com.rt2zz.reactnativecontacts.ReactNativeContacts;

public class MainApplication extends Application implements ReactApplication {

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

        @Override
        protected List<ReactPackage> getPackages() {
          @SuppressWarnings("UnnecessaryLocalVariable")
          List<ReactPackage> packages = new PackageList(this).getPackages();
          // Packages that cannot be autolinked yet can be added manually here, for example:
          // packages.add(new MyReactNativePackage());
          packages.add(new ReactNativeContacts());
          return packages;
        }

        @Override
        protected String getJSMainModuleName() {
          return "index";
        }
      };

  private final ReactNativeHost mNewArchitectureNativeHost =
      new MainApplicationReactNativeHost(this);

  @Override
  public ReactNativeHost getReactNativeHost() {
    if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
      return mNewArchitectureNativeHost;
    } else {
      return mReactNativeHost;
    }
  }

  @Override
  public void onCreate() {
    super.onCreate();
    // If you opted-in for the New Architecture, we enable the TurboModule system
    ReactFeatureFlags.useTurboModules = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
    SoLoader.init(this, /* native exopackage */ false);
    initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
  }

  /**
   * Loads Flipper in React Native templates. Call this in the onCreate method with something like
   * initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
   *
   * @param context
   * @param reactInstanceManager
   */
  private static void initializeFlipper(
      Context context, ReactInstanceManager reactInstanceManager) {
    if (BuildConfig.DEBUG) {
      try {
        /*
         We use reflection here to pick up the class that initializes Flipper,
        since Flipper library is not available in release mode
        */
        Class<?> aClass = Class.forName("com.mytest.ReactNativeFlipper");
        aClass
            .getMethod("initializeFlipper", Context.class, ReactInstanceManager.class)
            .invoke(null, context, reactInstanceManager);
      } catch (ClassNotFoundException e) {
        e.printStackTrace();
      } catch (NoSuchMethodException e) {
        e.printStackTrace();
      } catch (IllegalAccessException e) {
        e.printStackTrace();
      } catch (InvocationTargetException e) {
        e.printStackTrace();
      }
    }
  }
}
`

// AndroidManifest.xml

`<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.mytest">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_CONTACTS" />
    <uses-permission android:name="android.permission.WRITE_CONTACTS" />
    <uses-permission android:name="android.permission.READ_PROFILE" />

    <application
      android:name=".MainApplication"
      android:label="@string/app_name"
      android:icon="@mipmap/ic_launcher"
      android:roundIcon="@mipmap/ic_launcher_round"
      android:allowBackup="false"
      android:theme="@style/AppTheme">
      <activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
        android:launchMode="singleTask"
        android:windowSoftInputMode="adjustResize"
        android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
      </activity>
    </application>
</manifest>`
m7amad-7asan commented 2 years ago

@yanivbs Did you find the solution ?

yanivbs commented 2 years ago

The truth is I got stuck with it, I noticed that the error occurs when I try to access the contacts in this way:

openForm = () => {
    Contacts.openContactForm({}, (err) => {
      if (err) {
        console.warn(err)
      }
    })
  }

It works for me when I change the code to something like this:

getContacts = () => {
    this.requestContactsPermission().then((didGetPermission) => {
      if (didGetPermission) {
        Contacts.getAll()
          .then((contacts) => {
            this.setState({
              myContacts: contacts
            })
            alert("rich to here")
            //console.warn(Contacts)    
          }).catch((e) => { alert('no permission') })
      }
    })
  }

The thing is that I do not always manage to use this method, for example in this section the two methods do not work for me and with this code:

openForm = () => {
    Contacts.openContactForm({}, (err) => {
      if (err) {
        console.warn(err)
      }
    })
  }

I get this error: image

And in this code:

openForm = () => {
    Contacts.openContactForm({}, (err) => { 
    }).then(console.warn("gff")).catch((e) => { console.warn(err) });   
 }

I get this error : image

// App.js

import React, { useState, Component } from 'react';
import { Appbar } from 'react-native-paper';
import { View, StyleSheet, Header, StatusBar, Image, Text, SafeAreaView, ImageBackground, Button, Platform, PermissionsAndroid, requestMultiple, Linking, ErrorHandlerCallback, ErrorUtils } from 'react-native';
import Contacts from 'react-native-contacts';

class App extends Component {

  state = {
    myContacts: []
  }

  async requestContactsPermission() {
    if (Platform.OS === 'ios') {
      return true
    } else {
      const granted = await PermissionsAndroid.requestMultiple([PermissionsAndroid.PERMISSIONS.READ_CONTACTS, PermissionsAndroid.PERMISSIONS.WRITE_CONTACTS]);
      if (granted['android.permission.READ_CONTACTS'] === PermissionsAndroid.RESULTS.GRANTED && granted['android.permission.WRITE_CONTACTS'] === PermissionsAndroid.RESULTS.GRANTED) {
        return true
      } else {
        return false
      }
    }
  }

  // Getting my contacts ->
  getContacts = () => {
    this.requestContactsPermission().then((didGetPermission) => {
      if (didGetPermission) {
        Contacts.getAll()
          .then((contacts) => {
            this.setState({
              myContacts: contacts
            })
            alert("rich to here")
            //console.warn(Contacts)    
          }).catch((e) => { alert('no permission') })
      }
    })
  }
  // Getting my contacts //

  // Adding new contact ->
  addContacts = () => {
    this.requestContactsPermission().then((didGetPermission) => {
      if (didGetPermission) {
        const newContact = {
          emailAddresses: [{
            label: "work",
            email: "yaniv.welding@gmail.com",
          }],
          familyName: "Ben-Shetrit",
          givenName: "Yaniv",
          phoneNumbers: [{
            label: "mobile",
            number: "(053) 7276021",
          }],
        }
        Contacts.addContacts(newContact)
          .then((contacts) => {
            this.getContacts();
          }).catch((e) => { alert('no permission') })
      }
    })
  }
  // Adding new contact //

  // opening new form ->
  openForm = () => {
    Contacts.openContactForm({}, (err) => {
      if (err) {
        console.warn(err)
      }
    })
  }
  // opening new form

  render() {
    return (
      <View style={styles.container}>
        {this.state.myContacts.map((item, i) => (
          <Text key={i}>{item.givenName} {item.familyName}</Text>))
        }
        <Button title="Load contacts" onPress={this.getContacts}/>
        <Button title="Add contacts" onPress={this.addContacts} />

        <Button title="open form" onPress={this.openForm} />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center",
    backgroundColor: '#F5FCFF'
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin:10
  }
})

export default App; 
github-actions[bot] commented 2 years ago

This issue is stale, please provide more information about the status