Android 9中的Service.startForeground()问题

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

我正在使用调用REST API的后台服务,并在获取数据后将其发送给用户本地通知,但我在android 9中遇到了Service.startForeground()的问题。请查看代码并为我提供帮助。

NotificationEventReceiver类

public class NotificationEventReceiver extends BroadcastReceiver
{
    static AlarmManager alarmManager;
    static PendingIntent pendingIntent;
    static int count=0;
    static Context mcon;

    public static void setupAlarm(Context context) {
        mcon=context;
        enableBootReciever();

        AppSession.put(Constants.SERVICE_CALL,1);
        Intent service = new Intent(context, NotificationEventReceiver.class);
        service.setAction("Start");
        pendingIntent = PendingIntent.getBroadcast(context, 0, service, PendingIntent.FLAG_UPDATE_CURRENT);
        alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        Calendar calendar = Calendar.getInstance();

        calendar.setTimeInMillis(System.currentTimeMillis());
        calendar.setTime(new Date());


        System.out.println("Log: In the Notification Event Receiver");

        alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
                calendar.getTimeInMillis(),
                10800*1000,
                pendingIntent);
    }

    public static void disableAlarm(Context context) {

        if (alarmManager!=null)
            alarmManager.cancel(pendingIntent);
    }


    static void enableBootReciever(){
        ComponentName receiver = new ComponentName(mcon, NotificationServiceStarterReceiver.class);
        mcon.getPackageManager().setComponentEnabledSetting(receiver,
                PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
                PackageManager.DONT_KILL_APP);
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if(action.equals("Start")) {
            //Log.d("asdkl",Integer.toString(count));
            Intent i = new Intent(context, Service.class);
            //context.startService(i);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                context.startForegroundService(i);
            } else {
                context.startService(i);
            }
        }}}

NotificationServiceStarterReceiver类

    public final class NotificationServiceStarterReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        NotificationEventReceiver.setupAlarm(context);
        System.out.print("Log: In the Notification Service Starter Receiver");

    }}

