それで、私はストアに50000ユーザーのアプリを持っています。最近、Androidスタジオを更新し、SDKを27にコンパイルしました。通知の変更を含むAndroid 8の変更をサポートするためにいくつかの変更を加えました(たとえば、通知には一意のチャネルが必要です)。これをAndroid 1台の電話でテストしました(Android 8を実行)。そして、すべてがスムーズに行きました。 Playstoreでアプリを更新した後、Android 8デバイス(主にGoogle Pixelスマートフォン)でこれらのクラッシュが発生する
Fatal Exception: Android.app.RemoteServiceException: Bad notification for startForeground: Java.lang.RuntimeException: invalid channel for service notification: Notification(channel=null pri=-2 contentView=null vibrate=null sound=null defaults=0x0 flags=0x40 color=0xffffcf00 actions=3 vis=PRIVATE)
at Android.app.ActivityThread$H.handleMessage(ActivityThread.Java:1768)
at Android.os.Handler.dispatchMessage(Handler.Java:106)
at Android.os.Looper.loop(Looper.Java:164)
at Android.app.ActivityThread.main(ActivityThread.Java:6494)
at Java.lang.reflect.Method.invoke(Method.Java)
at com.Android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.Java:438)
at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:807)
Crashlyticsでこれらのエラーのうち7つが表示されます。それぞれに同じログがあり、約10人のユーザーに対して約5000以上のクラッシュがあります。したがって、見たところアプリはループでクラッシュしていました。
私が抱えている問題は、これらのログが、このクラッシュを開始しているアプリのソースを確認できる場所からのログを提供しないことですこれをスローしているクラスを見つける方法はありますか?クラッシュ?何か助けは?
また、私はこの通知用のコードを持っています:
if (Android.os.Build.VERSION.SDK_INT >= Android.os.Build.VERSION_CODES.O) {
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel mChannel = notificationManager.getNotificationChannel(id);
if (mChannel == null) {
mChannel = new NotificationChannel(id, name, importance);
mChannel.setDescription(description);
notificationManager.createNotificationChannel(mChannel);
}
}
NotificationCompat.Builder builder = new NotificationCompat.Builder(context,id);
builder.setContentTitle(pushMessages.size() + context.getString(R.string.new_notification))
.setContentIntent(pendingIntent)
.setContentText(pushMessages.get(0))
.setStyle(inboxStyle)
.setGroup(GROUP_KEY_NOTIFICATIONS)
.setGroupSummary(true)
.setAutoCancel(true);
if (Android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.Lollipop) {
builder.setSmallIcon(R.drawable.notification_img)
.setColor(context.getResources().getColor(R.color.settings_yellow));
} else {
builder.setSmallIcon(R.mipmap.ic_launcher);
}
summaryNotification = builder.build();
notificationManager.notify(i、summaryNotification);
サービスクラスを使用している場合は、このコードを置くことができます
public class BlablaService extends Service
@Override
public void onCreate(){
super.onCreate();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
startMyOwnForeground();
else
startForeground(1, new Notification());
}
private void startMyOwnForeground(){
String NOTIFICATION_CHANNEL_ID = "com.example.simpleapp";
String channelName = "My Background Service";
NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_NONE);
chan.setLightColor(Color.BLUE);
chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
assert manager != null;
manager.createNotificationChannel(chan);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
Notification notification = notificationBuilder.setOngoing(true)
.setSmallIcon(R.drawable.icon_1)
.setContentTitle("App is running in background")
.setPriority(NotificationManager.IMPORTANCE_MIN)
.setCategory(Notification.CATEGORY_SERVICE)
.build();
startForeground(2, notification);
}
もちろん、ForeGroundServiceのアクセス許可をAndroidManifest.xmlにすることを忘れないでください。
<uses-permission Android:name="Android.permission.FOREGROUND_SERVICE" />
通知のチャネルIDを設定するのを忘れました。
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) builder.setChannelId(youChannelID);
if
ステートメントはオプションであり、Min SDKレベルによって異なります。
はい、どのクラスがこのエラーをスローしているかを確認する方法があります。したがって、まず最初に、どのクラスがService.startForeground
を呼び出しているかを調べる必要があります。そのクラスがそれをスローする可能性があります。
Android Studioを使用して、Service
クラスのソースコードに移動し、startForeground
メソッドを見つけます。ctrl
(またはCommand
(Macの場合)、メソッドシグネチャをクリックします。ドキュメントの参照を含め、そのメソッドを呼び出しているすべてのライブラリのクラスが一覧表示されます。
私はまだ同じ問題に直面しています。 RoboSpice(現在アーカイブされています)がこれらのエラーをスローしていると思います。見つける唯一の方法は、他のものを使用するようにすべてのコードベースをリファクタリングすることです(おそらくRx + Retrofit)。
8.1では、独自の通知チャネルを作成する必要があるようです。
private void startForeground() {
String channelId ="";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
createNotificationChannel("my_service", "My Background Service");
}else{
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(getApplicationContext(), channelId);
Notification notification = notificationBuilder.setOngoing(true)
.setSmallIcon(R.mipmap.ic_launcher)
.setPriority(PRIORITY_MIN)
.setCategory(Notification.CATEGORY_SERVICE)
.build();
startForeground(101, notification);
}
}
以降
@RequiresApi(Build.VERSION_CODES.O)
private String createNotificationChannel(String channelId ,String channelName){
NotificationChannel chan = new NotificationChannel(channelId,
channelName, NotificationManager.IMPORTANCE_NONE);
chan.setLightColor(Color.BLUE);
chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager.createNotificationChannel(chan);
return channelId;
}
更新:また、必要に応じてフォアグラウンド権限を追加することも忘れないでくださいAndroid P:
<uses-permission Android:name="Android.permission.FOREGROUND_SERVICE" />
私のアプリケーションでこの問題を解決したところ、何が起こったかというと、通知を使用するクラスで、NotificationChannelのCHANNEL_IDとCHANNEL_NAMEを文字列と定数、静的または最終変数に保持しましたが、それらの値をXML Resource.Stringは、私が決して変更しない値であり、GetString(Resource.String.CH_NAME_GPS_ERROR_ID)を使用して取得するため、理由はわかりませんが、問題が解決することを願っています。