通知在 Java 中的 API 34 (Android 14) 上不起作用?

问题描述 投票:0回答:1

我遇到一个问题,即更新我的项目后,运行 Android 14(API 级别 34) 的设备上未收到通知,但通知无法显示在 Android 14 设备上。

清单权限:

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

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>

    <uses-feature android:name="android.hardware.camera" />

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

    <queries>
        <intent>
            <action
                android:name="android.media.action.IMAGE_CAPTURE"
                android:exported="true" />
        </intent>
    </queries>

    <application
        android:name=".Utils.App"
        android:allowBackup="false"
        android:exported="true"
        android:icon="@drawable/app_logo"
        android:label="@string/app_name"
        android:networkSecurityConfig="@xml/network_security_config"
        android:requestLegacyExternalStorage="true"
        android:roundIcon="@drawable/app_logo"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        android:usesCleartextTraffic="true"
        tools:replace="android:allowBackup">

        <uses-library
            android:name="org.apache.http.legacy"
            android:exported="true"
            android:required="false" />

        <service
            android:name=".Utils.ForegroundService"
            android:enabled="true"
            android:exported="false"
            android:foregroundServiceType="dataSync" />

        <service
            android:name=".Utils.BackgroundService"
            android:enabled="true"
            android:exported="false"
            android:foregroundServiceType="dataSync"/>

        <meta-data
            android:name="com.google.android.geo.API_KEY"
            android:exported="true"
            android:value="@string/google_maps_key" />

        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action
                    android:name="android.intent.action.MAIN"
                    android:exported="true" />

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

        <service
            android:name=".Utils.MyFirebaseMessagingService"
            android:enabled="true"
            android:exported="false"
            android:stopWithTask="false">
            <intent-filter>
                <action
                    android:name="com.google.firebase.MESSAGING_EVENT"
                    android:exported="true" />
            </intent-filter>
        </service>

        <meta-data
            android:name="com.google.firebase.messaging.default_notification_channel_id"
            android:exported="true"
            android:value="@string/notification_channel_id" />
        <meta-data
            android:name="com.google.firebase.messaging.default_notification_icon"
            android:exported="true"
            android:resource="@mipmap/ic_launcher_foreground" />
        <meta-data
            android:name="com.google.firebase.messaging.default_notification_color"
            android:exported="true"
            android:resource="@mipmap/ic_launcher_foreground" />
        <meta-data
            android:name="com.google.android.gms.wallet.api.enabled"
            android:exported="true"
            android:value="true" />

        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="${applicationId}"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:exported="true"
                android:resource="@xml/file_paths" />
        </provider>
    </application>

</manifest>

通知代码

public class MyFirebaseMessagingService extends FirebaseMessagingService {
    private static final String CHANNEL_ID = "default_channel";
    private static final String CHANNEL_NAME = "FCM";
    private static final String CHANNEL_DESC = "Firebase Cloud Messaging";
    final String TAG = "MyFirebaseMsgService";
    private String id = "";
    private String title = "";
    private String message = "";
    private String type = "";
    private String fcm_notification = "";
    private String uid = "";
    private String stuName = "", clsSec = "", imgUrl_old = "", imgUrl_new = "", enrollmentNo = "", cls = "", sec = "", conType = "", component = "", period = "";

    @Override
    public void onNewToken(@NonNull String s) {
        super.onNewToken(s);
        Log.e("newToken", s);
    }

