2016-04-26 4 views
1

Hey Ich habe ein Problem mit Gcm Intent-Service beim Aufruf von `subscribeToTopicP Klasse, die immer null Zeiger Ausnahme.Gcm Intent Service bekomme Null Zeiger Ausnahme bei Gcm Pubsub

Hier ist mein Code:

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(); 
    } 
} 

Mein LogCat Fehler:

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; 
} 

Und hier meine 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); 
} 

Antwort

2

Dieses Problem ist durch variable nicht instanziert werden. Sie verwenden die Aktivität als Context zu früh. Sie müssen warten bis onCreate() oder später in der activity lifecycle. Sie können getApplicationContext() nicht aufrufen, bis nach onCreate() aufgerufen wird. Die Aktivität wird erst dann vollständig initialisiert.

+0

ja du hast Recht. Danke für deine Antwort. @ d.datul1990 –

+0

keine Sorgen Kumpel! –