1

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)) {
                }
            }
        }
    }
}
8
  • @RohitArya I updated all error log. Commented Mar 28, 2016 at 7:00
  • Where have you defined insertContact method? In activity or fragment? Commented Mar 28, 2016 at 7:01
  • And also, from where are you calling insertContact method? meaning from which activity callbacks? Commented Mar 28, 2016 at 7:03
  • @RohitArya I updated a class calling insertContact method. Commented Mar 28, 2016 at 7:08
  • from where are you calling sendToServer method? it is required because I still don't find source of getting context to call getContentResolver() method. Commented Mar 28, 2016 at 7:11

1 Answer 1

3

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!

Sign up to request clarification or add additional context in comments.

8 Comments

thanks your answer. I updated my question. In other class, I am also using to call insertContact class onCreate event. I tried to add Context context but not working.
Which class is it? can you update that too... BTW if this solution has solved your problem, can you upvote and accept it?
In this class I initialization: private static Context mContext; and in onCreate event I add new line mContext = getApplicationContext();. And this working.
It will work, but its not a good idea.. If it is an activity, use activity's context not application context. Do something like this mContext = MyActivity.this;
Yes you can use it. Because AppCompactActivity eventually extends Context.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.