    @Override
    public void onMessageReceived(@NonNull RemoteMessage remoteMessage) {
        super.onMessageReceived(remoteMessage);
        Log.e("Message Body", Objects.requireNonNull(Objects.requireNonNull(remoteMessage.getNotification()).getBody()));
        Log.e("Message data payload: ", remoteMessage.getData().toString());
        Log.e("From: ", Objects.requireNonNull(remoteMessage.getFrom()));

        if (!remoteMessage.getData().isEmpty()) {
            try {
                Log.d(TAG, "Message data payload: " + remoteMessage.getData());

                id = remoteMessage.getData().get("id");
                uid = remoteMessage.getData().get("uid");
                title = remoteMessage.getData().get("title");
                message = remoteMessage.getData().get("message");
                type = remoteMessage.getData().get("type");
                fcm_notification = "Y";

                stuName = remoteMessage.getData().get("stuName");
                clsSec = remoteMessage.getData().get("clsSec");
                imgUrl_old = remoteMessage.getData().get("oldImg");
                imgUrl_new = remoteMessage.getData().get("newImg");
                enrollmentNo = remoteMessage.getData().get("enrollmentNo");

                cls = remoteMessage.getData().get("cls");
                sec = remoteMessage.getData().get("sec");
                conType = remoteMessage.getData().get("conType");

                component = remoteMessage.getData().get("component");
                period = remoteMessage.getData().get("period");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        sendNotification(remoteMessage.getNotification().getBody(), id, uid, title, message, type, fcm_notification, stuName, clsSec, imgUrl_old, imgUrl_new, enrollmentNo, cls, sec, conType, component, period);
    }

    private void sendNotification(String body, String user_id, String uid, String title, String message, String type, String fcm_notification, String stuName, String clsSec, String imgUrl_old, String imgUrl_new, String enrollmentNo, String cls, String sec, String conType, String component, String period) {
        try {
            Intent intent = new Intent(this, MainActivity.class);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
            intent.putExtra("fcm_notification", fcm_notification);
            intent.putExtra("title", title);
            intent.putExtra("message", message);
            intent.putExtra("type", type);
            intent.putExtra("id", user_id);
            intent.putExtra("uid", uid);
            intent.putExtra("stuName", stuName);
            intent.putExtra("clsSec", clsSec);
            intent.putExtra("imgUrl_old", imgUrl_old);
            intent.putExtra("imgUrl_new", imgUrl_new);
            intent.putExtra("enrollmentNo", enrollmentNo);
            intent.putExtra("cls", cls);
            intent.putExtra("sec", sec);
            intent.putExtra("conType", conType);
            intent.putExtra("component", component);
            intent.putExtra("period", period);

            int uniqueInt = (int) (System.currentTimeMillis() & 0xff);
            PendingIntent pendingIntent;
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {
                pendingIntent = PendingIntent.getActivity(getApplicationContext(), uniqueInt, intent, PendingIntent.FLAG_MUTABLE);
            } else {
                pendingIntent = PendingIntent.getActivity(getApplicationContext(), uniqueInt, intent, PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE);
            }

            Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
            NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, CHANNEL_ID);
            notificationBuilder.setSmallIcon(R.drawable.app_logo)
                    .setContentText(body)
                    .setAutoCancel(true)
                    .setSound(defaultSoundUri)
                    .setContentIntent(pendingIntent)
                    .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.app_logo))
                    .setColor(ContextCompat.getColor(this, R.color.colorAccent))
                    .setLights(Color.RED, 1000, 300)
                    .setDefaults(Notification.DEFAULT_VIBRATE)
                    .setPriority(NotificationCompat.PRIORITY_HIGH)
                    .setSmallIcon(R.drawable.app_logo);

            NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                NotificationChannel channel = new NotificationChannel(CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT);
                channel.setDescription(CHANNEL_DESC);
                channel.setShowBadge(true);
                channel.canShowBadge();
                channel.enableLights(true);
                channel.setLightColor(Color.RED);
                channel.enableVibration(true);
                channel.setVibrationPattern(new long[]{100, 200, 300, 400, 500});

                assert notificationManager != null;
                notificationManager.createNotificationChannel(channel);
            }

