Ave
Ave

Reputation: 4430

FATAL EXCEPTION: Thread-128 java.lang.NullPointerException

Today I build new app to add contact, but I have error in log cat like this:

threadid=11: thread exiting with uncaught exception (group=0xa4ca6b20)

FATAL EXCEPTION: Thread-128

Process: kr.co.composer.callrecord, PID: 5275 java.lang.NullPointerException

at android.content.ContextWrapper.getContentResolver(ContextWrapper.java:99)

at kr.co.composer.callrecord.page.AddContactActivity.insertContact(AddContactActivity.java:116)

at kr.co.composer.callrecord.callbroadcast.CallBroadcast$1.run(CallBroadcast.java:110)

at java.lang.Thread.run(Thread.java:841)

I think problem in line in class insertContact:

ContentResolver contentResolver = this.getContentResolver();

Check all more code, this class I extends from AppCompatActivity:

public boolean insertContact(String firstName, String mobileNumber, String addressCall, String timeStart, String currentDate) {
    ContentResolver contentResolver = this.getContentResolver();
    ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();

    ops.add(ContentProviderOperation
            .newInsert(ContactsContract.RawContacts.CONTENT_URI)
            .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, null)
            .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null)
            .build());
    ops.add(ContentProviderOperation
            .newInsert(ContactsContract.Data.CONTENT_URI)
            .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
            .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
            .withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, firstName + " " + timeStart + " " + currentDate).build());
    ops.add(ContentProviderOperation
            .newInsert(ContactsContract.Data.CONTENT_URI)
            .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
            .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
            .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, mobileNumber)
            .withValue(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE).build());
    ops.add(ContentProviderOperation
            .newInsert(ContactsContract.Data.CONTENT_URI)
            .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID,
                    0)
            .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE )
            .withValue(ContactsContract.CommonDataKinds.StructuredPostal.STREET, addressCall).build());
    try {
        contentResolver.applyBatch(ContactsContract.AUTHORITY, ops);
    } catch (Exception e) {
        return false;
    }
    return true;
}

After all, in CallBroadcast I have called this class with all parameter's (I insert values not null).

InputStream answerInputStream = connection.getInputStream();
final String answer = getTextFromInputStream(answerInputStream);

if(answer!="") {
    String[] contactInfo = answer.split(":::::");

    contact.insertContact(contactInfo[0], contactInfo[1], contactInfo[2], contactInfo[3], contactInfo[4]);
}

Values of answer is:

Alisan:::::".$text.":::::10p.m at Yusski street:::::25/03/2015:::::28/03/2015

In class CallBroadcast extends BroadcastReceiver I calling insertContact method. You can see more code at bellow:

public class CallBroadcast extends BroadcastReceiver {
    public void sendToServer(final String text){
        contact = new AddContactActivity();
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {

                    String textparam = "text1=" + URLEncoder.encode(text, "UTF-8");

                    URL scripturl = new URL(scripturlstring);
                    HttpURLConnection connection = (HttpURLConnection) scripturl.openConnection();
                    connection.setDoOutput(true);
                    connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
                    connection.setFixedLengthStreamingMode(textparam.getBytes().length);
                    OutputStreamWriter contentWriter = new OutputStreamWriter(connection.getOutputStream());
                    contentWriter.write(textparam);
                    contentWriter.flush();
                    contentWriter.close();

                    InputStream answerInputStream = connection.getInputStream();
                    final String answer = getTextFromInputStream(answerInputStream);

                    if(answer!="") {
                        String[] contactInfo = answer.split(":::::");

                        contact.insertContact(contactInfo[0], contactInfo[1], contactInfo[2], contactInfo[3], contactInfo[4]);
                    }
                    answerInputStream.close();
                    connection.disconnect();


                } catch (MalformedURLException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();

    }
}

@Override
public void onReceive(final Context context, final Intent intent) {
    callState = 0;
    callInfoPreferenceManager = CallInfoPreferenceManager.getInstance();
    configPreferenceManager = ConfigPreferenceManager.getInstance();

    TelephonyManager telManager = (TelephonyManager) context
            .getSystemService(Context.TELEPHONY_SERVICE);
    if (configPreferenceManager.getAutoRecord()) {
        if (intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)) {
            String textToServer = callInfoPreferenceManager.getPhoneNumber();
            sendToServer(textToServer.toString());
            Log.i("Gọi đến đã gửi->server:", textToServer.toString());
            callInfoPreferenceManager.setPhoneNumber(intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER));
            callInfoPreferenceManager.setMyPhone(number);
            callInfoPreferenceManager.setSending(String.valueOf(true));
        }
    }
    telManager.listen(new PhoneStateListener() {
        @Override
        public void onCallStateChanged(int state, String incomingNumber) {
            callDAO = new CallDAO(context);
            if (configPreferenceManager.getAutoRecord()) {
                if (state != pState) {
                    if (state == TelephonyManager.CALL_STATE_OFFHOOK && callInfoPreferenceManager.getCallState()) {
                        uri = Uri.withAppendedPath(
                                ContactsContract.PhoneLookup.CONTENT_FILTER_URI,
                                Uri.encode(callInfoPreferenceManager.getPhoneNumber()));
                        projection = new String[]{ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME
                                , ContactsContract.Contacts.PHOTO_ID
                        };

                        // Query the filter URI
                        Cursor cursor = context.getContentResolver().query(uri,
                                projection, null, null, null);
                        if (cursor != null) {
                            if (cursor.moveToFirst()) {
                                callInfoPreferenceManager.setName(cursor.getString(cursor.getColumnIndex
                                        (ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)));
                                int id = cursor.getInt(cursor.getColumnIndex(ContactsContract.Contacts.PHOTO_ID));
                                if (id != 0) {
                                    callInfoPreferenceManager.setPhotoId(id);
                                } else {
                                    callInfoPreferenceManager.setPhotoId(1);
                                }
                            } else {
                                callInfoPreferenceManager.setPhotoId(1);
                                callInfoPreferenceManager.setName("Số lạ");
                            }
                        }
                        cursor.close();

                        callInfoPreferenceManager.setCallState(CALLING);
                        callInfoPreferenceManager.setStartDate(DateFormat.format(
                                CallFormatter.START_DATE_FORMAT,
                                System.currentTimeMillis()).toString());

                        callInfoPreferenceManager.setStartTime(System
                                .currentTimeMillis());
                        try {
                            Thread.sleep(1000);                 //1000 milliseconds is one second.
                        } catch(InterruptedException ex) {
                            Thread.currentThread().interrupt();
                        }
                        sIntent = new Intent(context.getApplicationContext(),
                                CallRecordService.class);
                        context.startService(sIntent);

                    } else if (state == TelephonyManager.CALL_STATE_RINGING && callInfoPreferenceManager.getCallState()) {
                        callInfoPreferenceManager.setPhoneNumber(incomingNumber);
                        String textToServer = callInfoPreferenceManager.getPhoneNumber();
                        sendToServer(textToServer.toString());
                        callInfoPreferenceManager.setSending(String.valueOf(false));

                    } else if (state == TelephonyManager.CALL_STATE_IDLE && callInfoPreferenceManager.getCallState() == CALLING) {
                        long endTime = System.currentTimeMillis();
                        long startTime = callInfoPreferenceManager.getStartTime();
                        long callTime = endTime - startTime;
                        String totalTime = new SimpleDateFormat(
                                CallFormatter.TIME_FORMAT).format(new Date(
                                callTime - 32400000));
                        callDAO.insert(callInfoPreferenceManager.getName(),
                                callInfoPreferenceManager.getPhoneNumber(),
                                callInfoPreferenceManager.getStartDate(),
                                totalTime,
                                callInfoPreferenceManager.getSending(),
                                callInfoPreferenceManager.getPhotoId(),
                                callInfoPreferenceManager.getStartDate()
                                        + configPreferenceManager.getPathFormat());
                        callDAO.close();

                        sIntent = new Intent(context.getApplicationContext(),
                                CallRecordService.class);
                        context.stopService(sIntent);

                        callInfoPreferenceManager.setCallState(IDLE);
                        try {
                            Thread.sleep(1000);                 //1000 milliseconds is one second.
                        } catch(InterruptedException ex) {
                            Thread.currentThread().interrupt();
                        }
                    } else if (state == TelephonyManager.CALL_STATE_RINGING &&
                            callInfoPreferenceManager.getCallState() == CALLING) {
                        callState = REFUSE;
                    } else if (state == TelephonyManager.CALL_STATE_OFFHOOK && callInfoPreferenceManager.getCallState()
                            == CALLING) {
                        callState = ACCEPT;
                    } else if (state == TelephonyManager.CALL_STATE_IDLE && callState == REFUSE) {
                        callInfoPreferenceManager.setCallState(IDLE);
                    }
                    pState = state;
                }
            }
        }
    }, PhoneStateListener.LISTEN_CALL_STATE);
}//onReceive

I checked your answer, but when to editing my code, one class also calling insertContact, I tried to add onCreate(Context context, Bundle savedInstanceState) but can't using the pass with parameters Context context. And this code at:

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_add_contact);

        addContactBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (insertContact(name, number, address, timeStart, timeCurrrentDate)) {
                }
            }
        }
    }
}

Upvotes: 1

Views: 1775

Answers (1)

Rohit Arya
Rohit Arya

Reputation: 6791

getContentResolver() is method of class android.content.Context, so it definitely needs an instance of Context (like Activity or Service). And this is the cause of crash.

You are calling

ContentResolver contentResolver = this.getContentResolver();

And here this should be instance of subclasses of Context. If you are already calling this from activity then make sure it is being called after onCreate method of activity because by that time activity class doesn't have context.

EDIT 1:

Since you are using Broadcast Receiver you should pass context received here in:

onReceive (Context context, Intent intent){}

Change signature of sentToServer method like this public void sendToServer( Context context, final String text) and call from onReceive passing the context.

@Override
public void onReceive (Context context, Intent intent){
     sendToServer(context, "some text")
}

And similarly, change signature of insertContact method public boolean insertContact(Context context, String firstName, String mobileNumber, String addressCall, String timeStart, String currentDate)

And get ContentResolver like this:

ContentResolver contentResolver = context.getContentResolver();

Hope this helps you out!

Upvotes: 3

Related Questions