Android中PDF文件生成保存后显示系统通知栏通知的实现方法问询
Got it, let's swap those temporary Toasts with persistent system notifications that users can see even if they're not looking at your app right now. Here's how to implement this properly for Android:
Step 1: Add Required Permissions
First, update your AndroidManifest.xml to include the necessary permissions. For Android 13 (API level 33) and above, you need the POST_NOTIFICATIONS permission to send notifications. You'll also need storage permissions if your target SDK is below Android 10 (API 29):
<!-- For Android 13+ --> <uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> <!-- For SDK < 29 (optional if using scoped storage) --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="28" />
If your app targets API 33+, you'll need to request the POST_NOTIFICATIONS permission dynamically. Add this code to your RegistrationActivity (e.g., in onCreate):
private static final int REQUEST_CODE_NOTIFICATIONS = 101; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_registration); // Request notification permission for Android 13+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) { ActivityResultContracts.RequestPermission requestPermission = new ActivityResultContracts.RequestPermission(); registerForActivityResult(requestPermission, isGranted -> { if (!isGranted) { // Handle permission denial (e.g., show a dialog explaining why you need it) } }).launch(Manifest.permission.POST_NOTIFICATIONS); } } // Create notification channel (required for Android O+) createNotificationChannel(); }
Step 2: Create a Notification Channel (Android 8.0+)
Notifications won't show on Android 8.0 (API 26) or higher unless you create a notification channel. Add this method to your RegistrationActivity:
private void createNotificationChannel() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { CharSequence name = getString(R.string.notification_channel_name); // Define this in strings.xml String description = getString(R.string.notification_channel_description); // Define this too int importance = NotificationManager.IMPORTANCE_DEFAULT; NotificationChannel channel = new NotificationChannel("PDF_GENERATION_CHANNEL", name, importance); channel.setDescription(description); // Register the channel with the system NotificationManager notificationManager = getSystemService(NotificationManager.class); notificationManager.createNotificationChannel(channel); } }
Don't forget to add the channel name and description to your res/values/strings.xml:
<string name="notification_channel_name">PDF Generation</string> <string name="notification_channel_description">Notifications for PDF creation status</string>
Step 3: Update Your PDF Generation Method to Send Notifications
Now replace the Toast calls with code that sends system notifications. We'll create two helper methods for success and error cases, then call them in your try/catch block:
Helper Methods for Notifications
Add these to your RegistrationActivity:
private void sendSuccessNotification(String fileName) { // Create an intent to open the Downloads folder (optional but user-friendly) Intent intent = new Intent(DownloadManager.ACTION_VIEW_DOWNLOADS); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_IMMUTABLE); NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "PDF_GENERATION_CHANNEL") .setSmallIcon(R.drawable.ic_notification) // Replace with your app's notification icon .setContentTitle("PDF Generated Successfully") .setContentText("Coupon saved to Downloads: " + fileName) .setPriority(NotificationCompat.PRIORITY_DEFAULT) .setContentIntent(pendingIntent) .setAutoCancel(true); // Dismiss notification when tapped NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this); notificationManager.notify(1, builder.build()); // Use a unique ID for each notification } private void sendErrorNotification() { NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "PDF_GENERATION_CHANNEL") .setSmallIcon(R.drawable.ic_notification) .setContentTitle("PDF Generation Failed") .setContentText("There was an error creating your coupon PDF.") .setPriority(NotificationCompat.PRIORITY_DEFAULT) .setAutoCancel(true); NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this); notificationManager.notify(2, builder.build()); }
Modified createDocumentAboutRegistration Method
Update your existing method to call these notification helpers instead of Toast:
public void createDocumentAboutRegistration(User user){ PdfDocument myPdfDocument = new PdfDocument(); PdfDocument.PageInfo myPageInfo = new PdfDocument.PageInfo.Builder(300,600,1).create(); PdfDocument.Page myPage = myPdfDocument.startPage(myPageInfo); Paint myPaint = new Paint(); String myString = user.toString(); int x = 10, y=25; for (String line:myString.split("\\n")){ myPage.getCanvas().drawText(line, x, y, myPaint); y+=myPaint.descent()-myPaint.ascent(); } myPdfDocument.finishPage(myPage); String myFilePath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString(); String nameFile = "coupon-" + user.lastName + ".pdf"; File myFile = new File(myFilePath, nameFile); try { myPdfDocument.writeTo(new FileOutputStream(myFile)); // Replace Toast with success notification sendSuccessNotification(nameFile); } catch (Exception e){ e.printStackTrace(); // Replace Toast with error notification sendErrorNotification(); } myPdfDocument.close(); }
Key Notes
- Notification Icon: Make sure you have a proper notification icon (
ic_notification) in your drawable resources. Android requires a white icon on a transparent background for best results. - Pending Intent: The example uses an intent to open the Downloads folder when the notification is tapped—this is a nice touch for user experience, but you can replace it with any intent (e.g., opening your app's main activity).
- Notification IDs: Use unique IDs for each notification type (we used 1 for success, 2 for error) so they don't overwrite each other.
内容的提问来源于stack exchange,提问作者Artem Barabash

