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

Android WebView中通过JS获取PHP的FCM Token返回null的解决方案

解决方案

问题根源

你遇到的getActiveToken()返回null的核心原因是:你在MainFragment中新建了一个独立的JavaScriptAPI实例,而WebView中注入的是另一个未被你引用的实例。JS代码调用的是WebView绑定的实例的userToken()方法,但你调用getActiveToken()的是全新的实例,自然拿不到值。

修复步骤

1. 统一JavaScriptAPI实例并添加回调机制

修改JavaScriptAPI类,新增回调接口,确保Token接收时能通知到MainFragment:

public class JavaScriptAPI {
    private Activity mActivity;
    private volatile String activeToken;
    private OnTokenReceivedListener tokenListener;

    // 定义回调接口
    public interface OnTokenReceivedListener {
        void onTokenReceived(String token);
    }

    // 构造方法传入回调
    public JavaScriptAPI(Activity activity, OnTokenReceivedListener listener) {
        mActivity = activity;
        this.tokenListener = listener;
    }

    @JavascriptInterface
    public void userToken(String token){
        activeToken = token;
        Log.d("JavaScriptAPI", "Received Token: " + activeToken);
        
        // 切换到主线程通知Fragment(JS接口调用在WebView后台线程)
        if (tokenListener != null) {
            mActivity.runOnUiThread(() -> tokenListener.onTokenReceived(token));
        }
    }

    public String getActiveToken() {
        return activeToken;
    }
}

2. 在MainFragment中绑定统一实例并实现回调

在MainFragment中创建唯一的JavaScriptAPI实例,注入WebView,并实现回调来处理Token对比和Volley请求:

public class MainFragment extends Fragment implements JavaScriptAPI.OnTokenReceivedListener {
    private WebView webView;
    private JavaScriptAPI javaScriptAPI;
    private String fcmToken; // 已获取的FCM Token

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_main, container, false);
        webView = view.findViewById(R.id.webview);
        
        // 启用JavaScript
        WebSettings webSettings = webView.getSettings();
        webSettings.setJavaScriptEnabled(true);

        // 创建唯一的JavaScriptAPI实例并绑定回调
        javaScriptAPI = new JavaScriptAPI(getActivity(), this);
        webView.addJavascriptInterface(javaScriptAPI, "MyApp");

        // 获取FCM Token(替换为你的实际获取逻辑)
        FirebaseMessaging.getInstance().getToken()
                .addOnCompleteListener(task -> {
                    if (task.isSuccessful()) {
                        fcmToken = task.getResult();
                    }
                });

        // 加载PHP页面
        webView.loadUrl("你的PHP页面URL");

        webView.setWebViewClient(new WebViewClient() {
            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                // 无需在此处调用getActiveToken,等待回调即可
            }
        });
        return view;
    }

    // 实现回调方法,处理Token对比与请求
    @Override
    public void onTokenReceived(String phpToken) {
        if (fcmToken == null) {
            Log.d("MainFragment", "FCM Token未获取完成,延迟处理");
            return;
        }

        // 对比Token,决定是否发起Volley请求
        if (!fcmToken.equals(phpToken)) {
            sendTokenToServer(fcmToken);
        } else {
            Log.d("MainFragment", "Token一致,无需更新");
        }
    }

    // Volley请求逻辑
    private void sendTokenToServer(String token) {
        String url = "你的Token更新接口URL";
        StringRequest stringRequest = new StringRequest(Request.Method.POST, url,
                response -> Log.d("Volley", "Token更新成功"),
                error -> Log.e("Volley", "Token更新失败", error)) {
            @Override
            protected Map<String, String> getParams() {
                Map<String, String> params = new HashMap<>();
                params.put("token", token);
                return params;
            }
        };
        Volley.newRequestQueue(getActivity()).add(stringRequest);
    }
}

关键注意事项

  • 确保WebView已启用JavaScript:webSettings.setJavaScriptEnabled(true)
  • JS代码中的MyApp必须与WebView注入的接口名称完全一致
  • JS接口方法运行在WebView的后台线程,通知主线程时需调用runOnUiThread
  • 不要在onPageFinished中直接调用getActiveToken,因为JS代码可能尚未执行完成,回调机制更可靠

内容的提问来源于stack exchange,提问作者Super Coder

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 22:35:19