无法接收服务器通知,请求排查服务器数据获取代码正确性
问题分析与解决方案
我来帮你一步步拆解问题,先排查服务器数据获取的代码问题,再分析通知不显示的核心原因:
一、服务器数据获取代码的关键问题
你的Sev_data类存在几个容易导致失败的问题,我逐一指出并修正:
localhost访问错误:Android模拟器里访问本地电脑的服务器,不能用localhost,得换成10.0.2.2(Android Studio模拟器专属),否则会指向模拟器自身,根本连不上你的服务器。- 空catch块隐藏错误:所有异常捕获都没有日志输出,出错了你完全不知道问题在哪!必须添加日志来定位故障。
id_s未更新导致重复请求:你每次循环都重置id_s=0,会反复获取所有旧消息,应该把它改成成员变量,每次获取最新消息ID后更新。- 连接未断开导致泄漏:
HttpURLConnection用完后没调用disconnect(),会造成连接资源浪费。 - 字符串拼接效率低:
Stream2String里用Text+=line拼接字符串,频繁创建对象影响性能,换成StringBuilder更合理。
修正后的Sev_data核心代码:
package com.example.hussienalrubaye.myapplication; import android.app.IntentService; import android.content.Intent; import android.support.annotation.Nullable; import android.util.Log; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; public class Sev_data extends IntentService { public static boolean ServiceIsRun = false; private int lastMessageId = 0; // 保存最后一条消息的ID,避免重复请求 public Sev_data() { super("MyWebRequestService"); } @Override protected void onHandleIntent(@Nullable Intent intent) { while (ServiceIsRun) { String url0 = "http://10.0.2.2/sendapp.php?co>" + lastMessageId; // 替换localhost为10.0.2.2 String msg = null; HttpURLConnection urlConnection = null; try { URL url = new URL(url0); urlConnection = (HttpURLConnection) url.openConnection(); InputStream in = new BufferedInputStream(urlConnection.getInputStream()); msg = Stream2String(in); in.close(); JSONObject jsonRootObject = new JSONObject(msg); JSONArray jsonArray = jsonRootObject.optJSONArray("date"); if (jsonArray != null && jsonArray.length() > 0) { // 遍历消息并更新最新ID for (int i = 0; i < jsonArray.length(); i++) { JSONObject jsonObject = jsonArray.getJSONObject(i); String idStr = jsonObject.optString("id"); int currentId = Integer.parseInt(idStr); if (currentId > lastMessageId) { lastMessageId = currentId; } String title = jsonObject.optString("title"); String mess = jsonObject.optString("description"); } // 仅当获取到有效消息时发送广播 Intent broadcastIntent = new Intent(); broadcastIntent.setAction("com.example.Broadcast"); broadcastIntent.putExtra("msg", msg); sendBroadcast(broadcastIntent); } } catch (MalformedURLException e) { Log.e("Sev_data", "URL格式错误", e); } catch (IOException e) { Log.e("Sev_data", "网络请求失败", e); } catch (JSONException e) { Log.e("Sev_data", "JSON解析错误", e); } catch (Exception e) { Log.e("Sev_data", "未知错误", e); } finally { if (urlConnection != null) { urlConnection.disconnect(); // 断开连接释放资源 } } try{ Thread.sleep(20000); }catch (InterruptedException ex){ Log.e("Sev_data", "线程休眠被中断", ex); Thread.currentThread().interrupt(); // 恢复中断状态 } } } public String Stream2String(InputStream inputStream) { StringBuilder textBuilder = new StringBuilder(); BufferedReader bureader = new BufferedReader(new InputStreamReader(inputStream)); String line ; try{ while((line = bureader.readLine())!=null) { textBuilder.append(line); } inputStream.close(); bureader.close(); // 关闭阅读器 }catch (IOException ex){ Log.e("Sev_data", "流转换字符串失败", ex); } return textBuilder.toString(); } }
二、通知不显示的核心原因排查
- 广播接收器注册问题:确认
AndroidManifest.xml里正确注册了MyReceiver,且Action匹配:
<receiver android:name=".MyReceiver"> <intent-filter> <action android:name="com.example.Broadcast" /> </intent-filter> </receiver>
如果是动态注册,要在Activity的onCreate里注册,onDestroy里注销,避免内存泄漏。
- Android O+通知渠道缺失:从API 26开始,必须创建通知渠道才能显示通知。你的
NewMessageNotification需要补充渠道创建逻辑:
package com.example.doblist.mydobservice; import android.app.NotificationChannel; import android.app.NotificationManager; import android.content.Context; import android.content.Intent; import android.os.Build; import android.os.Bundle; import androidx.core.app.NotificationCompat; public class NewMessageNotification { public void notify(Context context, String msg, int notificationId) { NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); // 创建通知渠道(API 26+必填) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { String channelId = "message_channel"; String channelName = "新消息通知"; NotificationChannel channel = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_DEFAULT); notificationManager.createNotificationChannel(channel); } // 构建通知(必须设置小图标) NotificationCompat.Builder builder = new NotificationCompat.Builder(context, "message_channel") .setSmallIcon(R.drawable.ic_notification) // 替换成你的图标资源 .setContentTitle("收到新消息") .setContentText(msg) .setPriority(NotificationCompat.PRIORITY_DEFAULT); notificationManager.notify(notificationId, builder.build()); } }
⚠️ 注意:必须设置setSmallIcon,否则通知会被系统拦截不显示。
- 广播接收日志调试:在
MyReceiver里添加日志,确认是否收到广播:
@Override public void onReceive(Context context, Intent intent) { Log.d("MyReceiver", "收到广播"); final Bundle bundle = intent.getExtras(); if ( intent.getAction().equalsIgnoreCase("com.example.Broadcast")) { String msg = bundle.getString("msg"); Log.d("MyReceiver", "消息内容:"+msg); if(msg != null){ NewMessageNotification notfilyme= new NewMessageNotification(); notfilyme.notify(context,msg,223); } else { Log.w("MyReceiver", "消息为空"); } } }
三、其他必要配置检查
- 确认
AndroidManifest.xml添加了网络权限:
<uses-permission android:name="android.permission.INTERNET" />
- 如果服务器用的是HTTP而非HTTPS,Android 9.0+需要在
application标签里添加:
android:usesCleartextTraffic="true"
内容的提问来源于stack exchange,提问作者user6756076
相关产品推荐
相关产品推荐

