基于AltBeacon的应用在Android Pie崩溃及模拟器测试问题求助
Hey there! Let's break down and fix your Android Pie crash and emulator issues step by step.
First: The Crash Root Cause
Your crash log clearly points to an invalid notification channel for the foreground service:
Fatal Exception: android.app.RemoteServiceException: Bad notification for startForeground: java.lang.RuntimeException: invalid channel for service notification: Notification(channel=My Notification Channel ID pri=0 ...)
Looking at your code, you're creating a channel with ID My Notification ID but the crash shows the notification is using My Notification Channel ID—a mismatch! Plus, you have a defined CHANNEL_ID constant that isn't being used consistently. Let's fix that.
Fixed Notification Channel & Foreground Service Code
public class MyApplication extends Application implements BootstrapNotifier { private static final String TAG = ".RangingActivity"; public static final String CHANNEL_ID = "Geotoppng"; // Use this constant everywhere // ... your other variables ... @Override public void onCreate() { Log.d(TAG, "App started up"); getshareddata = new Sharedpreferncedatasource(this); navigationAppRepository = new NavigationAppRepository(getshareddata); beaconManager = BeaconManager.getInstanceForApplication(this); beaconManager.getBeaconParsers().add(new BeaconParser() .setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25")); // Critical Fix: Your UUID has invalid characters! "KEKL" isn't hexadecimal identifier = Identifier.parse("E2C56DB5-1234-48D2-B060-D0F5A71096E0"); beaconManager.setBackgroundBetweenScanPeriod(3001); beaconManager.setBackgroundScanPeriod(5001); // Create notification channel FIRST for Android Oreo+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { NotificationChannel channel = new NotificationChannel(CHANNEL_ID, "Beacon Scanning Service", NotificationManager.IMPORTANCE_DEFAULT); channel.setDescription("Foreground service to scan for AltBeacons"); NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); if (notificationManager != null) { notificationManager.createNotificationChannel(channel); } } // Build the notification with the correct channel ID Notification.Builder builder; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // Use the channel ID directly in the builder constructor for Oreo+ builder = new Notification.Builder(this, CHANNEL_ID); } else { builder = new Notification.Builder(this); } builder.setSmallIcon(R.mipmap.ic_launcher); builder.setContentTitle("Scanning for Beacons"); Intent intent = new Intent(this, SplashActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity( this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT ); builder.setContentIntent(pendingIntent); beaconManager.enableForegroundServiceScanning(builder.build(), 456); beaconManager.setEnableScheduledScanJobs(false); region = new Region("com.example.myapp.boostrapRegion", identifier, null, null); regionBootstrap = new RegionBootstrap(this, region); // Setup beacon simulator for emulator BeaconManager.setBeaconSimulator(new TimedBeaconSimulator()); ((TimedBeaconSimulator) BeaconManager.getBeaconSimulator()).createTimedSimulatedBeacons(); super.onCreate(); } // ... rest of your existing methods ... }
Second: Fix the Invalid UUID
Your current beacon UUID (E2C56DB5-KEKL-48D2-B060-D0F5A71096E0) uses KEKL—which isn't valid hexadecimal (UUID segments only accept 0-9, A-F). Replace that segment with a valid 4-character hex string (like 1234 or ABCD) to ensure your region is recognized correctly.
Third: Get the App Running on Emulators
Emulators don't have physical Bluetooth hardware, so we need to tweak a few things:
- Enable Bluetooth in the emulator: Go to the emulator's settings and turn on Bluetooth (supported on API 26+ emulators).
- Declare all required permissions in your
AndroidManifest.xml:<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <!-- For API 31+ --> <uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" /> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> - Request location permission dynamically: Android 6.0+ requires runtime permission requests for location. Add code to ask for
ACCESS_FINE_LOCATIONin yourSplashActivitybefore any beacon scanning starts. - Verify simulated beacons match your region: The
TimedBeaconSimulatorcreates beacons with a default UUID—make sure it matches the fixed UUID you set in your code, or customize the simulator to use your target UUID.
Final Checks
- Clear your app's data on the OnePlus 6T to remove any cached invalid notification channels.
- For Android 12+, add the foreground service type to the Beacon Service declaration in your manifest:
<service android:name="org.altbeacon.beacon.service.BeaconService" android:foregroundServiceType="location" />
After making these changes, your app should stop crashing on Android Pie and work as expected on emulators with simulated beacons.
内容的提问来源于stack exchange,提问作者kavinmkk6

