2015-08-19 15 views
3

我想從其他類(PhoneStateReceiver)調用MainActivity的方法display_notification。從其他類(它擴展廣播接收器)調用MainActivity方法

但得到這個錯誤:

java.lang.RuntimeException: Unable to start receiver com.weekendproject.roshu.spamblocker.PhoneStateReceiver: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference

錯誤是專門指出,這條線在MainActivity

意向resultIntent =新意圖(getApplicationContext(),MainActivity.class);

但是我試圖改變getApplicationContext()"this""getActivity()",但其沒有工作

這裏是完整代碼

MainActivity.java

public class MainActivity extends ActionBarActivity { 

    public void display_notification(String incoming_number) { 

    NotificationCompat.Builder mBuilder = 
      new NotificationCompat.Builder(getApplicationContext()) 
        .setSmallIcon(R.drawable.ic_action) 
        .setContentTitle("SpamBlocker alert !!") 
        .setContentText("SpamBlocker blocked number : " + incoming_number); 

    // **Error occured in following line** 
    Intent resultIntent = new Intent(getApplicationContext(), MainActivity.class); 

    TaskStackBuilder stackBuilder = TaskStackBuilder.create(getApplicationContext()); 
    stackBuilder.addParentStack(MainActivity.class); 
    stackBuilder.addNextIntent(resultIntent); 
    PendingIntent resultPendingIntent = 
      stackBuilder.getPendingIntent(
        0, 
        PendingIntent.FLAG_UPDATE_CURRENT 
      ); 
    mBuilder.setContentIntent(resultPendingIntent); 
    NotificationManager mNotificationManager = 
      (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); 
    Random r = new Random(); 
    int rand = r.nextInt(1000); 
    mNotificationManager.notify(rand, mBuilder.build()); 
    } 
} 

PhoneStateReceiver。 java

public class PhoneStateReceiver extends BroadcastReceiver { 

    MainActivity mActivity; 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     mActivity = new MainActivity(); 
     mActivity.display_notification(incomingNumber);   // call main activity methods 

    } 
} 

回答

2

您沒有使用的onReceive提供的上下文。嘗試將該上下文傳遞給display_notification,而不是使用在您接收廣播時可能未運行的活動上下文。

所以更改方法簽名這樣:

public void display_notification(String incoming_number, Context context) 

而且,通過從的onReceive背景是這樣的:

mActivity.display_notification(incomingNumber, context); 

,並使用此背景下,當您將它傳遞給意向像這樣:

Intent resultIntent = new Intent(context, MainActivity.class); 

EDITED

要麼把整個方法接收機,並使用該行這個由的onReceive

OR,

變化提供的上下文:

NotificationManager mNotificationManager = 
     (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); 

重要組成部分是,context.getSystemService,其中上下文來自onReceive。

+0

感謝您的回答。我修改了它。 但是我收到錯誤「java.lang.IllegalStateException:系統服務不可用於onCreate之前的活動()」 此錯誤發生在此行「NotificationManager mNotificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);」 – pavan

+0

對,因此最終必須將方法display_notification放入廣播接收器中,因爲尚未創建活動並正在使用系統服務。看到我編輯的答案。 – dhun

+0

謝謝,它的作品! – pavan

3

使用此:

Intent i = new Intent(); 
i.setClassName("com.test", "com.test.MainActivity"); 
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
    context.startActivity(i); 
1

我認爲這不是一個好主意,新的活動對象,否則生命週期將無法正確維護,並且它的字段可以爲空,這可能導致NPE。
我建議你將你的Notification構建器移動到util類中,詳細代碼可能類似於@dhun的答案。
順便說一句,使這個util類的util方法不是一個好習慣,因爲它會讓你的代碼很難進行單元測試。在Google Testing Blog更多詳細信息。

+0

感謝您的回答。我是Android應用開發者的初學者。你能不能展示一些關於「我們如何將它放入util類」的鏈接 – pavan

1

您正在向後執行您的ActivityBroadcastReceiver。接收者應該是你的活動的一員,反之亦然。此外,你永遠不應該這樣明確地打電話給new MainActivity()。 Android在內部執行此操作,並在調用中包含一些與系統和應用程序相關的信息(如包名!)。試試這個:

MainActivity.java

public class MainActivity extends ActionBarActivity { 
    PhoneStateReceiver mReceiver 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     // create the new receiver, passing MainActivity as an argument 
     mReceiver = new PhoneStateReceiver(this); 

     // initialize the filter. this is like a letterbox, it lets android 
     // know where to send your broadcast 
     IntentFilter filter = new IntentFilter(); 
     filter.addAction("NUMBER_BLOCKED"); // P.O. box NUMBER_BLOCKED 
     registerReceiver(mReceiver, filter); 
    } 

    public void display_notification(String incoming_number) { 

     NotificationCompat.Builder mBuilder = 
       new NotificationCompat.Builder(getApplicationContext()) 
         .setSmallIcon(R.drawable.ic_action) 
         .setContentTitle("SpamBlocker alert !!") 
         .setContentText("SpamBlocker blocked number : " + incoming_number); 

     // **Error occured in following line** 
     Intent resultIntent = new Intent(getApplicationContext(), MainActivity.class); 

     TaskStackBuilder stackBuilder = TaskStackBuilder.create(getApplicationContext()); 
     stackBuilder.addParentStack(MainActivity.class); 
     stackBuilder.addNextIntent(resultIntent); 
     PendingIntent resultPendingIntent = 
       stackBuilder.getPendingIntent(
         0, 
         PendingIntent.FLAG_UPDATE_CURRENT 
       ); 
     mBuilder.setContentIntent(resultPendingIntent); 
     NotificationManager mNotificationManager = 
       (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); 
     Random r = new Random(); 
     int rand = r.nextInt(1000); 
     mNotificationManager.notify(rand, mBuilder.build()); 
    } 
} 

PhoneStateReceiver.java

public class PhoneStateReceiver extends BroadcastReceiver { 
    MainActivity mActivity; 

    public PhoneStateReceiver(MainActivity activity) { 
     super(); 

     // store the activity from MainActivity.onCreate() 
     mActivity = activity; 
    } 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     // retrieve INCOMING_NUMBER from the broadcast 
     String number = intent.getStringExtra("INCOMING_NUMBER"); 
     mActivity.display_notification(number); 
    } 
} 

而且,我不知道發生了什麼事的app 發送播放,但我感覺到這可能仍然不起作用。如果您仍然收到錯誤,請發佈兩個應用的完整代碼。