javaandroidreact-nativemodule

create a java native module in react native


I am trying to build a native java module , I want to make a media file (an image ) immediately available in the gallery , so I read somewhere that I can use the MediaScannerConnection API in Android. The native Android API, and use it in React Native so here how I made it but i fires an error saying :

error: constructor MediaScannerPackage in class MediaScannerPackage cannot be applied to given types; modules.add(new MediaScannerPackage(reactContext));

here is my code :

MediaScannerPackage.java 
package com.myApp;

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

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class MediaScannerPackage implements ReactPackage {
    @Override
    public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
        return Collections.emptyList();
    }

    @Override
    public List<NativeModule> createNativeModules(
            ReactApplicationContext reactContext) {
        List<NativeModule> modules = new ArrayList<>();

        modules.add(new MediaScannerPackage(reactContext));

        return modules;
    }
}

MediaScannerModule.java

package com.myApp;

import android.content.Context;
import android.media.MediaScannerConnection;
import android.net.Uri;

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;

import java.io.File;

public class MediaScannerModule extends ReactContextBaseJavaModule {

    public MediaScannerModule(ReactApplicationContext reactContext) {
        super(reactContext);
    }

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

    @ReactMethod
    public void scanFile(String path) {
        Context context = getReactApplicationContext();

        // Check if the file exists
        File file = new File(path);
        if (!file.exists()) {
            // Notify React Native about the error
            sendEvent("SCAN_FILE_ERROR", "File not found: " + path);
            return;
        }

        // Use MediaScannerConnection to scan the file
        MediaScannerConnection.scanFile(
                context,
                new String[]{path},
                null,
                new MediaScannerConnection.OnScanCompletedListener() {
                    @Override
                    public void onScanCompleted(String path, Uri uri) {
                        // Scanning completed, notify React Native
                        if (uri != null) {
                            sendEvent("SCAN_FILE_SUCCESS", uri.toString());
                        } else {
                            sendEvent("SCAN_FILE_ERROR", "Scan completed, but URI is null");
                        }
                    }
                }
        );
    }

    // Helper method to send events to React Native
    private void sendEvent(String eventName, String message) {
        getReactApplicationContext()
                .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
                .emit(eventName, message);
    }
}

from MainApplication.java

...
import com.imagewatermarks.MediaScannerPackage;
....
    @Override
        protected List<ReactPackage> getPackages() {
          @SuppressWarnings("UnnecessaryLocalVariable")
          List<ReactPackage> packages = new PackageList(this).getPackages();
            packages.add(MediaScannerPackage());
         
          return packages;
        }

Solution

  • Add the module instead of the package.

    modules.add(new MediaScannerModule(reactContext));
    

    See Register the Module for details.