Red-Folder / bgs-core

Core code for the Cordova Background Service
Other
236 stars 105 forks source link

doWork returning always undefined instead of the string. #82

Open shamun opened 6 years ago

shamun commented 6 years ago

Is this normal? doWork is always returning "undefined" when i have code as following:

package com.red_folder.phonegap.plugin.backgroundservice.sample;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.json.JSONException;
import org.json.JSONObject;
import android.util.Log;
import com.red_folder.phonegap.plugin.backgroundservice.BackgroundService;
import android.net.Uri;
import android.media.RingtoneManager;
import android.media.Ringtone;

public class MyService extends BackgroundService {
    private final static String TAG = MyService.class.getSimpleName();
    private String mHelloTo = "World";

    @Override
    protected JSONObject doWork() {
        JSONObject result = new JSONObject();
        try {
            Uri ringtoneUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
            Ringtone ringtoneSound = RingtoneManager.getRingtone(getApplicationContext(), ringtoneUri);

            String msg = "";
            if (ringtoneSound != null) {
              //ringtoneSound.play(); // not even ringing?
                msg = "Ring";
                result.put("Message", msg);
            }
            else {
              msg = "NoRing";
                result.put("Message", msg);
            }

            Log.d(TAG, msg);
        } catch (JSONException e) {
        }

        return result;// not evening telling the status
    }

    @Override
    protected JSONObject getConfig() {
        JSONObject result = new JSONObject();

        try {
            result.put("HelloTo", this.mHelloTo);
        } catch (JSONException e) {
        }

        return result;
    }

    @Override
    protected void setConfig(JSONObject config) {
        try {
            if (config.has("HelloTo"))
                this.mHelloTo = config.getString("HelloTo");
        } catch (JSONException e) {
        }

    }

    @Override
    protected JSONObject initialiseLatestResult() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    protected void onTimerEnabled() {
        // TODO Auto-generated method stub

    }

    @Override
    protected void onTimerDisabled() {
        // TODO Auto-generated method stub

    }

}
Red-Folder commented 6 years ago

Where are you getting undefined? I assume in the JavaScript - can I see that code as well

I suspect you are hitting your exception - so while the result is being set to an instance of JObject, there is nothing being put into msg.

Try changing to:

        } catch (JSONException e) {
                                msg = "Hi ... I'm an exception.  Please fix me";
                result.put("Message", msg);
        }
shamun commented 6 years ago

@Red-Folder : YES you are correct (in Javascript getting undefined), its the exception from Java. but i am trying to put, in the exception also result.put() but that fails while compile.

image

shamun commented 6 years ago

It looks like cant send Exception outputs to Javascript for to read?

Following code still showing "undefined" (expected to return "Step1" in my Javascript) which means its dead in the exception scope and not hitting the return result; statement.

Is there anyway to see the Exception in my Javascript UI from Java within that doWork() method?

    @Override
    protected JSONObject doWork() {
        JSONObject result = new JSONObject();
        String msg = "Step1";
        try {
                        result.put("Message", msg);
            Uri alert = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);

            if(alert == null){
                // alert is null, using backup
                alert = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

                // I can't see this ever being null (as always have a default notification)
                // but just incase
                if(alert == null) {
                    // alert backup is null, using 2nd backup
                    alert = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
                }
            }
            //Ringtone ringtoneSound = RingtoneManager.getRingtone(getApplicationContext(), alert);
            MediaPlayer ringtoneSound = MediaPlayer.create(getApplicationContext(), alert);

            if (ringtoneSound != null) {
              ringtoneSound.start();
                msg = "Ring";
                result.put("Message", msg);
            }
            else {
              msg = "NoRing";
                result.put("Message", msg);
            }

            Log.d(TAG, msg);
        } catch (JSONException e) {
        }

        return result;
    }
Red-Folder commented 6 years ago

The build error is because it needs any JSONObject to be wrapped in try/ catch block

I'd suggest that within your first try/ catch you just set msg

After that try/ catch - add a second try catch that does the result.put

Also, in both exceptions log out that the exception occurred

shamun commented 6 years ago

