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

Android通知正确创建方式及后台Service实现合理性咨询

Hey there! Let's break down your questions one by one to get your Android app on the right track.

1. 符合当前规范的通知创建方式

Starting from Android 8.0 (API Level 26), all notifications must belong to a NotificationChannel—otherwise, they won't show up at all. Here's the correct, up-to-date way to create notifications for both Java and Kotlin:

Java Implementation

public class ConnectionService extends Service {
    private static final String CHANNEL_ID = "BluetoothConnectionChannel";
    private static final int NOTIFICATION_ID = 327;

    @Override
    public void onCreate() {
        super.onCreate();
        // Create notification channel (required for API 26+)
        createNotificationChannel();
        // Initialize foreground service with notification
        startForegroundWithNotification();
    }

    private void createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            CharSequence channelName = getString(R.string.bluetooth_channel_name);
            String channelDesc = getString(R.string.bluetooth_channel_desc);
            int importance = NotificationManager.IMPORTANCE_LOW; // Low priority to avoid user disruption

            NotificationChannel channel = new NotificationChannel(CHANNEL_ID, channelName, importance);
            channel.setDescription(channelDesc);

            // Register channel with system
            NotificationManager notificationManager = getSystemService(NotificationManager.class);
            notificationManager.createNotificationChannel(channel);
        }
    }

    private void startForegroundWithNotification() {
        Intent notificationIntent = new Intent(this, MainActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(
                this,
                0,
                notificationIntent,
                PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT // Mandatory for Android 12+
        );

        Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentTitle("Bluetooth Connected")
                .setContentText("Listening for incoming calls in background")
                .setContentIntent(pendingIntent)
                .setPriority(NotificationCompat.PRIORITY_LOW)
                .build();

        startForeground(NOTIFICATION_ID, notification);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return START_STICKY;
    }

    @Override
    public IBinder onBind(Intent intent) {
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public void onDestroy() {
        stopForeground(true);
        super.onDestroy();
    }
}

Kotlin Implementation

class ConnectionService : Service() {
    private val CHANNEL_ID = "BluetoothConnectionChannel"
    private val NOTIFICATION_ID = 327

    override fun onCreate() {
        super.onCreate()
        createNotificationChannel()
        startForegroundWithNotification()
    }

    private fun createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channelName = getString(R.string.bluetooth_channel_name)
            val channelDesc = getString(R.string.bluetooth_channel_desc)
            val importance = NotificationManager.IMPORTANCE_LOW

            val channel = NotificationChannel(CHANNEL_ID, channelName, importance).apply {
                description = channelDesc
            }

            val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            notificationManager.createNotificationChannel(channel)
        }
    }

    private fun startForegroundWithNotification() {
        val notificationIntent = Intent(this, MainActivity::class.java)
        val pendingIntent = PendingIntent.getActivity(
            this,
            0,
            notificationIntent,
            PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
        )

        val notification = NotificationCompat.Builder(this, CHANNEL_ID)
            .setSmallIcon(R.mipmap.ic_launcher)
            .setContentTitle("Bluetooth Connected")
            .setContentText("Listening for incoming calls in background")
            .setContentIntent(pendingIntent)
            .setPriority(NotificationCompat.PRIORITY_LOW)
            .build()

        startForeground(NOTIFICATION_ID, notification)
    }

    override fun onBind(intent: Intent): IBinder? {
        throw UnsupportedOperationException("Not yet implemented")
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        return START_STICKY
    }

    override fun onDestroy() {
        stopForeground(true)
        super.onDestroy()
    }
}

Key Notes:

  • Use PendingIntent.FLAG_IMMUTABLE (safer if you don't need to modify the intent later) or FLAG_MUTABLE (required if you need to update the intent) for Android 12+.
  • Choose IMPORTANCE_LOW for background service notifications to avoid interrupting users.
2. Is Your Service Implementation Reasonable for the Requirements?

Your core goal is to maintain a Bluetooth connection and listen for incoming calls in both foreground and background. Here's the breakdown:

What's Working Well

  • START_STICKY: If the system kills your service due to low memory, it will restart the service (without re-delivering the original intent) — perfect for persistent connection services.
  • Foreground Service: Long-running services need to be foregrounded to avoid being terminated by Android's background process limits. This aligns with your need for constant Bluetooth connectivity.
  • Start/Stop on Bluetooth Connect/Disconnect: This logic is efficient, as it prevents the service from running unnecessarily when no Bluetooth connection exists.

Key Improvements Needed

  1. Missing Bluetooth Connection Logic: Your current service has no code to handle Bluetooth connections. You need to:
    • Register broadcast receivers for Bluetooth state changes (ACTION_ACL_CONNECTED, ACTION_ACL_DISCONNECTED).
    • Initialize and manage the Bluetooth socket connection in onCreate().
  2. Incoming Call Listening: Add logic to monitor calls:
    • Register a broadcast receiver for ACTION_PHONE_STATE_CHANGED or use TelephonyManager's callback API.
    • Request necessary permissions: READ_PHONE_STATE (Android 10 and below) or READ_CALL_LOG (Android 11+, more permissive).
  3. Service Startup: Use startForegroundService() instead of startService() for Android 8.0+ to avoid IllegalStateException.
  4. Resource Cleanup: In onDestroy(), unregister broadcast receivers, close the Bluetooth socket, and stop call listeners to prevent memory leaks.

Example Kotlin Snippet for Bluetooth + Call Listening

private lateinit var telephonyManager: TelephonyManager
private val phoneStateReceiver = object : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        val state = intent?.getStringExtra(TelephonyManager.EXTRA_STATE)
        if (state == TelephonyManager.EXTRA_STATE_RINGING) {
            val incomingNumber = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER)
            // Handle incoming call (e.g., send notification via Bluetooth)
        }
    }
}

override fun onCreate() {
    super.onCreate()
    // Initialize call listener
    telephonyManager = getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
    registerReceiver(phoneStateReceiver, IntentFilter(TelephonyManager.ACTION_PHONE_STATE_CHANGED))
    
    // Initialize Bluetooth connection (example)
    val bluetoothAdapter = BluetoothAdapter.getDefaultAdapter()
    if (bluetoothAdapter.isEnabled) {
        // Connect to your target Bluetooth device here
    }
    
    createNotificationChannel()
    startForegroundWithNotification()
}

override fun onDestroy() {
    unregisterReceiver(phoneStateReceiver)
    // Close Bluetooth socket connection
    stopForeground(true)
    super.onDestroy()
}

Final Verdict

Your service framework is a solid foundation. Once you add the Bluetooth connection management, call listening logic, and permission handling, it will fully meet your requirements for persistent Bluetooth connectivity and call monitoring.

内容的提问来源于stack exchange,提问作者João Ghignatti

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:47:11