2016-04-26 24 views
1

ちょっと、私は `subscribeToTopicPクラスを呼び出す際にGcmインテントサービスに問題があります。ここで GcmインテントサービスはGcm pubsubでヌルポインタ例外を受け取ります

は私のコードです:

GcmIntentService.java

private static final String TAG = GcmIntentService.class.getSimpleName(); 

public GcmIntentService() { 
    super(TAG); 
} 

public static final String KEY = "key"; 
public static final String TOPIC = "topic"; 
public static final String SUBSCRIBE = "subscribe"; 
public static final String UNSUBSCRIBE = "unsubscribe"; 
public SessionManager session; 


@Override 
protected void onHandleIntent(Intent intent) { 
    session = new SessionManager(getApplicationContext()); 
    String key = intent.getStringExtra(KEY); 
    switch (key) { 
     case SUBSCRIBE: 
      // subscribe to a topic 
      String topic = intent.getStringExtra(TOPIC); 
      subscribeToTopic(topic); 
      break; 
     case UNSUBSCRIBE: 
      break; 
     default: 
      // if key is specified, register with GCM 
      registerGCM(); 
    } 

} 

/** 
* Registering with GCM and obtaining the gcm registration id 
*/ 
private void registerGCM() { 
    SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); 

    try { 
     InstanceID instanceID = InstanceID.getInstance(this); 
     String token = instanceID.getToken(getString(R.string.gcm_defaultSenderId), 
       GoogleCloudMessaging.INSTANCE_ID_SCOPE, null); 

     Log.e(TAG, "GCM Registration Token: " + token); 

     // sending the registration id to our server 
     sendRegistrationToServer(token); 

     sharedPreferences.edit().putBoolean(Config.SENT_TOKEN_TO_SERVER, true).apply(); 
    } catch (Exception e) { 
     Log.e(TAG, "Failed to complete token refresh", e); 

     sharedPreferences.edit().putBoolean(Config.SENT_TOKEN_TO_SERVER, false).apply(); 
    } 
    // Notify UI that registration has completed, so the progress indicator can be hidden. 
    Intent registrationComplete = new Intent(Config.REGISTRATION_COMPLETE); 
    LocalBroadcastManager.getInstance(this).sendBroadcast(registrationComplete); 
} 

private void sendRegistrationToServer(final String token) { 

    // checking for valid login session 
    session.isLoggedIn(); 
    HashMap<String, String> user = session.getUserDetails(); 
    String UserId = user.get(SessionManager.KEY_ID); 

    String endPoint = EndPoints.UPDATE_USER_GCM.replace("_ID_", UserId); 

    Log.e(TAG, "endpoint: " + endPoint); 

    StringRequest strReq = new StringRequest(Request.Method.PUT, endPoint, new Response.Listener<String>() { 

     @Override 
     public void onResponse(String response) { 
      Log.e(TAG, "response: " + response); 

      try { 
       JSONObject obj = new JSONObject(response); 

       // check for error 
       if (obj.getBoolean("error") == false) { 
        // broadcasting token sent to server 
        Intent registrationComplete = new Intent(Config.SENT_TOKEN_TO_SERVER); 
        LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(registrationComplete); 
       } else { 
        Toast.makeText(getApplicationContext(), "Unable to send gcm registration id to our sever. " + obj.getJSONObject("error").getString("message"), Toast.LENGTH_LONG).show(); 
       } 

      } catch (JSONException e) { 
       Log.e(TAG, "json parsing error: " + e.getMessage()); 
       Toast.makeText(getApplicationContext(), "Json parse error: " + e.getMessage(), Toast.LENGTH_SHORT).show(); 
      } 
     } 
    }, new Response.ErrorListener() { 

     @Override 
     public void onErrorResponse(VolleyError error) { 
      NetworkResponse networkResponse = error.networkResponse; 
      Log.e(TAG, "Volley error: " + error.getMessage() + ", code: " + networkResponse); 
      Toast.makeText(getApplicationContext(), "Volley error: " + error.getMessage(), Toast.LENGTH_SHORT).show(); 
     } 
    }) { 
     @Override 
     protected Map<String, String> getParams() { 
      Map<String, String> params = new HashMap<String, String>(); 
      params.put("UserGcmRegistrationId", token); 

      Log.e(TAG, "params: " + params.toString()); 
      return params; 
     } 
    }; 

    //Adding request to request queue 
    Volley.newRequestQueue(getApplicationContext()).add(strReq); 
} 

/** 
* Subscribe to a topic 
*/ 
public static void subscribeToTopic(String topic) { 
    GcmPubSub pubSub = GcmPubSub.getInstance(MyApplication.getInstance().getApplicationContext()); 
    InstanceID instanceID = InstanceID.getInstance(MyApplication.getInstance().getApplicationContext()); 
    String token = null; 
    try { 
     token = instanceID.getToken(MyApplication.getInstance().getApplicationContext().getString(R.string.gcm_defaultSenderId), 
       GoogleCloudMessaging.INSTANCE_ID_SCOPE, null); 
     if (token != null) { 
      pubSub.subscribe(token, "/topics/" + topic, null); 
      Log.e(TAG, "Subscribed to topic: " + topic); 
     } else { 
      Log.e(TAG, "error: gcm registration id is null"); 
     } 
    } catch (IOException e) { 
     Log.e(TAG, "Topic subscribe error. Topic: " + topic + ", error: " + e.getMessage()); 
     Toast.makeText(MyApplication.getInstance().getApplicationContext(), "Topic subscribe error. Topic: " + topic + ", error: " + e.getMessage(), Toast.LENGTH_SHORT).show(); 
    } 
} 

public void unsubscribeFromTopic(String topic) { 
    GcmPubSub pubSub = GcmPubSub.getInstance(getApplicationContext()); 
    InstanceID instanceID = InstanceID.getInstance(getApplicationContext()); 
    String token = null; 
    try { 
     token = instanceID.getToken(getString(R.string.gcm_defaultSenderId), 
       GoogleCloudMessaging.INSTANCE_ID_SCOPE, null); 
     if (token != null) { 
      pubSub.unsubscribe(token, ""); 
      Log.e(TAG, "Unsubscribed from topic: " + topic); 
     } else { 
      Log.e(TAG, "error: gcm registration id is null"); 
     } 
    } catch (IOException e) { 
     Log.e(TAG, "Topic unsubscribe error. Topic: " + topic + ", error: " + e.getMessage()); 
     Toast.makeText(getApplicationContext(), "Topic subscribe error. Topic: " + topic + ", error: " + e.getMessage(), Toast.LENGTH_SHORT).show(); 
    } 
} 

マイLogCatエラー:

E/AndroidRuntime: FATAL EXCEPTION: IntentService[GcmIntentService] 

Process: com.nvitek.www.aspirasirakyat, PID: 25962 
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.content.Context.getApplicationContext()' on a null object reference 
at android.content.ContextWrapper.getApplicationContext(ContextWrapper.java:107) 
at com.nvitek.www.aspirasirakyat.gcm.GcmIntentService.subscribeToTopic(GcmIntentService.java:155) 
at com.nvitek.www.aspirasirakyat.gcm.GcmIntentService.onHandleIntent(GcmIntentService.java:56) 
at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:66) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:148) 
at android.os.HandlerThread.run(HandlerThread.java:61) 

MyApplication.java

public static final String TAG = MyApplication.class.getSimpleName(); 
private RequestQueue mRequestQueue; 
private static MyApplication mInstance; 
private SessionManager pref; 

@Override 
public void onCreate() { 
    super.onCreate(); 
    mInstance = this; 
} 

public static synchronized MyApplication getInstance() { 
    if(mInstance==null) 
    { 
     mInstance=new MyApplication(); 
    } 
    return mInstance; 
} 

public RequestQueue getRequestQueue() { 
    if (mRequestQueue == null) { 
     mRequestQueue = Volley.newRequestQueue(getApplicationContext()); 
    } 

    return mRequestQueue; 
} 

public SessionManager getPrefManager() { 
    if (pref == null) { 
     pref = new SessionManager(this); 
    } 

    return pref; 
} 

そして、ここで私のActivityDashboard.java

//JSON TAGS 
public static final String TAG_IMAGE_URL = "image"; 
public static final String TAG_TITLE = "title"; 
public static final String TAG_FNAME = "fname"; 
public static final String TAG_LNAME = "lname"; 
public static final String TAG_CONTENT = "content"; 
public static final String TAG_DATE = "date"; 
public static final String TAG_ID = "id"; 

private String TAG = ActivityDashboard.class.getSimpleName(); 
private static final int PLAY_SERVICES_RESOLUTION_REQUEST = 9000; 
private BroadcastReceiver mRegistrationBroadcastReceiver; 

private List<ListItem> listItems; 

//Creating Views 
private RecyclerView recyclerView; 
private RecyclerView.LayoutManager layoutManager; 
private RecyclerView.Adapter adapter; 

//Volley Request Queue 
private RequestQueue requestQueue; 

private Boolean exit = false; 
SessionManager session; 
JSONArray users = null; 
DrawerLayout drawerLayout; 
NavigationView mNavigationView; 

private GoogleApiClient client; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_dashboard); 

    session = new SessionManager(getApplicationContext()); 

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
    setSupportActionBar(toolbar); 
    toolbar.setNavigationIcon(R.drawable.ic_menu_white); 

    drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); 
    mNavigationView = (NavigationView) findViewById(R.id.navigation); 
    mNavigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() { 

     @Override 
     public boolean onNavigationItemSelected(MenuItem menuItem) { 
      menuItem.setChecked(true); 
      Intent intent; 
      switch (menuItem.getItemId()) { 
       case R.id.navigation_item_1: 
        intent = new Intent(ActivityDashboard.this, ActivityDashboard.class); 
        startActivity(intent); 
        return true; 

       /* case R.id.navigation_item_2: 
        intent = new Intent(ActivityDashboard.this, ActivityDashboard.class); 
        startActivity(intent); 
        return true; */ 

       case R.id.navigation_item_3: 
        intent = new Intent(ActivityDashboard.this, ActivityStatistic.class); 
        startActivity(intent); 
        return true; 

       case R.id.navigation_item_4: 
        intent = new Intent(ActivityDashboard.this, ActivityProfile.class); 
        startActivity(intent); 
        return true; 

       case R.id.navigation_item_5: 
        session.logoutUser(); 
        return true; 

       default: 
        return true; 
      } 
     } 

    }); 

    FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); 
    fab.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      Snackbar.make(view, "Loading...", Snackbar.LENGTH_LONG) 
        .setAction("Action", null).show(); 
      gotoAdd(view); 
     } 
    }); 

    mRegistrationBroadcastReceiver = new BroadcastReceiver() { 
     @Override 
     public void onReceive(Context context, Intent intent) { 

      // checking for type intent filter 
      if (intent.getAction().equals(Config.REGISTRATION_COMPLETE)) { 
       // gcm successfully registered 
       // now subscribe to `global` topic to receive app wide notifications 
       subscribeToGlobalTopic(); 

      } else if (intent.getAction().equals(Config.SENT_TOKEN_TO_SERVER)) { 
       // gcm registration id is stored in our server's MySQL 
       Log.e(TAG, "GCM registration id is sent to our server"); 

      } else if (intent.getAction().equals(Config.PUSH_NOTIFICATION)) { 
       // new push notification is received 
       handlePushNotification(intent); 
      } 
     } 
    }; 
} 


@Override 
public void onStart() { 
    super.onStart(); 

    //Initializing Views 
    recyclerView = (RecyclerView) findViewById(R.id.recyclerView); 
    recyclerView.setHasFixedSize(true); 
    layoutManager = new LinearLayoutManager(this); 
    recyclerView.setLayoutManager(layoutManager); 

    recyclerView.addOnItemTouchListener(new RecyclerTouchListener(ActivityDashboard.this, recyclerView, new ClickListener() { 
     @Override 
     public void onListClick(View v, int position) { 

      Intent intent = new Intent(ActivityDashboard.this, ActivityPreviewPost.class); 
      intent.putExtra("Url_Key", EndPoints.COMMENTS + "?id=" + listItems.get(position).getId()); 
      intent.putExtra("Id_Key", listItems.get(position).getId()); 
      intent.putExtra("Photo_Key", listItems.get(position).getImageUrl()); 
      intent.putExtra("Title_Key", listItems.get(position).getTitle()); 
      intent.putExtra("FName_Key", listItems.get(position).getFName()); 
      intent.putExtra("LName_Key", listItems.get(position).getLName()); 
      intent.putExtra("Date_Key", listItems.get(position).getDate()); 
      intent.putExtra("Content_Key", listItems.get(position).getContent()); 
      startActivity(intent); 
     } 

     @Override 
     public void onListLongClick(View v, int position) { 

     } 
    })); 

    //Initializing our list 
    listItems = new ArrayList<>(); 
    requestQueue = Volley.newRequestQueue(this); 

    //Calling method to get data to fetch data 
    if (checkPlayServices()) { 
     registerGCM(); 
     getData(); 
    } 

    //initializing our adapter 
    adapter = new CardAdapter(listItems, this); 

    //Adding adapter to recyclerview 
    recyclerView.setAdapter(adapter); 
} 

/** 
* Handles new push notification 
*/ 
private void handlePushNotification(Intent intent) { 
    int type = intent.getIntExtra("type", -1); 

    // if the push is of chat room message 
    // simply update the UI unread messages count 
    if (type == Config.PUSH_TYPE_CHATROOM) { 
     ListComment listComment = (ListComment) intent.getSerializableExtra("CommentContent"); 
     String chatRoomId = intent.getStringExtra("TimelineId"); 

     if (listComment != null && chatRoomId != null) { 
      updateRow(chatRoomId, listComment); 
     } 
    } else if (type == Config.PUSH_TYPE_USER) { 
     // push belongs to user alone 
     // just showing the message in a toast 
     ListComment listComment = (ListComment) intent.getSerializableExtra("CommentContent"); 
     Toast.makeText(getApplicationContext(), "New push: " + listComment.getCommentContent(), Toast.LENGTH_LONG).show(); 
    } 
} 

private void updateRow(String chatRoomId, ListComment listComment) { 
    for (ListItem cr : listItems) { 
     if (cr.getId().equals(chatRoomId)) { 
      int index = listItems.indexOf(cr); 
      cr.setLastMessage(listComment.getCommentContent()); 
      cr.setUnreadCount(cr.getUnreadCount() + 1); 
      listItems.remove(index); 
      listItems.add(index, cr); 
      break; 
     } 
    } 
    adapter.notifyDataSetChanged(); 
} 

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    switch (item.getItemId()) { 
     case android.R.id.home: 
      drawerLayout.openDrawer(GravityCompat.START); 
      return true; 
    } 
    return super.onOptionsItemSelected(item); 
} 

private JsonArrayRequest getDataFromServer() { 
    //JsonArrayRequest of volley 
    JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(EndPoints.TIMELINES, 
      new Response.Listener<JSONArray>() { 
       @Override 
       public void onResponse(JSONArray response) { 
        //Calling method parseData to parse the json response 
        parseData(response); 
       } 
      }, 
      new Response.ErrorListener() { 
       @Override 
       public void onErrorResponse(VolleyError error) { 
        Toast.makeText(ActivityDashboard.this, "No More Items Available", Toast.LENGTH_SHORT).show(); 
       } 
      }); 

    return jsonArrayRequest; 
} 

//This method will get data from the web api 
private void getData() { 
    //Adding the method to the queue by calling the method getDataFromServer 
    requestQueue.add(getDataFromServer()); 
} 

//This method will parse json data 
private void parseData(JSONArray array) { 
    for (int i = 0; i < array.length(); i++) { 
     //Creating the superhero object 
     ListItem listItem = new ListItem(); 
     JSONObject json = null; 
     try { 
      //Getting json 
      json = array.getJSONObject(i); 

      //Adding data to the superhero object 
      listItem.setId(json.getString(TAG_ID)); 
      listItem.setImageUrl(json.getString(TAG_IMAGE_URL)); 
      listItem.setTitle(json.getString(TAG_TITLE)); 
      listItem.setFName(json.getString(TAG_FNAME)); 
      listItem.setLName(json.getString(TAG_LNAME)); 
      listItem.setContent(json.getString(TAG_CONTENT)); 
      listItem.setDate(json.getString(TAG_DATE)); 
     } catch (JSONException e) { 
      e.printStackTrace(); 
     } 
     //Adding the superhero object to the list 
     listItems.add(listItem); 
    } 

    //Notifying the adapter that data has been added or changed 
    adapter.notifyDataSetChanged(); 
    subscribeToAllTopics(); 
} 

class RecyclerTouchListener implements RecyclerView.OnItemTouchListener{ 
    private GestureDetector mGestureDetector; 
    private ClickListener mClickListener; 


    public RecyclerTouchListener(final Context context, final RecyclerView recyclerView, final ClickListener clickListener) { 
     this.mClickListener = clickListener; 
     mGestureDetector = new GestureDetector(context,new GestureDetector.SimpleOnGestureListener(){ 
      @Override 
      public boolean onSingleTapUp(MotionEvent e) { 
       return true; 
      } 

      @Override 
      public void onLongPress(MotionEvent e) { 
       View child = recyclerView.findChildViewUnder(e.getX(),e.getY()); 
       if (child!=null && clickListener!=null){ 
        clickListener.onListLongClick(child, recyclerView.getChildAdapterPosition(child)); 
       } 
       super.onLongPress(e); 
      } 
     }); 
    } 

    @Override 
    public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) { 
     View child = rv.findChildViewUnder(e.getX(), e.getY()); 
     if (child!=null && mClickListener!=null && mGestureDetector.onTouchEvent(e)){ 
      mClickListener.onListClick(child, rv.getChildAdapterPosition(child)); 
     } 
     return false; 
    } 

    @Override 
    public void onTouchEvent(RecyclerView rv, MotionEvent e) { 

    } 

    @Override 
    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) { 

    } 
} 

public void gotoAdd(View view) { 
    Intent intent = new Intent(this, ActivityAddPost.class); 
    Log.e("aspirasi", "change activity"); 
    startActivity(intent); 
} 


// subscribing to global topic 
private void subscribeToGlobalTopic() { 
    Intent intent = new Intent(this, GcmIntentService.class); 
    intent.putExtra(GcmIntentService.KEY, GcmIntentService.SUBSCRIBE); 
    intent.putExtra(GcmIntentService.TOPIC, Config.TOPIC_GLOBAL); 
    startService(intent); 
} 

// Subscribing to all chat room topics 
// each topic name starts with `topic_` followed by the ID of the chat room 
// Ex: topic_1, topic_2 
private void subscribeToAllTopics() { 
    for (ListItem cr : listItems) { 

     Intent intent = new Intent(this, GcmIntentService.class); 
     intent.putExtra(GcmIntentService.KEY, GcmIntentService.SUBSCRIBE); 
     intent.putExtra(GcmIntentService.TOPIC, "topic_" + cr.getId()); 
     startService(intent); 
    } 
} 

@Override 
protected void onResume() { 
    super.onResume(); 

    // register GCM registration complete receiver 
    LocalBroadcastManager.getInstance(this).registerReceiver(mRegistrationBroadcastReceiver, 
      new IntentFilter(Config.REGISTRATION_COMPLETE)); 

    // register new push message receiver 
    // by doing this, the activity will be notified each time a new message arrives 
    LocalBroadcastManager.getInstance(this).registerReceiver(mRegistrationBroadcastReceiver, 
      new IntentFilter(Config.PUSH_NOTIFICATION)); 
} 

@Override 
protected void onPause() { 
    LocalBroadcastManager.getInstance(this).unregisterReceiver(mRegistrationBroadcastReceiver); 
    super.onPause(); 
} 

// starting the service to register with GCM 
private void registerGCM() { 
    Intent intent = new Intent(this, GcmIntentService.class); 
    intent.putExtra("key", "register"); 
    startService(intent); 
} 

private boolean checkPlayServices() { 
    GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance(); 
    int resultCode = apiAvailability.isGooglePlayServicesAvailable(this); 
    if (resultCode != ConnectionResult.SUCCESS) { 
     if (apiAvailability.isUserResolvableError(resultCode)) { 
      apiAvailability.getErrorDialog(this, resultCode, PLAY_SERVICES_RESOLUTION_REQUEST) 
        .show(); 
     } else { 
      Log.i(TAG, "This device is not supported. Google Play Services not installed!"); 
      Toast.makeText(getApplicationContext(), "This device is not supported. Google Play Services not installed!", Toast.LENGTH_LONG).show(); 
      finish(); 
     } 
     return false; 
    } 
    return true; 
} 

@Override 
public void onStop() { 
    super.onStop(); 
} 

public static interface ClickListener{ 
    public void onListClick(View v, int position); 
    public void onListLongClick(View v, int position); 
} 

@Override 
public void onBackPressed() { 
    if (exit) { 
     finish(); // finish activity 
    } else { 
     Toast.makeText(this, "Press Back again to Exit.", Toast.LENGTH_SHORT).show(); 
     exit = true; 
     new Handler().postDelayed(new Runnable() { 
      @Override 
      public void run() { 
       exit = false; 
      } 
     }, 3 * 1000); 
    } 
} 

// Before 2.0 
@Override 
public boolean onKeyUp(int keyCode, KeyEvent event) { 
    if (keyCode == KeyEvent.KEYCODE_BACK) { 
     if (exit) { 
      finish(); // finish activity 
     } else { 
      Toast.makeText(this, "Press Back again to Exit.", Toast.LENGTH_SHORT).show(); 
      exit = true; 
      new Handler().postDelayed(new Runnable() { 
       @Override 
       public void run() { 
        exit = false; 
       } 
      }, 3 * 1000); 
     } 
     return true; 
    } 
    return super.onKeyUp(keyCode, event); 
} 

答えて

2

この問題は、変数、インスタンス化されていないためです。アクティビティをContextとして早期に使用しています。 onCreate()以降がactivity lifecycleになるまで待つ必要があります。 onCreate()が呼び出されるまで、getApplicationContext()に電話をかけることはできません。それまでActivityは完全に初期化されていません。

+0

はい、そうです。ご回答有難うございます。 @ d.datul1990 –

+0

心配なし! –

関連する問題