从其他类调用MainActivity方法(扩展广播接收器)

时间:2015-08-19 14:10:19

标签: java android android-intent

我试图从其他类(PhoneStateReceiver)调用MainActivity的方法display_notification。

但是出现了这个错误:

  

java.lang.RuntimeException:无法启动接收器com.weekendproject.roshu.spamblocker.PhoneStateReceiver:java.lang.NullPointerException:尝试调用虚方法' java.lang.String android.content.Context.getPackageName ()'在空对象引用上

错误特别指向MainActivity中的这一行

Intent resultIntent = new Intent(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

    }
}

4 个答案:

答案 0 :(得分:3)

使用此:

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

答案 1 :(得分:2)

您没有使用onReceive 提供的上下文。尝试将该上下文传递给display_notification,而不是使用在您收到广播时可能没有运行的活动的上下文。

所以将方法签名更改为:

 public void display_notification(String incoming_number, Context context) 

然后,从onReceive传递上下文:

 mActivity.display_notification(incomingNumber, context);

当你将它传递给Intent时使用这个上下文:

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

<强> EDITED

将整个方法放在接收器中,并使用 onReceive

提供的上下文

OR,

将该行更改为:

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

重要的部分是 context.getSystemService ,其中上下文来自onReceive。

答案 2 :(得分:1)

我认为新建一个Activity对象并不是一个好主意,否则生命周期将无法正常维护,其字段可能为空,这可能会导致NPE。
我建议您将Notification构建器移动到util类中,详细代码可能类似于@dhun的回答。
顺便说一下,将这个util类的util方法设置为静态不是一个好习惯,因为它会使你的代码难以进行单元测试。 Google Testing Blog

中的更多详细信息

答案 3 :(得分: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);
    }
}

此外,我不确定发送广播的应用中发生了什么,但我觉得这可能仍然不起作用。如果您仍然遇到错误,请发布两个应用的完整代码。