0

I know than this bug was commented in other blogs but I've tried to correct this and I did not succeed.

Only happend in android 8+, but in simulator of Android Studio works fine.

I have an app than activate a notification in some specific date, this notification remember some task for user. This works fine in android 7 or lower but in Android 8+ don't works. App works fine, but notification don't appear and in google Play is activated an ERROR.

My app never crash, only shows that error into Google Play console.

This is the bug in PlayStore Console:

java.lang.RuntimeException: 
    at android.app.ActivityThread.handleReceiver (ActivityThread.java:3606)
    at android.app.ActivityThread.access$1300 (ActivityThread.java:237)
    at android.app.ActivityThread$H.handleMessage (ActivityThread.java:1796)
    at android.os.Handler.dispatchMessage (Handler.java:106)
    at android.os.Looper.loop (Looper.java:214)
    at android.app.ActivityThread.main (ActivityThread.java:7045)
    at java.lang.reflect.Method.invoke (Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:493)
    at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:964)
Caused by: java.lang.IllegalStateException: 
    at android.app.ContextImpl.startServiceCommon (ContextImpl.java:1666)
    at android.app.ContextImpl.startService (ContextImpl.java:1611)
    at android.content.ContextWrapper.startService (ContextWrapper.java:677)
    at android.content.ContextWrapper.startService (ContextWrapper.java:677)
    at com.example.tomas.memoru.R_Activate.onReceive (R_Activate.java:45)
    at android.app.ActivityThread.handleReceiver (ActivityThread.java:3597)

And this is my source code:

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.tomas.memoru" >

    <permission android:name="com.example.tomas.memoru.permission.C2D_MESSAGE" android:protectionLevel="signature" />

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-feature
        android:glEsVersion="0x00020000"
        android:required="true"/>

    <application
        android:name="com.example.tomas.memoru.R_Variables1"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/Theme.AppCompat.Light.DarkActionBar" >

        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />

        <receiver
            android:name=".R_Activate">
                    <intent-filter>
                        <action android:name="android.intent.action.BOOT_COMPLETED" />

                        <category android:name="android.intent.category.DEFAULT" />
                    </intent-filter>
                </receiver>

                <service android:name="com.example.tomas.memoru.R_Activate_generador" />

                <service android:name="com.example.tomas.memoru.GcmIntentService" />


                <receiver android:name="com.example.tomas.memoru.R_NotificationPublisher" />


                <activity
                    android:name="com.example.tomas.memoru.R_Pantalla_Main"
                    android:screenOrientation="portrait"
                    android:configChanges="orientation|screenSize"
                    android:launchMode="singleInstance"
                    android:label="@string/app_name" >
                    <intent-filter>
                        <action android:name="android.intent.action.MAIN" />

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

        </manifest>

R_Activate.java

package com.example.tomas.memoru;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import java.util.ArrayList;

public class R_Activate extends BroadcastReceiver {
    Integer cont1 = 0;

    @Override
    public void onReceive(Context context, Intent intent) {

        if (intent.getAction().equalsIgnoreCase(Intent.ACTION_BOOT_COMPLETED)) {
            intent = new Intent(context,R_Activate_generador.class);
            context.startService(intent);
            Log.i("Autostart", "started");
        }
    }
}

R_Activate_generator.java

package com.example.tomas.memoru;

import android.app.AlarmManager;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.os.Build;
import android.os.IBinder;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Locale;
import java.util.TimeZone;

public class R_Activate_generador extends Service {
    ArrayList<String> task_cargar = new ArrayList<>();
    Integer cont1=0;
    static final int READ_BLOCK_SIZE = 100;

    private static final String TAG = "MyService";
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
    public void onDestroy() {
        super.onDestroy();
        stopForeground(true);

    }

    @Override
    public void onStart(Intent intent, int startid) {

        cargadatosfile(); //this works fine, only charge information to check date and tasks
        if(cont1>0){
            scheduleNotification(getNotification("30 second delay"), 0);//this put notification

        }
    }

    private void cargadatosfile() {

        //this function works fine, only charge information to schedule the tasks
    }

    private void scheduleNotification(Notification notification, int delay) {


        R_Variables1 comparteVariables = ((R_Variables1) getApplicationContext());


        String s = "";
        Integer temp_id = 0, masXdias=0;
        String[] strValues_temp1;

        Calendar today = Calendar.getInstance(TimeZone.getDefault(), Locale.getDefault());

        cont1 = 0;

        while (cont1 < task_cargar.size()) {

            strValues_temp1 = task_cargar.get(cont1).split(";");


            String[] strValues_time1 = strValues_temp1[11].split(" ");
            String[] strValues_time2 = strValues_time1[1].split(":");
            String[] strValues_date1 = strValues_time1[0].split("-");

            Calendar cal = Calendar.getInstance(TimeZone.getDefault(), Locale.getDefault());

            cal.set(Calendar.DATE, Integer.valueOf(strValues_date1[2]) + masXdias);  //1-31
            cal.set(Calendar.MONTH, Integer.valueOf(strValues_date1[1]) - 1);  //first month is 0!!! January is zero!!!
            cal.set(Calendar.YEAR, Integer.valueOf(strValues_date1[0]));//year...


            cal.set(Calendar.HOUR_OF_DAY, Integer.valueOf(strValues_time2[0]));  //HOUR
            cal.set(Calendar.MINUTE, Integer.valueOf(strValues_time2[1]));       //MIN
            cal.set(Calendar.SECOND, 0);       //SEC

            if (cal.after(today) ) {//fecha futura es la de File
                Intent notificationIntent = new Intent(this, R_NotificationPublisher.class);
                notificationIntent.putExtra(R_NotificationPublisher.NOTIFICATION_ID, Integer.valueOf(strValues_temp1[0]));// se reemplazo 1 por max_id
         //                notificationIntent.putExtra(R_NotificationPublisher.NOTIFICATION, notification);
                PendingIntent pendingIntent = PendingIntent.getBroadcast(this, Integer.valueOf(strValues_temp1[0]), notificationIntent, PendingIntent.FLAG_ONE_SHOT);//FLAG_UPDATE_CURRENT // se reemplazo 0 por max_id

                AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
                if(Build.VERSION.SDK_INT < 23){
                    alarmManager.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);
                }
                else{
                    alarmManager.setAlarmClock(new AlarmManager.AlarmClockInfo(cal.getTimeInMillis(), pendingIntent), pendingIntent);
                }

                masXdias=0;
                cont1++;
            }
            else{
                masXdias=masXdias+1;
            }


        }


    }

    private Notification getNotification(String content) {


        Notification.Builder builder = new Notification.Builder(this);
        builder.setContentTitle("Scheduled Notification");
        builder.setContentText(content);
        builder.setSmallIcon(getNotificationIcon());
        builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.movando2_xx));
        builder.setAutoCancel(true);
        return builder.build();
    }

    private int getNotificationIcon() {
        boolean useWhiteIcon = (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP);
        return useWhiteIcon ? R.drawable.movando2_xxbl : R.drawable.movando2_xx;
    }
}

There are other java modules in my application, but the bug is in somewhere place of these code.

Thank you very much for your help, any hint and feedback is appreciated!.

Edwin

  • The stacktrace points to line 45 of R_Activate. This might help you find that on your own https://stackoverflow.com/questions/12688068/how-to-read-and-understand-the-java-stack-trace – DCTID Oct 10 '19 at 03:35
  • 8.0+ you should use notification channel, on [the android develop](https://developer.android.com/training/notify-user/channels), you can see the declared – Lenoarod Oct 10 '19 at 05:17

0 Answers0