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

Android定时检测MySQL新数据并推送通知的实现求助

Hey there! Let's figure out why your periodic database check isn't working and fix it up. First, let's recap your problem clearly, then break down the issues in your current code, and finally walk through a reliable solution.


问题描述

I'm building a simple Android app that needs to check a MySQL database every 2 minutes for new data, then display that data in notifications. I've tried using the sev_data IntentService below, but it never works. The database itself runs fine, though I can't view your attached screenshots right now.

My Existing Code

sev_data.java

public class sev_data extends IntentService {
    public static boolean ServiceIsRun = false;

    public sev_data() {
        super("MyWebRequestService");
    }

    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        while (ServiceIsRun) {
            int id_s=0;
            // Note: Original code had a syntax error (extra double quote) — fixed here
            String url0 = "http://172.17.100.2/sendapp.php?co=" + id_s;
            String msg;
            try {
                URL url = new URL(url0);
                HttpURLConnection 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");
                for (int i = 0; i < jsonArray.length(); i++) {
                    JSONObject jsonObject = jsonArray.getJSONObject(i);
                    String id= jsonObject.optString("id");
                    String title = jsonObject.optString("title");
                    String mess = jsonObject.optString("mess");
                    // No logic here to handle new data (like saving the latest ID or showing notifications)
                }

                // Send broadcast with data
                intent = new Intent();
                intent.setAction("com.example.Broadcast");
                intent.putExtra("msg", msg);
                sendBroadcast(intent);

            } catch (Exception e) {
                // No logging here — you can't see what went wrong!
                e.printStackTrace(); // Add this to debug
            }

            try{
                Thread.sleep(20000); // You wanted 2 minutes, but this is only 20 seconds
            }catch (Exception ex){
                ex.printStackTrace();
            }
        }
    }

    public String Stream2String(InputStream inputStream) {
        BufferedReader bureader=new BufferedReader(
                new InputStreamReader(inputStream));
        String line ;
        String Text="";
        try{
            while((line=bureader.readLine())!=null) {
                Text+=line;
            }
            inputStream.close();
        }catch (Exception ex){
            ex.printStackTrace();
        }
        return Text;
    }
}

sendapp.php

<?php
$hostname_mus_db = "localhost";
$database_mus_db = "musdb2";
$username_mus_db = "root";
$password_mus_db = "";

$tf=@mysql_connect($hostname_mus_db,$username_mus_db,$password_mus_db);
if(!$tf) die('Connection problem1 ..');

$tf_db=mysql_select_db($database_mus_db);
if(!$tf_db) {
    @mysql_close($tf_handle);
    die('selection problem2 ..');
}

$co_array=array();
if (isset($_GET['co'])) {
    $co=$_GET['co'];
    $sql = mysql_query("SELECT * FROM mha1 where id>".$co);
    while($row = mysql_fetch_assoc($sql)){
        $co_array[]=$row;
    }
}

header('Content-Type:application/json');
echo json_encode(array("date"=>$co_array));
?>

Why Your Current Code Isn't Working

