-1

I am trying to sync google task with my application. For this I have created a class called GTaskSyncer where I have created methods to get task details.

I want to call these methods from UI. Now for test I have created a class which extends AsyncTask in this I have called method in doInbackground.

This I have called in main activity.

Now I am getting a null pointer exception on service object in GTaskSyncer.

Main activity

public class MainActivity extends AppCompatActivity {
    GoogleAccountCredential mCredential;
    private TextView mOutputText;
    ProgressDialog mProgress;

    static final int REQUEST_ACCOUNT_PICKER = 1000;
    static final int REQUEST_AUTHORIZATION = 1001;
    static final int REQUEST_GOOGLE_PLAY_SERVICES = 1002;
    private static final String PREF_ACCOUNT_NAME = "accountName";
    private static final String[] SCOPES = { TasksScopes.TASKS };
    public com.google.api.services.tasks.Tasks mService = null;
    /**
     * Create the main activity.
     * @param savedInstanceState previously saved instance data.
     */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        LinearLayout activityLayout = new LinearLayout(this);
        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT,
                LinearLayout.LayoutParams.MATCH_PARENT);
        activityLayout.setLayoutParams(lp);
        activityLayout.setOrientation(LinearLayout.VERTICAL);
        activityLayout.setPadding(16, 16, 16, 16);

        ViewGroup.LayoutParams tlp = new ViewGroup.LayoutParams(
                ViewGroup.LayoutParams.WRAP_CONTENT,
                ViewGroup.LayoutParams.WRAP_CONTENT);

        mOutputText = new TextView(this);
        mOutputText.setLayoutParams(tlp);
        mOutputText.setPadding(16, 16, 16, 16);
        mOutputText.setVerticalScrollBarEnabled(true);
        mOutputText.setMovementMethod(new ScrollingMovementMethod());
        activityLayout.addView(mOutputText);

        mProgress = new ProgressDialog(this);
        mProgress.setMessage("Calling Google Tasks API ...");

        Button sync = new Button(this);

        sync.setText("Sync");

        setContentView(activityLayout);

        // Initialize credentials and service object.
        SharedPreferences settings = getPreferences(Context.MODE_PRIVATE);
        mCredential = GoogleAccountCredential.usingOAuth2(
                getApplicationContext(), Arrays.asList(SCOPES))
                .setBackOff(new ExponentialBackOff())
                .setSelectedAccountName(settings.getString(PREF_ACCOUNT_NAME, null));

        HttpTransport transport = AndroidHttp.newCompatibleTransport();
        JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
        mService = new com.google.api.services.tasks.Tasks.Builder(
                transport, jsonFactory, mCredential)
                .setApplicationName("Google Tasks API Android Quickstart")
                .build();
    }


    /**
     * Called whenever this activity is pushed to the foreground, such as after
     * a call to onCreate().
     */
    @Override
    protected void onResume() {
        super.onResume();
        if (isGooglePlayServicesAvailable()) {
            refreshResults();
        } else {
            mOutputText.setText("Google Play Services required: " +
                    "after installing, close and relaunch this app.");
        }
    }

    /**
     * Called when an activity launched here (specifically, AccountPicker
     * and authorization) exits, giving you the requestCode you started it with,
     * the resultCode it returned, and any additional data from it.
     * @param requestCode code indicating which activity result is incoming.
     * @param resultCode code indicating the result of the incoming
     *     activity result.
     * @param data Intent (containing result data) returned by incoming
     *     activity result.
     */
    @Override
    protected void onActivityResult(
            int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch(requestCode) {
            case REQUEST_GOOGLE_PLAY_SERVICES:
                if (resultCode != RESULT_OK) {
                    isGooglePlayServicesAvailable();
                }
                break;
            case REQUEST_ACCOUNT_PICKER:
                if (resultCode == RESULT_OK && data != null &&
                        data.getExtras() != null) {
                    String accountName =
                            data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
                    if (accountName != null) {
                        mCredential.setSelectedAccountName(accountName);
                        SharedPreferences settings =
                                getPreferences(Context.MODE_PRIVATE);
                        SharedPreferences.Editor editor = settings.edit();
                        editor.putString(PREF_ACCOUNT_NAME, accountName);
                        editor.apply();
                    }
                } else if (resultCode == RESULT_CANCELED) {
                    mOutputText.setText("Account unspecified.");
                }
                break;
            case REQUEST_AUTHORIZATION:
                if (resultCode != RESULT_OK) {
                    chooseAccount();
                }
                break;
        }

        super.onActivityResult(requestCode, resultCode, data);
    }

    /**
     * Attempt to get a set of data from the Google Tasks API to display. If the
     * email address isn't known yet, then call chooseAccount() method so the
     * user can pick an account.
     */
    private void refreshResults() {
        if (mCredential.getSelectedAccountName() == null) {
            chooseAccount();
        } else {
            if (isDeviceOnline()) {
                new TestAsyncTask(mCredential).execute();
            } else {
                mOutputText.setText("No network connection available.");
            }
        }
    }
    /**
     * Starts an activity in Google Play Services so the user can pick an
     * account.
     */
    private void chooseAccount() {
        startActivityForResult(
                mCredential.newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER);
    }

    /**
     * Checks whether the device currently has a network connection.
     * @return true if the device has a network connection, false otherwise.
     */
    private boolean isDeviceOnline() {
        ConnectivityManager connMgr =
                (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
        return (networkInfo != null && networkInfo.isConnected());
    }

    /**
     * Check that Google Play services APK is installed and up to date. Will
     * launch an error dialog for the user to update Google Play Services if
     * possible.
     * @return true if Google Play Services is available and up to
     *     date on this device; false otherwise.
     */
    private boolean isGooglePlayServicesAvailable() {
        final int connectionStatusCode =
                GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
        if (GooglePlayServicesUtil.isUserRecoverableError(connectionStatusCode)) {
            showGooglePlayServicesAvailabilityErrorDialog(connectionStatusCode);
            return false;
        } else if (connectionStatusCode != ConnectionResult.SUCCESS ) {
            return false;
        }
        return true;
    }

    /**
     * Display an error dialog showing that Google Play Services is missing
     * or out of date.
     * @param connectionStatusCode code describing the presence (or lack of)
     *     Google Play Services on this device.
     */
    void showGooglePlayServicesAvailabilityErrorDialog(
            final int connectionStatusCode) {
        Dialog dialog = GooglePlayServicesUtil.getErrorDialog(
                connectionStatusCode,
                MainActivity.this,
                REQUEST_GOOGLE_PLAY_SERVICES);
        dialog.show();
    }

}

