# Notification builder

**URL:** https://discourse.processing.org/t/notification-builder/1101
**Category:** Processing for Android
**Created:** [June 19, 2018, 8:12pm UTC](https://discourse.processing.org/t/notification-builder/1101 "2018-06-19T20:12:13Z")
**Posts on this page:** 13
**Page:** 1

<div class="post-metadata">

### Author: ![basher24](https://avatars.discourse-cdn.com/v4/letter/b/ee7513/32.png) [@basher24](https://discourse.processing.org/u/basher24)
#### Post date: [June 19, 2018, 8:12pm UTC](https://discourse.processing.org/t/notification-builder/1101/1 "2018-06-19T20:12:13Z")

</div>

I built an android app that gets a message from a server and pass it to the notification … every thing work wonderful … when i close the app (shutdown) … i stop getting the notification …  
how can i make my app working at the background like “whatsApp” when it closed she still getting messages  
i read and try sketch’s from the net … but no success …

help me … plzzzzzzzzzzzzz

thanx a lot

---

<div class="post-metadata">

### Author: ![Andres](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/andres/32/18007_2.png) [@Andres](https://discourse.processing.org/u/Andres)
#### Post date: [June 20, 2018, 2:28pm UTC](https://discourse.processing.org/t/notification-builder/1101/2 "2018-06-20T14:28:26Z")

</div>

@basher24 You could create a [foreground service](https://developer.android.com/guide/components/services) from your sketch.

I quickly adapted some code from a larger project:

service\_demo.pde

```java
void setup() {
  fullScreen();
  initService();
}

void draw() {
  background(180);

  if (instance != null) {
    println("Service is running:", instance.running);
  }
}

void initService() {
  Intent startIntent = new Intent(getActivity(), DummyService.class);
  getActivity().startService(startIntent);
}

void stop() {
  if (instance != null) {
    instance.stop();
  }
}

```

DummyService.pde

```java
import android.app.Service;
import android.os.Handler;
import android.os.IBinder;
import android.content.Intent;
import android.app.Notification;
import android.app.PendingIntent;

DummyService instance;

class DummyService extends Service {
  static final String TAG = "DummyService";
  static final int FOREGROUND_NOTIFICATION_ID = 1;

  boolean running = false;
  Handler handler = new Handler();
  Runnable runnable;
  
  int WAIT_SECONDS = 30;

  @Override
  void onCreate() {
    super.onCreate();
    start();
    instance = this;
  }

  @Override
  void onDestroy() {
    stop();
    super.onDestroy();
  }

  @Override
  IBinder onBind(Intent intent) {
    // Used only in case of bound services.
    return null;
  }

  void start() {
    goForeground();
    workLoop();
    running = true;
  }
  
  void stop() {
    running = false;
  }
  
  void goForeground() {
    Intent notificationIntent = new Intent(this, getActivity().getClass());
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
    Notification n = new Notification.Builder(this)
            .setContentTitle("Dummy Service")
            .setContentText("Testing foreground services from Processing.")
            .setContentIntent(pendingIntent)
            .build();
    startForeground(FOREGROUND_NOTIFICATION_ID, n);    
  }
  
  void workLoop() {
    runnable = new Runnable() {
      @Override
      public void run() {
        // Do something
      }
    };
    if (running) {
      handler.postDelayed(runnable, WAIT_SECONDS * 1000);
    }
  }
}

```

I hope this can get you going!

---

<div class="post-metadata">

### Author: ![basher24](https://avatars.discourse-cdn.com/v4/letter/b/ee7513/32.png) [@basher24](https://discourse.processing.org/u/basher24)
#### Post date: [June 21, 2018, 9:31am UTC](https://discourse.processing.org/t/notification-builder/1101/3 "2018-06-21T09:31:50Z")

</div>

thanks andres

i try to lunch the program but i still get null

for the variable “instance”

basher

---

<div class="post-metadata">

### Author: ![Andres](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/andres/32/18007_2.png) [@Andres](https://discourse.processing.org/u/Andres)
#### Post date: [June 21, 2018, 12:22pm UTC](https://discourse.processing.org/t/notification-builder/1101/4 "2018-06-21T12:22:03Z")

</div>

Ok… I missed a couple of important things. Firs of all, the service class needs to be declared in the manifest file… and also think the source file for DummyService should be a .java instead of .pde, so…

service\_demo.pde

```java
import android.content.Intent;

void setup() {
  fullScreen();
  initService();
}

void draw() {
  background(180);

  if (DummyService.instance != null) {
    println("Service is running:", DummyService.instance.running);
  }
}

void initService() {
  DummyService.activity = getActivity();
  Intent startIntent = new Intent(getActivity(), DummyService.class);
  getActivity().startService(startIntent);
}

void stop() {
  if (DummyService.instance != null) {
    DummyService.instance.stop();
  }
}

```

DummyService.java

```java
import android.app.Activity;
import android.app.Service;
import android.os.Handler;
import android.os.IBinder;
import android.content.Intent;
import android.app.Notification;
import android.app.PendingIntent;

class DummyService extends Service {
  static final String TAG = "DummyService";
  static final int FOREGROUND_NOTIFICATION_ID = 1;

  static Activity activity;
  static DummyService instance;

  boolean running = false;
  Handler handler = new Handler();
  Runnable runnable;
  
  int WAIT_SECONDS = 30;

  @Override
  public void onCreate() {
    System.out.println("Created service");
    super.onCreate();
    start();
    instance = this;
  }

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

  @Override
  public IBinder onBind(Intent intent) {
    // Used only in case of bound services.
    return null;
  }

  void start() {
    goForeground();
    workLoop();
    running = true;
  }
  
  void stop() {
    running = false;
  }
  
  void goForeground() {
    Intent notificationIntent = new Intent(this, activity.getClass());
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
    Notification n = new Notification.Builder(this)
            .setContentTitle("Dummy Service")
            .setContentText("Testing foreground services from Processing.")
            .setContentIntent(pendingIntent)
            .build();
    startForeground(FOREGROUND_NOTIFICATION_ID, n);    
  }
  
  void workLoop() {
    runnable = new Runnable() {
      @Override
      public void run() {
        // Do something
      }
    };
    if (running) {
      handler.postDelayed(runnable, WAIT_SECONDS * 1000);
    }
  }
}

```

and the manifest file:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="">
    <uses-sdk android:minSdkVersion="17" android:targetSdkVersion="26"/>
    <application android:icon="@drawable/icon" android:label="">
        <activity android:name=".MainActivity" android:theme="@style/Theme.AppCompat.Light.NoActionBar.FullScreen">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
        <service android:enabled="true" android:exported="false" android:name=".DummyService"/>
    </application>
</manifest>

```

---

<div class="post-metadata">

### Author: ![basher24](https://avatars.discourse-cdn.com/v4/letter/b/ee7513/32.png) [@basher24](https://discourse.processing.org/u/basher24)
#### Post date: [June 21, 2018, 2:20pm UTC](https://discourse.processing.org/t/notification-builder/1101/5 "2018-06-21T14:20:29Z")

</div>

Now I have this error 🙂

FATAL EXCEPTION: main  
Process: processing.test.service\_demo, PID: 2514  
java.lang.RuntimeException: Unable to instantiate service processing.test.service\_demo.DummyService: java.lang.IllegalAccessException: java.lang.Class\<processing.test.service\_demo.DummyService\> is not accessible from java.lang.Class\<android.app.ActivityThread\>  
at android.app.ActivityThread.handleCreateService(ActivityThread.java:3446)  
at android.app.ActivityThread.-wrap6(ActivityThread.java)  
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1725)  
at android.os.Handler.dispatchMessage(Handler.java:102)  
at android.os.Looper.loop(Looper.java:154)  
at android.app.ActivityThread.main(ActivityThread.java:6692)  
at java.lang.reflect.Method.invoke(Native Method)  
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468)  
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358)  
Caused by: java.lang.IllegalAccessException: java.lang.Class\<processing.test.service\_demo.DummyService\> is not accessible from java.lang.Class\<android.app.ActivityThread\>  
at java.lang.Class.newInstance(Native Method)  
at android.app.ActivityThread.handleCreateService(ActivityThread.java:3443)  
… 8 more

---

<div class="post-metadata">

### Author: ![Andres](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/andres/32/18007_2.png) [@Andres](https://discourse.processing.org/u/Andres)
#### Post date: [June 22, 2018, 12:36pm UTC](https://discourse.processing.org/t/notification-builder/1101/6 "2018-06-22T12:36:18Z")

</div>

Declare the DummyService class as public, i.e.:

```java
public class DummyService extends Service {

```

Just noticed another error in my example, the runnable should post itself at the end of the run() method to keep the process going in the background:

```java
  void workLoop() {
    System.out.println("launching...");
    runnable = new Runnable() {
      @Override
      public void run() {
        System.out.println("working...");
        if (running) {
          handler.postDelayed(runnable, WAIT_SECONDS * 1000);
        }        
      }
    };
    handler.postDelayed(runnable, WAIT_SECONDS * 1000);    
  }

```

With these changes, you should see the message “working…” every two seconds even if the app is in the background.

---

<div class="post-metadata">

### Author: ![basher24](https://avatars.discourse-cdn.com/v4/letter/b/ee7513/32.png) [@basher24](https://discourse.processing.org/u/basher24)
#### Post date: [June 23, 2018, 10:20am UTC](https://discourse.processing.org/t/notification-builder/1101/7 "2018-06-23T10:20:57Z")

</div>

thank you very much 😊😊😊😊  
its work very fine …

I insert whats inside setup() to my setup() program .  
and add the functions below draw() to my sketch …

my sketch name is “AnnexSafe” … which reports building worker accidents or hazard from the field to an office server (excel sheet) … and receive notification from the server If the issue has not been addressed .

so , i didnt access my App when i tap the notification … i try some codes from internet … no access

I respect your help  
thanx  
basher

---

<div class="post-metadata">

### Author: ![basher24](https://avatars.discourse-cdn.com/v4/letter/b/ee7513/32.png) [@basher24](https://discourse.processing.org/u/basher24)
#### Post date: [June 25, 2018, 6:47am UTC](https://discourse.processing.org/t/notification-builder/1101/8 "2018-06-25T06:47:26Z")

</div>

hi andres ,

basher again … short question … how can i ran a function from my (processing sketch) inside run() at the DummyService.java ?

the function (listed below) is checking\trying connection between server and client …

public void MyConnection()  
{

client = new MuKCastClient(this, ServerIP, int(ServerPort));

```
                try {

                     client.connect();     
                     ConnectStatus = "Connected";

                } catch(IOException e) {
                                   // e.printStackTrace();   
                                        ConnectStatus = "disConnected";
                                        }

```

}

thanx ;  
basher

---

<div class="post-metadata">

### Author: ![Andres](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/andres/32/18007_2.png) [@Andres](https://discourse.processing.org/u/Andres)
#### Post date: [June 25, 2018, 12:55pm UTC](https://discourse.processing.org/t/notification-builder/1101/9 "2018-06-25T12:55:36Z")

</div>

Hi, the tricky part of using services is that the code in the java file does not know anything about the sketch, you need to explicitly send a reference to the sketch object so the service can access all your functions. A not-very elegant way to do this, but which seems to work, is as follows (only listing the changes):

AndroidService.pde

```java
...
void draw() {
  background(180);

  if (DummyService.instance != null) {
    DummyService.instance.setSketch(this);
  }
}

void hi() {
  println("hi");
}
...

```

```java
public class DummyService extends Service {
  ...
  AndroidService sketch;
  ...
  void setSketch(AndroidService sketch) {
    this.sketch = sketch;
  }
  ...
  void workLoop() {
    System.out.println("launching...");
    runnable = new Runnable() {
      @Override
      public void run() {
        System.out.println("working...");
        if (sketch != null) {
          sketch.hi();
        }
        if (running) {
          handler.postDelayed(runnable, WAIT_SECONDS * 1000);
        }        
      }
    };
    handler.postDelayed(runnable, WAIT_SECONDS * 1000);    
  }

```

---

<div class="post-metadata">

### Author: ![basher24](https://avatars.discourse-cdn.com/v4/letter/b/ee7513/32.png) [@basher24](https://discourse.processing.org/u/basher24)
#### Post date: [June 25, 2018, 1:33pm UTC](https://discourse.processing.org/t/notification-builder/1101/10 "2018-06-25T13:33:46Z")

</div>

hi,  
thanx …  
i have this Error !  
working …  
FATAL EXCEPTION: main  
Process: processing.test.annexsafe, PID: 9475  
android.os.NetworkOnMainThreadException  
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1303)  
at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:86)  
at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:74)  
at java.net.InetAddress.getByName(InetAddress.java:708)  
at processing.test.annexsafe.AnnexSafe.isConnectingToInternet(AnnexSafe.java:2288)  
at processing.test.annexsafe.DummyService$1.run(DummyService.java:91)  
at android.os.Handler.handleCallback(Handler.java:751)  
at android.os.Handler.dispatchMessage(Handler.java:95)  
at android.os.Looper.loop(Looper.java:154)  
at android.app.ActivityThread.main(ActivityThread.java:6692)  
at java.lang.reflect.Method.invoke(Native Method)  
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468)  
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358)

---

<div class="post-metadata">

### Author: ![kfrajer](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kfrajer/32/196_2.png) [@kfrajer](https://discourse.processing.org/u/kfrajer)
#### Post date: [June 25, 2018, 3:22pm UTC](https://discourse.processing.org/t/notification-builder/1101/11 "2018-06-25T15:22:41Z")

</div>

> [@basher24](#):
>
> android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork

This [link](https://stackoverflow.com/questions/22395417/error-strictmodeandroidblockguardpolicy-onnetwork) looks promising related to your last error.

Kf

---

<div class="post-metadata">

### Author: ![basher24](https://avatars.discourse-cdn.com/v4/letter/b/ee7513/32.png) [@basher24](https://discourse.processing.org/u/basher24)
#### Post date: [June 26, 2018, 6:03am UTC](https://discourse.processing.org/t/notification-builder/1101/12 "2018-06-26T06:03:47Z")

</div>

I still having the problem when the App goes to the background (when i close all the applications) the loop function “void workLoop()” stopped of working (i think there as an error witch stopped the loop function)

Here is my function i used at processing sketch :

```auto
public void isConnectingToInternet(){
 
  ConnectivityManager connectivityManager = (ConnectivityManager) act.getSystemService(Context.CONNECTIVITY_SERVICE);
  NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
                                 
  if (activeNetworkInfo != null) { 
    if( activeNetworkInfo.isConnected()) { 
     try{
         address = InetAddress.getByName("www.google.com");                                  
         String hostIP = address.getHostAddress() ;
         if(hostIP.equals(currentIP) == false ) {
                    ConnectStatus = "disConnected" ;
                    currentIP = hostIP ;                    
         }                 
         if (ConnectStatus.equals("disConnected")) {             
             MyConnection();
          } 
      } catch(UnknownHostException e ){ ConnectStatus = "disConnected" ;}
  } else { ConnectStatus = "disConnected" ; }
 
}else { ConnectStatus = "disConnected" ; }

}

public void MyConnection()
{

client = new MuKCastClient(this, ServerIP, int(ServerPort));

                    try {

                         client.connect();     
                         ConnectStatus = "Connected";
    
                    } catch(IOException e) {
                                       // e.printStackTrace();   
                                            ConnectStatus = "disConnected";
                                            }
                                
}

here the code i used in java file : mu pde file called AnnexSafe

import android.app.Activity;
import android.app.Service;
import android.os.Handler;
import android.os.IBinder;
import android.content.Intent;
import android.app.Notification;
import android.app.PendingIntent;
import processing.core.PApplet;
import android.os.StrictMode;

public class DummyService extends Service {
  
   
  public AnnexSafe sketch;
   
  static final String TAG = "DummyService";
  static final int FOREGROUND_NOTIFICATION_ID = 1;

  static Activity activity;
  static DummyService instance;
  
  boolean running = false;
  Handler handler = new Handler();
  Runnable runnable;
  
  int WAIT_SECONDS = 5;

// public DummyService(PApplet sketch) {
  
 // this.sketch = sketch;
//}

  @Override
  public void onCreate() {
    System.out.println("Created service");
    super.onCreate();
    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
    StrictMode.setThreadPolicy(policy);
    start();
    instance = this;
  }

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

  @Override
  public IBinder onBind(Intent intent) {
    // Used only in case of bound services.
    return null;
  }

  void start() {
    goForeground();
    workLoop();
    running = true;
  }
  
  void stop() {
    running = false;
  }
  
  void goForeground() {
    Intent notificationIntent = new Intent(this, activity.getClass());
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
    Notification m = new Notification.Builder(this)
            .setContentTitle("Dummy Service")
            .setContentText("Testing foreground services from Processing.")
            .setContentIntent(pendingIntent)
            .build();
    startForeground(FOREGROUND_NOTIFICATION_ID, m);
        
  }
 
  void setSketch(AnnexSafe sketch) {
    this.sketch = sketch;
  }
  
  
  void workLoop() {
    System.out.println("launching ....");
  // runnable = new Runnable() {
  Thread thread = new Thread(runnable = new Runnable(){  
      @Override
      public void run() {
          System.out.println("working ....");
          if (sketch != null) {
            System.out.println("hi ....");
            sketch.isConnectingToInternet();
        }
        
         
        if (running) {
           handler.postDelayed(runnable, WAIT_SECONDS * 1000);
           }
      }
    });
    thread.start();
handler.postDelayed(runnable, WAIT_SECONDS * 1000);
  }
  
}
```

---

<div class="post-metadata">

### Author: ![basher24](https://avatars.discourse-cdn.com/v4/letter/b/ee7513/32.png) [@basher24](https://discourse.processing.org/u/basher24)
#### Post date: [June 26, 2018, 1:59pm UTC](https://discourse.processing.org/t/notification-builder/1101/13 "2018-06-26T13:59:29Z")

</div>

thanx … the problem solved …

I respect your helps  
thanx  
basher
