Getting Contact List - App Crashes on Start

i created my first extension with the help of chat gpt for personal use and build extension from Niotron IDE but when exporting app, the app crashes on start

the extension code is

package com.contact;

import android.content.Context;
import android.database.Cursor;
import android.provider.ContactsContract;
import android.util.Log;
import com.google.appinventor.components.annotations.*;
import com.google.appinventor.components.common.ComponentCategory;
import com.google.appinventor.components.runtime.*;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@DesignerComponent(
        version = 1,
        description = "Contact List",
        category = ComponentCategory.EXTENSION,
        nonVisible = true,
        iconName = "")
@SimpleObject(external = true)
public class Contact extends AndroidNonvisibleComponent {

    public Contact(ComponentContainer container) {
        super(container.$form());
    }

    @SimpleEvent(description = "Got Contact List")
    public void GotContact(List<String> contactList) {  
        Log.d("ContactExtension", "GotContact event triggered with list size: " + contactList.size());
        EventDispatcher.dispatchEvent(this, "GotContact", contactList);  
    }

    @SimpleFunction(description = "Sort A to Z")
    public void GetContact() {  
        final Context context = this.form.$context();
        Log.d("ContactExtension", "Starting to retrieve contacts");

        new Thread(new Runnable() {
            @Override
            public void run() {
                final List<String> contactList = new ArrayList<>();
                Cursor cursor = context.getContentResolver().query(
                        ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                        new String[]{ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER},
                        null, null, null);

                if (cursor != null && cursor.getCount() > 0) {
                    Log.d("ContactExtension", "Found contacts: " + cursor.getCount());
                    HashMap<String, Set<String>> contactsMap = new HashMap<>();

                    while (cursor.moveToNext()) {
                        String contactName = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
                        String phoneNumber = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));

                        phoneNumber = phoneNumber.replaceAll("\\s+", "");

                        if (!contactsMap.containsKey(contactName)) {
                            contactsMap.put(contactName, new HashSet<String>());
                        }
                        contactsMap.get(contactName).add(phoneNumber);
                    }
                    cursor.close();

                    for (String name : contactsMap.keySet()) {
                        String numbers = String.join(" ", contactsMap.get(name));
                        contactList.add(name + " - " + numbers);
                    }

                    Collections.sort(contactList);

                    form.runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            GotContact(contactList);  
                        }
                    });
                } else {
                    Log.d("ContactExtension", "No contact found");
                }
            }
        }).start();
    }
}

can anyone fix it....

package com.contact;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.provider.ContactsContract;
import android.util.Log;

import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import com.google.appinventor.components.annotations.*;
import com.google.appinventor.components.common.ComponentCategory;
import com.google.appinventor.components.runtime.*;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@DesignerComponent(
        version = 1,
        description = "Contact List",
        category = ComponentCategory.EXTENSION,
        nonVisible = true,
        iconName = "")
@SimpleObject(external = true)
public class Contact extends AndroidNonvisibleComponent {
    private static final int REQUEST_CODE_READ_CONTACTS = 100;

    public Contact(ComponentContainer container) {
        super(container.$form());
    }

    @SimpleEvent(description = "Got Contact List")
    public void GotContact(List<String> contactList) {
        Log.d("ContactExtension", "GotContact event triggered with list size: " + contactList.size());
        EventDispatcher.dispatchEvent(this, "GotContact", contactList);
    }

    @SimpleFunction(description = "Sort A to Z")
    public void GetContact() {
        final Context context = this.form.$context();
        
        // Check for permissions
        if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
            Log.d("ContactExtension", "Permission to read contacts is not granted.");
            if (context instanceof Activity) {
                ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.READ_CONTACTS}, REQUEST_CODE_READ_CONTACTS);
            }
            return; // Stop further execution until permission is granted
        }

        Log.d("ContactExtension", "Starting to retrieve contacts");

        new Thread(new Runnable() {
            @Override
            public void run() {
                final List<String> contactList = new ArrayList<>();
                Cursor cursor = null;
                try {
                    cursor = context.getContentResolver().query(
                            ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                            new String[]{ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER},
                            null, null, null);

                    if (cursor != null && cursor.getCount() > 0) {
                        Log.d("ContactExtension", "Found contacts: " + cursor.getCount());
                        HashMap<String, Set<String>> contactsMap = new HashMap<>();

                        while (cursor.moveToNext()) {
                            String contactName = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
                            String phoneNumber = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));

                            if (phoneNumber != null) {
                                phoneNumber = phoneNumber.replaceAll("\\s+", "");
                                contactsMap.computeIfAbsent(contactName, k -> new HashSet<>()).add(phoneNumber);
                            }
                        }

                        for (String name : contactsMap.keySet()) {
                            String numbers = String.join(" ", contactsMap.get(name));
                            contactList.add(name + " - " + numbers);
                        }

                        Collections.sort(contactList);

                        // Dispatch event on the UI thread
                        form.runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                GotContact(contactList);
                            }
                        });
                    } else {
                        Log.d("ContactExtension", "No contacts found.");
                    }
                } catch (Exception e) {
                    Log.e("ContactExtension", "Error retrieving contacts: " + e.getMessage());
                } finally {
                    if (cursor != null) {
                        cursor.close();
                    }
                }
            }
        }).start();
    }
}

try this

it have java 8 functions so you can't compile it in Niotron You can use rush to compile it
i've tried this and working

1 Like

thanks, its working, it modified it for niotron ide with the help of chat gpt

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.