Let's break down the key issues:

  1. IntentService isn't built for long-running loops: IntentService is designed for one-time tasks. Once onHandleIntent finishes executing, the service automatically stops and is destroyed. Your while loop tries to keep it running, but the system will kill it or it'll terminate on its own.
  2. Syntax error: The original URL string had an extra double quote, which would cause a compile error (if you didn't fix it already).
  3. Static id_s value: You're always using id_s=0, so you'll keep fetching all old data instead of only new entries. You need to track the latest ID you've fetched.
  4. No error logging: You catch all exceptions but don't log them, so you have no way to debug issues like failed network requests or broken JSON parsing.
  5. Incorrect sleep time: You wanted a 2-minute interval, but Thread.sleep(20000) only waits 20 seconds. Plus, using Thread.sleep in a service is unreliable on Android, especially with background restrictions.

The Fix: Use WorkManager for Reliable Periodic Tasks

Android 8.0+ has strict background service limits, so WorkManager is Google's recommended tool for periodic or delayed tasks. It works across all Android versions, survives system reboots, and handles background restrictions automatically.

Step 1: Add WorkManager Dependency

Add this to your app-level build.gradle:

dependencies {
    implementation "androidx.work:work-runtime:2.8.1"
}

Step 2: Create a Worker Class (Replace IntentService)

This class will handle the database check and notification logic:

public class DatabaseCheckWorker extends Worker {
    private static final String TAG = "DatabaseCheckWorker";
    private int lastId; // Tracks the latest ID we've fetched

    public DatabaseCheckWorker(@NonNull Context context, @NonNull WorkerParameters params) {
        super(context, params);
        // Load the last saved ID from SharedPreferences
        SharedPreferences prefs = context.getSharedPreferences("AppPrefs", Context.MODE_PRIVATE);
        lastId = prefs.getInt("last_id", 0);
    }

    @NonNull
    @Override
    public Result doWork() {
        try {
            // Fetch only new data (where ID > lastId)
            String url0 = "http://172.17.100.2/sendapp.php?co=" + lastId;
            URL url = new URL(url0);
            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setRequestMethod("GET");
            
            InputStream in = new BufferedInputStream(urlConnection.getInputStream());
            String msg = streamToString(in);
            in.close();
            urlConnection.disconnect();

            // Parse JSON response
            JSONObject jsonRoot = new JSONObject(msg);
            JSONArray jsonArray = jsonRoot.optJSONArray("date");
            
            if (jsonArray != null && jsonArray.length() > 0) {
                // Process each new entry
                for (int i = 0; i < jsonArray.length(); i++) {
                    JSONObject entry = jsonArray.getJSONObject(i);
                    String idStr = entry.optString("id");
                    String title = entry.optString("title");
                    String message = entry.optString("mess");

                    // Update lastId to the newest entry's ID
                    int currentId = Integer.parseInt(idStr);
                    if (currentId > lastId) {
                        lastId = currentId;
                    }

                    // Show a notification for the new entry
                    showNotification(title, message);
                }

                // Save the latest ID to avoid re-fetching old data
                SharedPreferences prefs = getApplicationContext().getSharedPreferences("AppPrefs", Context.MODE_PRIVATE);
                prefs.edit().putInt("last_id", lastId).apply();
            }

            return Result.success(); // Task completed successfully
        } catch (Exception e) {
            Log.e(TAG, "Database check failed", e);
            return Result.retry(); // Retry the task later if it fails
        }
    }

    private String streamToString(InputStream inputStream) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
        StringBuilder sb = new StringBuilder();
        String line;
        while ((line = reader.readLine()) != null) {
            sb.append(line);
        }
        reader.close();
        return sb.toString();
    }

    private void showNotification(String title, String content) {
        // Create a notification channel (required for Android O+)
        String channelId = "NEW_MESSAGE_CHANNEL";
        NotificationManager notificationManager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
        
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(channelId, "New Messages", NotificationManager.IMPORTANCE_DEFAULT);
            notificationManager.createNotificationChannel(channel);
        }

        // Build and show the notification
        NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext(), channelId)
                .setSmallIcon(R.drawable.ic_notification) // Replace with your notification icon
                .setContentTitle(title)
                .setContentText(content)
                .setPriority(NotificationCompat.PRIORITY_DEFAULT)
                .setAutoCancel(true);

        notificationManager.notify((int) System.currentTimeMillis(), builder.build());
    }
}

Step 3: Start the Periodic Task

In your Activity or Application class, start the 2-minute recurring task:

// Configure the periodic work request
PeriodicWorkRequest periodicCheck = new PeriodicWorkRequest.Builder(
        DatabaseCheckWorker.class,
        120, TimeUnit.SECONDS, // Run every 2 minutes
        30, TimeUnit.SECONDS) // Allow a 30-second flexibility window
        .build();

// Submit the task to WorkManager
WorkManager.getInstance(getApplicationContext()).enqueue(periodicCheck);

Bonus Optimizations

  1. Update PHP to use modern MySQL functions: Your current PHP uses deprecated mysql_* functions. Switch to mysqli for security and compatibility:
<?php
$hostname_mus_db = "localhost";
$database_mus_db = "musdb2";
$username_mus_db = "root";
$password_mus_db = "";

// Use mysqli for secure, supported database access
$conn = mysqli_connect($hostname_mus_db, $username_mus_db, $password_mus_db, $database_mus_db);
if (!$conn) {
    die(json_encode(array("error" => "Connection failed: " . mysqli_connect_error())));
}

$co_array = array();
if (isset($_GET['co'])) {
    $co = intval($_GET['co']); // Sanitize input to prevent SQL injection
    $sql = "SELECT * FROM mha1 WHERE id > ?";
    $stmt = mysqli_prepare($conn, $sql);
    mysqli_stmt_bind_param($stmt, "i", $co);
    mysqli_stmt_execute($stmt);
    $result = mysqli_stmt_get_result($stmt);
    
    while ($row = mysqli_fetch_assoc($result)) {
        $co_array[] = $row;
    }
    mysqli_stmt_close($stmt);
}

header('Content-Type:application/json');
echo json_encode(array("date" => $co_array));
mysqli_close($conn);
?>
  1. Add Internet Permission: Make sure your AndroidManifest.xml includes this:
<uses-permission android:name="android.permission.INTERNET" />

内容的提问来源于stack exchange,提问作者Mohamed Mrzook

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:03:09