TestAsyncTask

    public class TestAsyncTask extends AsyncTask<Void, Void, List<TaskList>>{

    private com.google.api.services.tasks.Tasks mService = null;
    private Exception mLastError = null;
    private MainActivity activity;
    private com.google.api.services.tasks.Tasks client = null;

    public TestAsyncTask(GoogleAccountCredential credential) {
        HttpTransport transport = AndroidHttp.newCompatibleTransport();
        JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
        mService = new com.google.api.services.tasks.Tasks.Builder(
                transport, jsonFactory, credential)
                .setApplicationName("Google Tasks API Android Quickstart")
                .build();

    }
    protected List<TaskList> doInBackground(Void... params) {

        GTaskSyncer gTaskSyncer = new GTaskSyncer(activity);

        List<TaskList> result = new ArrayList<>();

        try {

            result = gTaskSyncer.getAllTaskList();

        } catch (IOException e) {

            Toast.makeText(activity,"IO Exception",Toast.LENGTH_SHORT).show();
        }
        return result;
    }
}

GTaskSyncer

  public class GTaskSyncer
{

    final MainActivity activity;
    final com.google.api.services.tasks.Tasks mService;


    GTaskSyncer(MainActivity activity) {
        this.activity = activity;
        mService = activity.mService;
    }

    public List<TaskList> getAllTaskList() throws IOException
    {
        List<TaskList> result = new ArrayList<TaskList>();

        TaskLists taskLists = mService.tasklists().list().execute();

        for (TaskList taskList : taskLists.getItems()) {

                result.add(taskList);
        }

        return result;

    }


    public TaskList createList() throws IOException
    {

        TaskList taskList = new TaskList();

        taskList =  activity.mService.tasklists().insert(taskList).execute();

        return taskList;
    }

    public Task createTask(String listId) throws IOException
    {

        Task task = new Task();

        task =   activity.mService.tasks().insert(listId, task).execute();

        return  task;
    }

    public Task getTask(String listId,String taskId) throws IOException
    {

        Task task =   activity.mService.tasks().get(listId, taskId).execute();

        return task;
    }

    public List<Task> getTaskList(String listId) throws IOException
    {
        List<Task> result = new ArrayList<Task>();

        List<Task> tasks = mService.tasks().list(listId).execute().getItems();

        if (tasks != null) {

            for (Task task : tasks) {

                result.add(task);
            }
        } else {

            Toast.makeText(activity,"No tasks.",Toast.LENGTH_SHORT).show();
        }

        return result;
    }

}

Please help..

flavio.donze
  • 7,432
  • 9
  • 58
  • 91
user5881997
  • 219
  • 2
  • 19
  • Please show your log output. It may become useful to track the issue. – Ruchira Randana Mar 30 '16 at 08:27
  • 1
    Possible duplicate of [What is a Null Pointer Exception, and how do I fix it?](http://stackoverflow.com/questions/218384/what-is-a-null-pointer-exception-and-how-do-i-fix-it) – beresfordt Mar 30 '16 at 09:13

2 Answers2

1

you haven't initialized this private MainActivity activity; And you are using this to create instance of GTaskSyncer

GTaskSyncer gTaskSyncer = new GTaskSyncer(activity);

Thus it is being passed here at:

GTaskSyncer(MainActivity activity) {
    this.activity = activity; // null
    mService = activity.mService; // exception
}

And finally, you are using it at many places which is causing exception.

taskList =  activity.mService.tasklists().insert(taskList).execute();

Try to change the constructor:

public TestAsyncTask(GoogleAccountCredential credential, MainActivity activity) {
  HttpTransport transport = AndroidHttp.newCompatibleTransport();
    JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
    mService = new com.google.api.services.tasks.Tasks.Builder(
            transport, jsonFactory, credential)
            .setApplicationName("Google Tasks API Android Quickstart")
            .build();
  this.activity = activity;
}

And call it like this:

new TestAsyncTask(mCredential, MainActivity.this).execute();
Rohit Arya
  • 6,751
  • 1
  • 26
  • 40
  • Thank you.. It solved null exception. But I dint get any list of tasks. Can you help please? – user5881997 Mar 30 '16 at 08:50
  • @user5881997, if it solved null pointer exception, can you please [accept and upvote](http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work) my answer. – Rohit Arya Mar 30 '16 at 09:07
  • can you update code for getting list of tasks? – Rohit Arya Mar 30 '16 at 09:14
  • it's the same one. In GTaskSyncer method of getAllTaskLists() this I am calling in TestAsyncTask. And TestAsyncTask I am calling in main activity. But the activity is blank. I am not able to see the list. I did debug to check if the list is empty. But the list has the values. @RohitArya – user5881997 Mar 30 '16 at 09:21
0

its better to change your constructor

GTaskSyncer(MainActivity activity,com.google.api.services.tasks.Tasks mService) {
        this.activity = activity;
        this.mService = mService;
}