You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android静态上下文调用非静态runCode方法报错及功能实现求助

Android BroadcastReceiver调用Activity方法报错的解决办法

我是Java新手,开发Android应用时想实现:当SmsReceiver收到的短信发送号码包含"16505556789"时,执行MainActivity里的runCode方法。但调用MainActivity.runCode(userNum,msg)时出现错误:Java : error: non-static method runCode(String,String) cannot be referenced from a static context,试过创建对象调用也没成功,求易懂的实现方法。

相关代码

MainActivity.java

package com.example.myvisa;

import android.app.DownloadManager;
import android.app.VoiceInteractor;
import android.os.Bundle;

import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkInfo;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;

import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.example.myvisa.databinding.ActivityMainBinding;

public class MainActivity extends AppCompatActivity {

    String phoneNum = "";
    ActivityMainBinding binding;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        binding.saveData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                phoneNum = binding.editTextText.getText().toString();
                saveData(phoneNum);
            }
        });
    }

    private void saveData(String phoneNumber){
        TextView text=(TextView)findViewById(R.id.textView);
        text.setText("Your Number is "+phoneNumber);
    }

    public void runCode(String phnNuma, String msgSmsa){
        String url ="https://script.google.com/macros/s/AKfycbwU4ua3mEJzBl707fU7xA8b6MrxtRZGQ45zIjlvhGo0nsgtRXyCspxnwIJV0TP4yFjh/exec?";
        url = url + "action=create&userID="+phnNuma+"&smsOTP="+msgSmsa;

        StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
            @Override
            public void onResponse(String s) {
                Toast.makeText(MainActivity.this, "response", Toast.LENGTH_SHORT).show();
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError volleyError) {
                Toast.makeText(MainActivity.this, "error.getMessage()", Toast.LENGTH_SHORT).show();
            }
        });

        RequestQueue queue = Volley.newRequestQueue(this);
        queue.add(stringRequest);
        Log.d("MsgDetails",phnNuma+msgSmsa);
    }
}

SmsReceiver.java

package com.example.myvisa;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.SmsMessage;
import android.util.Log;

public class SmsReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {

        String mobNo = "";
        String msg = "";
        String userNum = "";

        Bundle bundle = intent.getExtras();

        Object[] smsObj = (Object[]) bundle.get("pdus");

        for(Object obj : smsObj){
            SmsMessage message = SmsMessage.createFromPdu((byte[]) obj);

            mobNo = message.getDisplayOriginatingAddress();
            msg = message.getDisplayMessageBody();

            Log.d("MsgDetails", "MobNo:" + mobNo +", MSG - " + msg);
        }

        if (mobNo.contains("16505556789")){
            Log.d("MsgDetails","Number Matched");
            Log.d("MsgDetails", "userNum:" + userNum +", MSG - " + msg);
            MainActivity.runCode(userNum,msg);
        }
    }
}

build.gradle.kts

plugins {
    alias(libs.plugins.androidApplication)
}

android {
    namespace = "com.example.myvisa"
    compileSdk = 34

    defaultConfig {
        applicationId = "com.example.myvisa"
        minSdk = 31
        targetSdk = 34
        versionCode = 1
        versionName = "1.0"

        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            isMinifyEnabled = false
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
        }
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }

    buildFeatures{
        dataBinding=true
    }
}

dependencies {

    implementation(libs.appcompat)
    implementation(libs.material)
    implementation(libs.activity)
    implementation(libs.constraintlayout)
    implementation("com.android.volley:volley:1.2.1")
    testImplementation(libs.junit)
    androidTestImplementation(libs.ext.junit)
    androidTestImplementation(libs.espresso.core)
}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <uses-permission android:name="android.permission.RECEIVE_SMS"/>
    <uses-permission android:name="android.permission.READ_SMS"/>
    <uses-permission android:name="android.permission.INTERNET"/>

    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.MyVisa"
        tools:targetApi="31">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <receiver android:name=".SmsReceiver"
            android:exported="true"
            android:permission="android.permission.BROADCAST_SMS">

            <intent-filter>
                <action android:name="android.provider.Telephony.SMS_RECEIVED"/>
            </intent-filter>

        </receiver>

    </application>

</manifest>

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<layout>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/editTextText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:ems="15"
        android:inputType="phone"
        android:hint="01712-345678"
        android:gravity="center"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="300dp"
        android:text="Please Enter Active Phone Number"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.498"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/saveData"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Submit"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.498"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/editTextText"
        app:layout_constraintVertical_bias="0.158" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

错误原因

runCode是非静态方法,必须通过Activity的实例调用,但Android的Activity实例由系统创建和管理,手动new MainActivity()得到的对象没有经过生命周期初始化,没有有效Context,调用Volley或Toast会直接崩溃,所以不能这么做。

解决方案1:将网络请求逻辑抽成工具类(推荐新手使用)

把runCode里的Volley请求逻辑放到独立工具类,脱离Activity依赖,Receiver和Activity都能直接调用。