Tried as below, which still gives undefined

    @Override
    protected JSONObject doWork() {
        JSONObject result = new JSONObject();
        String msg = "Step1";

        try {
            Uri alert = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
            if(alert == null){
                alert = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
                if(alert == null) {
                    alert = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
                }
            }
            //Ringtone ringtoneSound = RingtoneManager.getRingtone(getApplicationContext(), alert);
            MediaPlayer ringtoneSound = MediaPlayer.create(getApplicationContext(), alert);
            if (ringtoneSound != null) {
                ringtoneSound.start();
            }

            Log.d(TAG, msg);
        } catch (Exception e) {

            try {

                msg = "Step2";
                result.put("Message", msg);

            } catch(JSONException ee) {
            }

            Log.d(TAG, e.toString());
        }

        try {

            msg = "Step3";
            result.put("Message", msg);

        } catch(JSONException e) {

        }

        return result;
    }
Red-Folder commented 6 years ago

Are you able to provide the JavaScript?

shamun commented 6 years ago

myService.html is as below:

<!DOCTYPE HTML>
<!--
/*
 * Copyright 2013 Red Folder Consultancy Ltd
 *   
 * Licensed under the Apache License, Version 2.0 (the "License");   
 * you may not use this file except in compliance with the License.   
 * You may obtain a copy of the License at       
 * 
 *  http://www.apache.org/licenses/LICENSE-2.0   
 *
 * Unless required by applicable law or agreed to in writing, software   
 * distributed under the License is distributed on an "AS IS" BASIS,   
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   
 * See the License for the specific language governing permissions and   
 * limitations under the License.
 */