            assert notificationManager != null;
            notificationManager.notify(0, notificationBuilder.build());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

在MainActivity中请求通知权限

public class MainActivity extends AppCompatActivity {
    private static final int REQUEST_NOTIFICATION_PERMISSION = 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.POST_NOTIFICATIONS}, REQUEST_NOTIFICATION_PERMISSION);
            } else {
                // Permission already granted
                showNotification();
            }
        } else {
            // For devices below Android 13, no need to request the permission
            showNotification();
        }
    }

    private void showNotification() {
        // Code to show your notification
        Toast.makeText(this, "Notification permission granted", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_NOTIFICATION_PERMISSION) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // Permission granted
                showNotification();
            } else {
                // Permission denied
                Toast.makeText(this, "Notification permission denied", Toast.LENGTH_SHORT).show();
            }
        }
    }
}

后台服务

public class BackgroundService extends Service {

    private static final int NOTIF_ID = 1;
    private static final String NOTIF_CHANNEL_ID = "Channel_Id";

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

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

    private void startForegroundService() {
        Intent notificationIntent = new Intent(this, MainActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_IMMUTABLE);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // Create Notification Channel
            CharSequence name = getString(R.string.channel_name);
            String description = getString(R.string.channel_description);
            int importance = NotificationManager.IMPORTANCE_DEFAULT;
            NotificationChannel channel = new NotificationChannel(NOTIF_CHANNEL_ID, name, importance);
            channel.setDescription(description);
            NotificationManager notificationManager = getSystemService(NotificationManager.class);
            notificationManager.createNotificationChannel(channel);
        }

        startForeground(NOTIF_ID, new NotificationCompat.Builder(this, NOTIF_CHANNEL_ID)
                .setOngoing(true)
                .setSmallIcon(R.drawable.app_logo)
                .setContentTitle(getString(R.string.app_name))
                .setContentText("Service is running in the background")
                .setContentIntent(pendingIntent)
                .build());
    }
}

前台服务

public class ForegroundService extends Service {
    public static final String CHANNEL_ID = "ForegroundServiceChannel";

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        String input = intent.getStringExtra("inputExtra");
        createNotificationChannel();
        Intent notificationIntent = new Intent(this, MainActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(this,
                0, notificationIntent, PendingIntent.FLAG_IMMUTABLE);
        Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
                .setContentTitle("Foreground Service")
                .setContentText(input)
                .setSmallIcon(R.drawable.app_logo)
                .setContentIntent(pendingIntent)
                .build();
        startForeground(1, notification);
        return START_NOT_STICKY;
    }

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

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    private void createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel serviceChannel = new NotificationChannel(CHANNEL_ID, "Foreground Service Channel",
                    NotificationManager.IMPORTANCE_DEFAULT
            );
            NotificationManager manager = getSystemService(NotificationManager.class);
            manager.createNotificationChannel(serviceChannel);
        }
    }
}

问题:

  1. Android 14(API 级别 34)中的通知是否需要任何其他更改或权限?
  2. Android 14 中的新通知行为是否需要任何特定处理?
  3. Android 14 中是否存在与通知相关的已知问题或错误?

我在 Google 和 ChatGPT 的帮助下尝试了多种选项,但仍未解决。

android permissions notifications firebase-cloud-messaging android-14
1个回答
0
投票

确保您在 MainActivity 中正确请求 POST_NOTIFICATIONS 权限。您现有的代码似乎是正确的,但请确保它正在执行。

或 更新 PendingIntent 标志: 确保您对 PendingIntent 使用适当的标志。具体来说,根据您的需要使用 PendingIntent.FLAG_UPDATE_CURRENT 或其他合适的标志。

PendingIntent 待定意图; 如果(Build.VERSION.SDK_INT >= Build.VERSION_CODES.S){ endingIntent = PendingIntent.getActivity(getApplicationContext(), uniqueInt, 意图, PendingIntent.FLAG_MUTABLE); } 别的 { endingIntent = PendingIntent.getActivity(getApplicationContext(), uniqueInt, 意图, PendingIntent.FLAG_UPDATE_CURRENT); }

© www.soinside.com 2019 - 2024. All rights reserved.