服务等级

    public class Service extends IntentService {
    String CHANNEL_ID = "999";
    private static String CHANNEL_NAME="My Channel";
    private static String CHANNEL_DESCRIPTION="My Channel Description";

    public Service() {

        super(Service.class.getSimpleName());
    }

    @Override
    protected void onHandleIntent(@Nullable Intent intent) {

        StartListening(getApplicationContext());
    }

    @Override
    public void onCreate() {
        super.onCreate();
        System.out.print("Log: In the Service");

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
            createNotification();

        }else{
            this.startForeground(1,new Notification());
        }
        //getApplicationContext().startForeground(1,new Notification());
    }


    private void createNotification()
    {
        createNotificationChannel();
        Bitmap largeIcon = BitmapFactory.decodeResource(getApplicationContext().getResources(), R.mipmap.ic_launcher);

        Intent intent = new Intent(this, MainActivity.class);
        intent.putExtra("fromNotification", true);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);


        if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
            ShortcutBadger.applyCount(getApplicationContext(), AppSession.getInt(Constants.NOTIFICATION_COUNT));
        }
        final NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID);
        builder.setContentTitle("Scheduled Notification")
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentTitle("Quiz Alert")
                .setContentText("A New Quiz has been scheduled on " + AppSession.get(Constants.QUIZ_DATE_TIME) + ". Kindly don't forget to Join.")
                .setChannelId(CHANNEL_ID)
                .setLargeIcon(largeIcon)
                .setNumber(AppSession.getInt(Constants.NOTIFICATION_COUNT))
                .setBadgeIconType(NotificationCompat.BADGE_ICON_SMALL)
                .setVibrate(new long[]{1000, 1000, 1000, 1000, 1000})
                .setAutoCancel(true)
                .setSound(Settings.System.DEFAULT_NOTIFICATION_URI)
                .setColor(getResources().getColor(R.color.colorAccent))
                .setPriority(NotificationCompat.PRIORITY_DEFAULT)
                .setContentIntent(pendingIntent)
                .setStyle(new NotificationCompat.BigTextStyle().bigText("A New Quiz has been scheduled on " + AppSession.get(Constants.QUIZ_DATE_TIME) + ". Kindly don't forget to Join."))
                .setGroup("TEST");

        final NotificationManagerCompat manager = NotificationManagerCompat.from(this);
        manager.notify(2, builder.build());

    }



    private void createNotificationChannel() {
        // Create the NotificationChannel, but only on API 26+ because
        // the NotificationChannel class is new and not in the support library

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            int importance = NotificationManager.IMPORTANCE_DEFAULT;
            NotificationChannel channel = new NotificationChannel(CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT);
            channel.setDescription(CHANNEL_DESCRIPTION);
            NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
            notificationManager.createNotificationChannel(channel);
        }
    }

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

    public void StartListening(final Context mcontext) {


        Log.d("In StartListening",("Listening " + Integer.toString(count)));
        System.out.println("In StartListening " + Integer.toString(count));


        //    Toast.makeText(mcontext, "In StartListening", Toast.LENGTH_SHORT).show();
        new RestCaller(new iResponseHandler() {
            @Override
            public void onSuccess(Call call, Response response, int reqCode) {
                if (reqCode == Constants.REQUEST_CODE_QUIZ_DATE) {
                    AppSession.put(Constants.KEY_API_CALL,0);
                    QuizDatePOJO quizDatePojo = (QuizDatePOJO) response.body();

                    if(quizDatePojo.getResponse().getDate()==null){

                    }else{
                        SimpleDateFormat inputFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
                        SimpleDateFormat outputFormat = new SimpleDateFormat("dd-MM-yyyy");
                        Date date = null;
                        try {
                            date = inputFormat.parse(quizDatePojo.getResponse().getDate());
                        } catch (ParseException e) {
                            e.printStackTrace();
                        }
                        String formattedDate = outputFormat.format(date);
                        String time =quizDatePojo.getResponse().getTime();
                        AppSession.put(Constants.QUIZ_DATE_TIME,formattedDate+" "+time);
                        createNotification();

                    }
                }
            }

            @Override
            public void onFailure(Call call, Response response, int reqCode) {
                AppSession.put(Constants.KEY_API_CALL,"FAILED");
                StartListening(mcontext);
                Loading.cancel();

            }

            @Override
            public void onApiCrash(Call call, Throwable t, int reqCode) {
                AppSession.put(Constants.KEY_API_CALL,"FAILED");
                StartListening(mcontext);
                Loading.cancel();

            }
        }, MainApplication.getRestClient()
                .getApiServices().getQuizDate(), Constants.REQUEST_CODE_QUIZ_DATE);

    }}

请在此处指导需要进行哪些更改。此问题在Android 9中出现,并且通知弹出后,应用就会崩溃

日志致命异常:android.app.RemoteServiceException:Context.startForegroundService()然后未调用Service.startForeground():ServiceRecord {a341388 u0 com.developer.emten / .services.Service}在android.app.ActivityThread $ H.handleMessage + 2112(ActivityThread.java:2112)在android.os.Handler.dispatchMessage + 112(Handler.java:112)在android.os.Looper.loop + 216(Looper.java:216)在android.app.ActivityThread.main + 7593(ActivityThread.java:7593)在java.lang.reflect.Method.invoke(Method.java)在com.android.internal.os.RuntimeInit $ MethodAndArgsCaller.run + 524(RuntimeInit.java:524)在com.android.internal.os.ZygoteInit.main + 987(ZygoteInit.java:987)

service notifications foreground-service
1个回答
0
投票
解决方案是在AndroidManifest.xml中添加以下内容:

<manifest ...> ... <uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> ... <application ...> ... </manifest>

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