-->
<html>
    <head>
        <title>MyService</title>

        <script type="text/javascript" src="cordova.js"></script>

        <script type="text/javascript" >
            var myService;

            document.addEventListener('deviceready', function() {
                myService = cordova.plugins.myService;
                getStatus();
            }, true);

            function handleSuccess(data) {
                updateView(data);
            }

            function handleError(data) {
                alert("Error: " + data.ErrorMessage);
                alert(JSON.stringify(data));
                updateView(data);
            }

            /*
             * Button Handlers
             */             
            function getStatus() {
                myService.getStatus(    function(r){handleSuccess(r)},
                                        function(e){handleError(e)});
            };

            function startService() {
                myService.startService( function(r){handleSuccess(r)},
                                        function(e){handleError(e)});
            }

            function stopService() {
                myService.stopService(  function(r){handleSuccess(r)},
                                        function(e){handleError(e)});
            }

            function enableTimer() {
                myService.enableTimer(  60000,
                                        function(r){handleSuccess(r)},
                                        function(e){handleError(e)});
            }

            function disableTimer() {
                myService.disableTimer( function(r){handleSuccess(r)},
                                        function(e){handleError(e)});
            };

            function registerForBootStart() {
                myService.registerForBootStart( function(r){handleSuccess(r)},
                                                function(e){handleError(e)});
            }

            function deregisterForBootStart() {
                myService.deregisterForBootStart(   function(r){handleSuccess(r)},
                                                    function(e){handleError(e)});
            }

            function registerForUpdates() {
                myService.registerForUpdates(   function(r){handleSuccess(r)},
                                                function(e){handleError(e)});
            }

            function deregisterForUpdates() {
                myService.deregisterForUpdates( function(r){handleSuccess(r)},
                                                function(e){handleError(e)});
            }

            function setConfig() {
                var helloToTxt = document.getElementById("helloToTxt");
                var helloToString = helloToTxt.value;
                var config = { 
                                "HelloTo" : helloToString 
                            }; 
                myService.setConfiguration( config,
                                            function(r){handleSuccess(r)},
                                            function(e){handleError(e)});
            }

            /*
             * View logic
             */
            function updateView(data) {
                var serviceBtn = document.getElementById("toggleService");
                var timerBtn = document.getElementById("toggleTimer");
                var bootBtn = document.getElementById("toggleBoot");
                var listenBtn = document.getElementById("toggleListen");
                var updateBtn = document.getElementById("updateBtn");
                var refreshBtn = document.getElementById("refreshBtn");

                var serviceStatus = document.getElementById("serviceStatus");
                var timerStatus = document.getElementById("timerStatus");
                var bootStatus = document.getElementById("bootStatus");
                var listenStatus = document.getElementById("listenStatus");

                serviceBtn.disabled = false;
                if (data.ServiceRunning) {
                    serviceStatus.innerHTML = "Running";
                    serviceBtn.onclick = stopService;
                    timerBtn.disabled = false;
                    if (data.TimerEnabled) {
                        timerStatus.innerHTML = "Enabled";
                        timerBtn.onclick = disableTimer;
                    } else {
                        timerStatus.innerHTML = "Disabled";
                        timerBtn.onclick = enableTimer;
                    } 

                    updateBtn.disabled = false;
                    updateBtn.onclick = setConfig;

                    refreshBtn.disabled = false;
                    refreshBtn.onclick = getStatus;

                } else { 
                    serviceStatus.innerHTML = "Not running";
                    serviceBtn.onclick = startService;
                    timerBtn.disabled = true;
                    timerEnabled = false; 

                    updateBtn.disabled = true;
                    refreshBtn.disabled = true;
                } 

                bootBtn.disabled = false;
                if (data.RegisteredForBootStart) {
                    bootStatus.innerHTML = "Registered";
                    bootBtn.onclick = deregisterForBootStart;
                } else {
                    bootStatus.innerHTML = "Not registered";
                    bootBtn.onclick = registerForBootStart;
                }

                listenBtn.disabled = false;
                if (data.RegisteredForUpdates) {
                    listenStatus.innerHTML = "Registered";
                    listenBtn.onclick = deregisterForUpdates;
                } else {
                    listenStatus.innerHTML = "Not registered";
                    listenBtn.onclick = registerForUpdates;
                }

                if (data.Configuration != null)
                {
                    try {
                        var helloToTxt = document.getElementById("helloToTxt");
                        helloToTxt.value = data.Configuration.HelloTo;
                    } catch (err) {
                    }
                }

                if (data.LatestResult != null)
                {
                    try {
                        var resultMessage = document.getElementById("resultMessage");
                        resultMessage.innerHTML = data.LatestResult.Message;
                    } catch (err) {
                    }
                }
            }

        </script>

    </head>

    <body>
        <h1>MyService</h1>

        <table>
            <tr>
                <th>Service</th>
                <td><div id="serviceStatus"></div></td>
                <td><input disabled id="toggleService" type="button" value="toggle"/></td>
            </tr>
            <tr>
                <th>Timer</th>
                <td><div id="timerStatus"></div></td>
                <td><input disabled id="toggleTimer" type="button" value="toggle"/></td>
            </tr>
            <tr>
                <th>Boot</th>
                <td><div id="bootStatus"></div></td>
                <td><input disabled id="toggleBoot" type="button" value="toggle"/></td>
            </tr>
            <tr>
                <th>Listen</th>
                <td><div id="listenStatus"></div></td>
                <td><input disabled id="toggleListen" type="button" value="toggle"/></td>
            </tr>

            <tr>
                <th colspan=3 align="center">Configuration</th>
            </tr>
            <tr>
                <th align="left">Hello To</th>
                <td colspan=2 align="center"><input id="helloToTxt" type="Text"/></td>
            </tr>
            <tr>
                <td colspan=3 align="center"><input disabled id="updateBtn" type="button" value="Update Config"/></td>
            </tr>

            <tr>
                <th colspan=3 align="center">Latest Result</th>
            </tr>

            <tr>
                <td colspan=3 align="center"><div id="resultMessage"></div></td>
            </tr>

            <tr>
                <td colspan=3 align="center"><input disabled id="refreshBtn" type="button" value="Refresh"/></td>
            </tr>

        </table>

    </body>
</html>
Red-Folder commented 6 years ago

Which line is throwing the undefined?

shamun commented 6 years ago

This one resultMessage.innerHTML = data.LatestResult.Message;

                if (data.LatestResult != null)
                {
                    try {
                        var resultMessage = document.getElementById("resultMessage");
                        resultMessage.innerHTML = data.LatestResult.Message;
                    } catch (err) {
                    }
                }
Red-Folder commented 6 years ago

Add this to your java file (if not already there):

    @Override
    protected JSONObject initialiseLatestResult() {
        return null;
    }
shamun commented 6 years ago

It was there. I also tried by removing it or by keeping it in both cases still returning 'undefined'

image

Red-Folder commented 6 years ago

Well I'm confused.

Have you tried adding addition Log.d messages in the java and then looking at logcat? See if it is stepping through that doWork() as expected

shamun commented 6 years ago

Very confusing. I did not check the logcat, but i will look further.


I think when the Exception is happening we will not get return, the reason is Java do not continue after any exception which might be the reason. Because when i do not use the ALARM, NOTIFY, Ring statements then it works.

Which means in doWork() we might need an external ringer app so that we can do like Runtime.getRuntime().exec("shell command"); kind of execution and resume next. or run a new thread which only does the ring handle without being synchronous