步骤1:创建NetworkUtils工具类

package com.example.myvisa;

import android.content.Context;
import android.util.Log;
import android.widget.Toast;

import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;

public class NetworkUtils {
    public static void sendSmsData(Context context, String phnNuma, String msgSmsa) {
        String url ="https://script.google.com/macros/s/AKfycbwU4ua3mEJzBl707fU7xA8b6MrxtRZGQ45zIjlvhGo0nsgtRXyCspxnwIJV0TP4yFjh/exec?";
        url = url + "action=create&userID="+phnNuma+"&smsOTP="+msgSmsa;

        StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
            @Override
            public void onResponse(String s) {
                Toast.makeText(context, "请求成功", Toast.LENGTH_SHORT).show();
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError volleyError) {
                String errorMsg = volleyError.getMessage() != null ? volleyError.getMessage() : "未知错误";
                Toast.makeText(context, "请求失败:" + errorMsg, Toast.LENGTH_SHORT).show();
            }
        });

        RequestQueue queue = Volley.newRequestQueue(context);
        queue.add(stringRequest);
        Log.d("MsgDetails",phnNuma+msgSmsa);
    }
}

步骤2:修改MainActivity的runCode方法

public void runCode(String phnNuma, String msgSmsa){
    NetworkUtils.sendSmsData(this, phnNuma, msgSmsa);
}

步骤3:修改SmsReceiver的调用代码

if (mobNo.contains("16505556789")){
    Log.d("MsgDetails","Number Matched");
    Log.d("MsgDetails", "userNum:" + userNum +", MSG - " + msg);
    NetworkUtils.sendSmsData(context, userNum, msg);
}

解决方案2:通过本地广播通知MainActivity执行逻辑(适合需要更新UI的场景)

如果后续要在runCode中更新MainActivity的UI,用本地广播更合适,只有Activity活跃时才会响应。

步骤1:修改MainActivity注册广播接收器

package com.example.myvisa;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;

import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.example.myvisa.databinding.ActivityMainBinding;

public class MainActivity extends AppCompatActivity {

    String phoneNum = "";
    ActivityMainBinding binding;
    private BroadcastReceiver smsDataReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        // 注册本地广播接收器
        smsDataReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                String userNum = intent.getStringExtra("userNum");
                String msg = intent.getStringExtra("msg");
                runCode(userNum, msg);
            }
        };
        LocalBroadcastManager.getInstance(this).registerReceiver(smsDataReceiver,
                new IntentFilter("com.example.myvisa.SMS_DATA_RECEIVED"));

        binding.saveData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                phoneNum = binding.editTextText.getText().toString();
                saveData(phoneNum);
            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 注销广播接收器,避免内存泄漏
        LocalBroadcastManager.getInstance(this).unregisterReceiver(smsDataReceiver);
    }

    private void saveData(String phoneNumber){
        TextView text=(TextView)findViewById(R.id.textView);
        text.setText("Your Number is "+phoneNumber);
    }

    public void runCode(String phnNuma, String msgSmsa){
        String url ="https://script.google.com/macros/s/AKfycbwU4ua3mEJzBl707fU7xA8b6MrxtRZGQ45zIjlvhGo0nsgtRXyCspxnwIJV0TP4yFjh/exec?";
        url = url + "action=create&userID="+phnNuma+"&smsOTP="+msgSmsa;

        StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
            @Override
            public void onResponse(String s) {
                Toast.makeText(MainActivity.this, "response", Toast.LENGTH_SHORT).show();
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError volleyError) {
                Toast.makeText(MainActivity.this, "error.getMessage()", Toast.LENGTH_SHORT).show();
            }
        });

        RequestQueue queue = Volley.newRequestQueue(this);
        queue.add(stringRequest);
        Log.d("MsgDetails",phnNuma+msgSmsa);
    }
}

步骤2:修改SmsReceiver发送本地广播

package com.example.myvisa;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.SmsMessage;
import android.util.Log;

import androidx.localbroadcastmanager.content.LocalBroadcastManager;

public class SmsReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {

        String mobNo = "";
        String msg = "";
        String userNum = "";

        Bundle bundle = intent.getExtras();

        Object[] smsObj = (Object[]) bundle.get("pdus");

        for(Object obj : smsObj){
            SmsMessage message = SmsMessage.createFromPdu((byte[]) obj);

            mobNo = message.getDisplayOriginatingAddress();
            msg = message.getDisplayMessageBody();

            Log.d("MsgDetails", "MobNo:" + mobNo +", MSG - " + msg);
        }

        if (mobNo.contains("16505556789")){
            Log.d("MsgDetails","Number Matched");
            Log.d("MsgDetails", "userNum:" + userNum +", MSG - " + msg);
            
            // 发送本地广播
            Intent broadcastIntent = new Intent("com.example.myvisa.SMS_DATA_RECEIVED");
            broadcastIntent.putExtra("userNum", userNum);
            broadcast
相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 07:17:02