Home > Software engineering >  Problem with accessing contacts on React-Native Android
Problem with accessing contacts on React-Native Android

Time:05-27

I have implemented all the installation instructions for working with contacts, but for some reason it does not work for me.

I have tried all the solutions offered here including a number of different examples of code.

The problem seems to be related to adding the package to the MainApplication.java file :

@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());  <---- The package I added
      return packages;
    }

The reason I think so is because if I delete this line, after clicking the button, the warn is activated with the comment "No permission" (attached pic.).

enter image description here

And if I run the code with this line (which mentioned above), then I get this error: (attached pic.)

enter image description here

Below I have attached pictures of App.js, package.json, MainApplication.java :

// 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 HomePage from './components/HomePage';
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((err, Contacts) => {    ///Contacts.get
          if (err) {
            throw err;
          }
          console.warn(Contacts)
        })
      } else {
        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;

// package.json

{
  "name": "MyTest",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "android": "react-native run-android",
    "ios": "react-native run-ios",
    "start": "react-native start",
    "test": "jest",
    "lint": "eslint ."
  },
  "dependencies": {
    "prop-types": "^15.8.1",
    "react": "17.0.2",
    "react-native": "0.68.2",
    "react-native-contacts": "^7.0.4"
  },
  "devDependencies": {
    "@babel/core": "7.18.0",
    "@babel/runtime": "7.18.0",
    "@react-native-community/eslint-config": "2.0.0",
    "babel-jest": "26.6.3",
    "eslint": "7.32.0",
    "jest": "26.6.3",
    "metro-react-native-babel-preset": "0.67.0",
    "react-test-renderer": "17.0.2"
  },
  "jest": {
    "preset": "react-native"
  }
}

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

Thanks !

CodePudding user response:

I have resolve the issue and checked your code you have to make changes in below files

setting.gradle file you only have to insert below line

include ':react-native-contacts'
project(':react-native-contacts').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-contacts/android')

Build.gradle you only have to insert below line in dependencies

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

ManiApplication.java file you only have to insert below line

import com.rt2zz.reactnativecontacts.ReactNativeContacts;

AndroidManifest.xml you have to add below lines

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

And checked your app.js file also you have done some mistakes like

You have done some error below If condition which was you have to check PermissionsAndroid.RESULTS.GRANTED not PermissionsAndroid.RESULTS.granted for both.

App.js

import React, { Component } from 'react';
import { View, StyleSheet, Button, Platform, PermissionsAndroid } 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,
  ]);
  // You have done some error below If condition 
  // which was you have to check PermissionsAndroid.RESULTS.GRANTED  not PermissionsAndroid.RESULTS.granted for both.
  if (
    granted['android.permission.READ_CONTACTS'] === PermissionsAndroid.RESULTS.GRANTED &&
    granted['android.permission.WRITE_CONTACTS'] === PermissionsAndroid.RESULTS.GRANTED
  ) {
    console.log('granted if ==>> ');
    return true
  } else {
    console.log('granted else ==>> ');
    return false
    }
  }
}
getContaxt = () => {
this.requestContactsPermission().then((didGetPermission) => {
  if (didGetPermission) {
    Contacts.getAll()
      .then(contacts => {
        console.log("Contacts ==>> ", contacts);
      })
      .catch(e => {
        console.log("e ==>> ", e);
      });
   } else {
    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;

CodePudding user response:

Hi Mobile Team iOS-RN and thanks for your replay,

I fixed the code as you explained, and i still have the same error.

// App.js

 // 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((err, Contacts) => {    ///Contacts.get
              if (err) {
                throw err;
              }
              console.warn(Contacts)
            })
          } else {
            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" />

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

// settings.gradle

rootProject.name = 'MyTest'
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
include ':app'
includeBuild('../node_modules/react-native-gradle-plugin')

include ':react-native-contacts'
project(':react-native-contacts').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-contacts/android')

if (settings.hasProperty("newArchEnabled") && settings.newArchEnabled == "true") {
    include(":ReactAndroid")
    project(":ReactAndroid").projectDir = file('../node_modules/react-native/ReactAndroid')
}

// Screenshot :

enter image description here

  • Related