App Error 104 uncaught : runtime exception while running blackberry application - blackberry

I have created one application to get My location coordinates using GPS after deploying my code in simulator i am getting above error with explanation -
uncaught exception:pushmodalscreen called by a non-event thread
I am not able to figure out whats going wrong.
/**
* GPSDemo.java
*
* Copyright © 1998-2011 Research In Motion Ltd.
*
* Note: For the sake of simplicity, this sample application may not leverage
* resource bundles and resource strings. However, it is STRONGLY recommended
* that application developers make use of the localization features available
* within the BlackBerry development platform to ensure a seamless application
* experience across a variety of languages and geographies. For more information
* on localizing your application, please refer to the BlackBerry Java Development
* Environment Development Guide associated with this release.
*/
package com.gps;
import java.util.*;
import javax.microedition.location.*;
import net.rim.device.api.command.*;
import net.rim.device.api.gps.*;
import net.rim.device.api.system.*;
import net.rim.device.api.ui.*;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.container.*;
import net.rim.device.api.util.*;
import net.rim.blackberry.api.invoke.*;
import net.rim.blackberry.api.maps.*;
import net.rim.blackberry.api.menuitem.*;
/**
* This application acts as a simple travel computer, recording route
* coordinates, speed and altitude. Recording begins as soon as the
* application is invoked.
*/
public class GPSScreen extends UiApplication
{
// Represents the number of updates over which altitude is calculated, in seconds
private static final int GRADE_INTERVAL = 5;
private static final long ID = 0x5d459971bb15ae7aL;
// Represents period of the position query, in seconds
private static int _interval = 1;
private double _latitude;
private double _longitude;
private LocationProvider _locationProvider;
private GPSDemoScreen _screen;
private MapView _mapview = new MapView();
/**
* Entry point for application
*
* #param args Command line arguments (not used)
*/
public static void main(String[] args)
{
// Create a new instance of the application and make the currently
// running thread the application's event dispatch thread.
new GPSScreen().enterEventDispatcher();
}
/**
* Create a new GPSDemo object
*/
public GPSScreen()
{
_screen = new GPSDemoScreen();
_screen.setTitle("GPS Demo");
// Attempt to start the location listening thread
if(startLocationUpdate())
{
_screen.setState(_locationProvider.getState());
}
// Render the screen
pushScreen(_screen);
}
/**
* Invokes the Location API with Standalone criteria
*
* #return True if the <code>LocationProvider</code> was successfully started, false otherwise
*/
private boolean startLocationUpdate()
{
boolean returnValue = false;
if(!(GPSInfo.getDefaultGPSMode() == GPSInfo.GPS_MODE_NONE))
{
try
{
Criteria criteria = new Criteria();
criteria.setCostAllowed(false);
_locationProvider = LocationProvider.getInstance(criteria);
if(_locationProvider != null)
{
/*
* Only a single listener can be associated with a provider,
* and unsetting it involves the same call but with null.
* Therefore, there is no need to cache the listener
* instance request an update every second.
*/
_locationProvider.setLocationListener(new LocationListenerImpl(), _interval, -1, -1);
returnValue = true;
}
else
{
invokeLater(new Runnable()
{
public void run()
{
Dialog.alert("Failed to obtain a location provider, exiting...");
System.exit(0);
}
});
}
}
catch(final LocationException le)
{
invokeLater(new Runnable()
{
public void run()
{
Dialog.alert("Failed to instantiate LocationProvider object, exiting..." + le.toString());
System.exit(0);
}
});
}
}
else
{
invokeLater(new Runnable()
{
public void run()
{
Dialog.alert("GPS is not supported on this device, exiting...");
System.exit(0);
}
});
}
return true;
}
/**
* Implementation of the LocationListener interface. Listens for updates to
* the device location and displays the results.
*/
private class LocationListenerImpl implements LocationListener
{
/**
* #see javax.microedition.location.LocationListener#locationUpdated(LocationProvider,Location)
*/
public void locationUpdated(LocationProvider provider, Location location)
{
if(location.isValid())
{
_longitude = location.getQualifiedCoordinates().getLongitude();
_latitude = location.getQualifiedCoordinates().getLatitude();
_mapview.setZoom(Integer.parseInt("0.1"));
try
{
int latitude = (int) (100000 * _latitude);
int longitude = (int) (100000 * _longitude);
if (latitude > 9000000 || latitude < -9000000 || longitude >= 18000000 || longitude < -18000000)
{
throw new IllegalArgumentException ();
}
_mapview.setLatitude(latitude);
_mapview.setLongitude(longitude);
// Invoke BlackBerry Maps application with provided MapView object.
Invoke.invokeApplication(Invoke.APP_TYPE_MAPS, new MapsArguments(_mapview));
}
catch(RuntimeException re)
{
// An exception is thrown when any of the following occur :
// Latitude is invalid : Valid range: [-90, 90]
// Longitude is invalid : Valid range: [-180, 180)
// Minus sign between 2 numbers.
Dialog.alert("Temporary Unavailable Service");
}
}
}
/**
* #see javax.microedition.location.LocationListener#providerStateChanged(LocationProvider, int)
*/
public void providerStateChanged(LocationProvider provider, int newState)
{
if(newState == LocationProvider.TEMPORARILY_UNAVAILABLE)
{
provider.reset();
}
_screen.setState(newState);
}
}
/**
* The main screen to display the current GPS information
*/
private final class GPSDemoScreen extends MainScreen
{
TextField _statusTextField;
/**
* Create a new GPSDemoScreen object
*/
GPSDemoScreen()
{
// Initialize UI
_statusTextField = new TextField(Field.NON_FOCUSABLE);
}
/**
* Display the state of the GPS service
*
* #param newState The state to display
*/
public void setState(final int newState)
{
UiApplication.getUiApplication().invokeLater(new Runnable()
{
/**
* #see java.lang.Runnable#run()
*/
public void run()
{
switch(newState)
{
case LocationProvider.AVAILABLE:
_statusTextField.setText("Available");
break;
case LocationProvider.OUT_OF_SERVICE:
_statusTextField.setText("Out of Service");
break;
case LocationProvider.TEMPORARILY_UNAVAILABLE:
_statusTextField.setText("Temporarily Unavailable");
break;
}
}
});
}
/**
* #see net.rim.device.api.ui.Screen#close()
*/
public void close()
{
if(_locationProvider != null)
{
_locationProvider.reset();
_locationProvider.setLocationListener(null, -1, -1, -1);
}
super.close();
}
}
}

I've seen that error when Dialog.alert() is used outside of the event thread. Looking at your code, I see LocationListenerImpl.locationUpdated assumes it is running on the event thread. If it is not, the UI update code would throw an exception, and then your exception handler will try to display a dialog, and that will fail as well.

Related

Corda responder flow not answering

I created a very easy flow test with IntelliJ.
#Test
public void dummyTest() throws InterruptedException, ExecutionException {
Party Alice = aliceNode.getServices().getIdentityService().wellKnownPartyFromX500Name(new CordaX500Name("Alice", "London", "GB"));
FlowInitiatorIssueToken flow = new FlowInitiatorIssueToken(30, alice, network.getDefaultNotaryIdentity());
SignedTransaction transaction = bobNode.startFlow(flow).get();
// The error occurs because of this line ....
State state = (State) transaction.getTx().getOutputStates().get(0);
assertEquals(state.getParticipants(), alice);
VaultQueryCriteria criteria = new VaultQueryCriteria(Vault.StateStatus.ALL);
aliceNode.transaction(() -> {
Vault.Page<State> result = aliceNode.getServices().getVaultService().queryBy(State.class, criteria);
assertTrue(result.getStates().size() > 0);
return null;
});
network.runNetwork();
}
IntelliJ is not able to fulfil the test and gives me the error
statemachine.FlowMonitor. - Flow with id 3982ab19-3e5b-4737-9adf-e4a6a97d20e6 has been waiting for 117 seconds to receive messages from parties [O=Alice, L=London, C=GB]
This led to the assumption that the responder flow is not doing anything.
// ******************
// * Initiator flow *
// ******************
#InitiatingFlow
#StartableByRPC
public class FlowInitiatorIssueToken extends FlowLogic<SignedTransaction> {
private final Integer value;
private final Party counterParty;
private final Party notary;
public FlowInitiatorIssuToken(Integer value, Party counterParty, Party notary) {
this.value = value;
this.counterParty = counterParty;
this.notary = notary;
}
/**
* The flow logic is encapsulated within the call() method.
*/
#Suspendable
#Override
public SignedTransaction call() throws FlowException {
/*------------------------------
* SENDING AND RECEIVING DATA *
------------------------------*/
FlowSession issueTokenSession = initiateFlow((Party) counterParty);
/*------------------------------------------
* GATHERING OTHER TRANSACTION COMPONENTS *
------------------------------------------*/
State outputState = new State(this.value, this.counterParty);
Command<ContractToken.Commands.Issue> command = new Command<>(new ContractToken.Commands.Issue(), getOurIdentity().getOwningKey());
/*------------------------
* TRANSACTION BUILDING *
------------------------*/
TransactionBuilder txBuilder = new TransactionBuilder(notary)
.addOutputState(outputState, ContractToken.ID)
.addCommand(command);
/*-----------------------
* TRANSACTION SIGNING *
-----------------------*/
SignedTransaction signedTx = getServiceHub().signInitialTransaction(txBuilder);
/*------------------------------
* FINALISING THE TRANSACTION *
------------------------------*/
System.out.println("Hey World!");
subFlow(new FinalityFlow(signedTx, issueTokenSession));
return null;
}
}
// ******************
// * Responder flow *
// ******************
#InitiatedBy(FlowInitiatorIssueToken.class)
public class FlowResponderIssueToken extends FlowLogic<SignedTransaction> {
private final FlowSession issueTokenSession;
public FlowResponderIssueToken(FlowSession issueTokenSession) {
this.issueTokenSession = issueTokenSession;
}
#Suspendable
#Override
public SignedTransaction call() throws FlowException {
/*-----------------------------------------
* RESPONDING TO COLLECT_SIGNATURES_FLOW *
-----------------------------------------*/
class SignTxFlow extends SignTransactionFlow {
private SignTxFlow(FlowSession issueTokenSession) {
super(issueTokenSession);
}
#Override
protected void checkTransaction(SignedTransaction stx) {
}
}
SecureHash idOfTxWeSigned = subFlow(new SignTxFlow(issueTokenSession, SignTransactionFlow.tracker())).getId();
/*------------------------------
* FINALISING THE TRANSACTION *
------------------------------*/
subFlow(new ReceiveFinalityFlow(issueTokenSession, idOfTxWeSigned));
return null;
}
}
The initiator flow is executed. I can see that, because the System.out.println("Hey World!") command is showing up in the logs. However, I don't know whether the responder flow is never started by the initiator flow or it is just not reacting. Maybe you can help me with that.
Thanks!
You didn't call CollectSignaturesFlow in your initiator; that's why you didn't initiate a "conversation" with the responder for them to sign the transaction. See example here.
SignTransactionFlow that you call in your responder is a "reply" to calling CollectSignaturesFlow in the initiator.
Btw, you must verify a transaction before you sign it in your initiator. See example here.
Another thing missing was the key of the counterParty. When initialising the command, I added
final Command<ContractToken.Commands.Issue> txCommand = new Command<>(
new ContractToken.Commands.Issue(),
ImmutableList.of(getOurIdentity().getOwningKey(), counterParty.getOwningKey()));

proper video streaming with rxjava

To handle a video stream from a webcam (delivered by opencv) i am considering to use RxJava.
I am hoping to achieve the following:
being able to control the frames per second to be delivered
to be able to handle different inputs - e.g. a life webcam, a video or even a still picture
being able to switch to a picture-by-picture handling under the control of a gui
I have been experimenting a bit with RxJava but i am confused about the debounce, throttleFirst and async operators
Examples like https://stackoverflow.com/a/48723331/1497139 show some code but I am missing more detailed explanation.
Where could I find a decent example for video processing or something similar along the needs mentioned above?
The code below does some non async logic at this time - please let me know if i could build on it:
ImageFetcher
import org.opencv.core.Mat;
import org.opencv.videoio.VideoCapture;
import rx.Observable;
import rx.functions.Action1;
import rx.functions.Func0;
import rx.functions.Func1;
/**
* fetcher for Images
*
*/
public class ImageFetcher {
// OpenCV video capture
private VideoCapture capture = new VideoCapture();
private String source;
protected int frameIndex;
public int getFrameIndex() {
return frameIndex;
}
/**
* fetch from the given source
*
* #param source
* - the source to fetch from
*/
public ImageFetcher(String source) {
this.source = source;
}
/**
* try opening my source
*
* #return true if successful
*/
public boolean open() {
boolean ret = this.capture.open(source);
frameIndex=0;
return ret;
}
/**
* fetch an image Matrix
*
* #return - the image fetched
*/
public Mat fetch() {
if (!this.capture.isOpened()) {
boolean ret = this.open();
if (!ret) {
String msg = String.format(
"Trying to fetch image from unopened VideoCapture and open %s failed",
source);
throw new IllegalStateException(msg);
}
}
final Mat frame = new Mat();
this.capture.read(frame);
frameIndex++;
return !frame.empty() ? frame : null;
}
#Override
protected void finalize() throws Throwable {
super.finalize();
}
/**
* convert me to an observable
* #return a Mat emitting Observable
*/
public Observable<Mat> toObservable() {
// Resource creation.
Func0<VideoCapture> resourceFactory = () -> {
VideoCapture capture = new VideoCapture();
capture.open(source);
return capture;
};
// Convert to observable.
Func1<VideoCapture, Observable<Mat>> observableFactory = capture -> Observable
.<Mat> create(subscriber -> {
boolean hasNext = true;
while (hasNext) {
final Mat frame = this.fetch();
hasNext = frame!=null && frame.rows()>0 && frame.cols()>0;
if (hasNext) {
String msg = String.format("->%6d:%4dx%d", frameIndex, frame.cols(), frame.rows());
System.out.println(msg);
subscriber.onNext(frame);
}
}
subscriber.onCompleted();
});
// Disposal function.
Action1<VideoCapture> dispose = VideoCapture::release;
return Observable.using(resourceFactory, observableFactory, dispose);
}
}
ImageSubscriber
import org.opencv.core.Mat;
import rx.Subscriber;
public class ImageSubscriber extends Subscriber<Mat> {
public Throwable error;
public int cols = 0;
public int rows=0;
public int frameIndex=0;
public boolean completed = false;
public boolean debug = false;
#Override
public void onCompleted() {
completed = true;
}
#Override
public void onError(Throwable e) {
error = e;
}
#Override
public void onNext(Mat mat) {
cols = mat.cols();
rows = mat.rows();
frameIndex++;
if (cols==0 || rows==0)
System.err.println("invalid frame "+frameIndex);
if (debug) {
String msg = String.format("%6d:%4dx%d", frameIndex, cols, rows);
System.out.println(msg);
}
}
};

BlackBerry Refresh location via GPS or Cell Tower

I am trying to refresh the current location through a click of a button. The location can be acquired via GPS or Cell Tower, whichever is available. My problem is I never see the "Loading Screen". I know it appears as something appears/closes instantly while the coordinates remain zero. Can somebody help me - what I am doing wrong below?
Neither the location is updated nor the loading screen appears. Without the loading screen and by multiple clicks of the "refresh button" I do get the location. Below is my code for handling clicks on the "Refresh Button":
FieldChangeListener refreshImgListener = new FieldChangeListener() {
public void fieldChanged(Field field, int context)
{
Thread backgroundWorker = new Thread(new Runnable() {
public void run() {
refreshCoordinates();
}
});
busyDialog.setEscapeEnabled(false);
busyDialog.show();
backgroundWorker.start();
}
};
And my refreshCoordinates() method is as below:
public void refreshCoordinates() {
do
{
getLatitude(handleeGPS.latitude);
getLongitude(handleeGPS.longitude);
} while ((longi == "0.0" || lati == "0.0") || (longi.length() == 0 || lati.length()==0));
UiApplication.getUiApplication().invokeLater( new Runnable()
{
public void run ()
{
lblLatitude.setText(lati);
lblLongitude.setText(longi);
busyDialog.cancel();
}
} );
}
public static String getLatitude(double value)
{
lati= Double.toString(value);
return lati;
}
public static String getLongitude(double value)
{
longi= Double.toString(value);
return longi;
}
Class that returns the latitude and longitude values:
public class handleeGPS{
static GPSThread gpsThread;
public static double latitude;
public static double longitude;
public handleeGPS(){
gpsThread = new GPSThread();
gpsThread.start();
}
private static class GPSThread extends Thread{
public void run() {
Criteria myCriteria = new Criteria();
myCriteria.setCostAllowed(false);
int m_bbHandle = CodeModuleManager.getModuleHandle("net_rim_bb_lbs");
if(m_bbHandle>0){
try {
int cellID = GPRSInfo.getCellInfo().getCellId();
int lac = GPRSInfo.getCellInfo().getLAC();
String urlString2 = "http://www.google.com/glm/mmap";
// Open a connection to Google Maps API
ConnectionFactory connFact = new ConnectionFactory();
ConnectionDescriptor connDesc;
connDesc = connFact.getConnection(urlString2);
HttpConnection httpConn2;
httpConn2 = (HttpConnection)connDesc.getConnection();
httpConn2.setRequestMethod("POST");
// Write some custom data to Google Maps API
OutputStream outputStream2 = httpConn2.openOutputStream();//getOutputStream();
WriteDataGoogleMaps(outputStream2, cellID, lac);
// Get the response
InputStream inputStream2 = httpConn2.openInputStream();//getInputStream();
DataInputStream dataInputStream2 = new DataInputStream(inputStream2);
// Interpret the response obtained
dataInputStream2.readShort();
dataInputStream2.readByte();
int code = dataInputStream2.readInt();
//Dialog.alert(code+"");
if (code == 0) {
latitude= dataInputStream2.readInt() / 1000000D;
longitude=dataInputStream2.readInt() / 1000000D;
//Dialog.alert(latitude+"-----"+longitude);
dataInputStream2.readInt();
dataInputStream2.readInt();
dataInputStream2.readUTF();
} else {
System.out.println("Error obtaining Cell Id ");
}
outputStream2.close();
inputStream2.close();
} catch (Exception e) {
System.out.println("Error: " + e.getMessage());
}
} else {
try {
LocationProvider myLocationProvider = LocationProvider.getInstance(myCriteria);
try {
Location myLocation = myLocationProvider.getLocation(300);
latitude = myLocation.getQualifiedCoordinates().getLatitude();
longitude = myLocation.getQualifiedCoordinates().getLongitude();
if(latitude==0.0 && longitude==0.0){
try {
int cellID = GPRSInfo.getCellInfo().getCellId();
int lac = GPRSInfo.getCellInfo().getLAC();
String urlString2 = "http://www.google.com/glm/mmap";
// Open a connection to Google Maps API
ConnectionFactory connFact = new ConnectionFactory();
ConnectionDescriptor connDesc;
connDesc = connFact.getConnection(urlString2);
HttpConnection httpConn2;
httpConn2 = (HttpConnection)connDesc.getConnection();
httpConn2.setRequestMethod("POST");
// Write some custom data to Google Maps API
OutputStream outputStream2 = httpConn2.openOutputStream();
//getOutputStream();
WriteDataGoogleMaps(outputStream2, cellID, lac);
// Get the response
InputStream inputStream2 = httpConn2.openInputStream();
//getInputStream();
DataInputStream dataInputStream2 = new DataInputStream(inputStream2);
// Interpret the response obtained
dataInputStream2.readShort();
dataInputStream2.readByte();
int code = dataInputStream2.readInt();
//Dialog.alert(code+"");
if (code == 0) {
latitude= dataInputStream2.readInt() / 1000000D;
longitude=dataInputStream2.readInt() / 1000000D;
//Dialog.alert(latitude+"-----"+longitude);
dataInputStream2.readInt();
dataInputStream2.readInt();
dataInputStream2.readUTF();
} else {
System.out.println("Error obtaining Cell Id ");
}
outputStream2.close();
inputStream2.close();
} catch (Exception e) {
System.out.println("Error: " + e.getMessage());
}
}
}
catch ( InterruptedException iex ) {
return;
}
catch ( LocationException lex ) {
return;
}
} catch ( LocationException lex ) {
return;
}
}
return;
}
}
private static void WriteDataGoogleMaps(OutputStream out, int cellID, int lac)
throws IOException {
DataOutputStream dataOutputStream = new DataOutputStream(out);
dataOutputStream.writeShort(21);
dataOutputStream.writeLong(0);
dataOutputStream.writeUTF("en");
dataOutputStream.writeUTF("Android");
dataOutputStream.writeUTF("1.0");
dataOutputStream.writeUTF("Web");
dataOutputStream.writeByte(27);
dataOutputStream.writeInt(0);
dataOutputStream.writeInt(0);
dataOutputStream.writeInt(3);
dataOutputStream.writeUTF("");
dataOutputStream.writeInt(cellID);
dataOutputStream.writeInt(lac);
dataOutputStream.writeInt(0);
dataOutputStream.writeInt(0);
dataOutputStream.writeInt(0);
dataOutputStream.writeInt(0);
dataOutputStream.flush();
}
}
Ok, so although my original answer was valid, the new code you posted has some different problems, so I'm posting a second answer. There were enough things that didn't look right, that I just rewrote your handleeGPS class. I'll explain the major changes I made, one-by-one:
Try to use Java naming conventions. This makes it easier for us to help you. Before you posted the code to your handleeGPS class, I thought it was a variable, because lowercase names are usually used for variables, not classes.
Avoid duplicating code. The handleeGPS class had a lot of code to read through, but most of it was the code to get location from Google's web service, which you duplicated in two places. Just make a method that contains only that code, and call it twice.
I renamed your handleeGPS class to GPSHandler. I'm not sure if handlee was an error, or if that's a word in another language that you used. Anyway, the name should at least start with an uppercase letter.
Avoid lots of static variables and methods. Sometimes, there really should be only one of something. A GPS handling class is probably a good example of that, because the device only has one GPS system. But, to enforce this code construct, don't mark everything as static. Just make the class a Singleton, which involves creating only one static member variable (_instance) and one static method (getInstance()). In my code, you will access the class like this: GPSHandler gps = GPSHandler.getInstance();.
I believe the check you had for whether BB maps was installed was actually backwards. You looked up the net_rim_bb_lbs module, and if it was greater than zero (which means BB Maps is installed) then you went directly to the Google webservice. I think you want it the other way around (try device GPS if BB Maps installed). Also, since 6.0, you need to check for net_rim_bb_maps, too.
Before you posted the update, I thought your getLatitude() and getLongitude() methods were actually fetching the device location. That was a bad assumption on my part. They were just converting numbers to strings. So, there's no reason for that to be done in the background (with a Thread). You already wrote your handleeGPS class to use a background thread, which is good. One background thread is enough. The UI that uses the location information should not also need a background Thread. I changed the code to add a GPSListener interface. That interface should be implemented by your UI code, to receive location updates. There is no reason to keep looping, asking if the location is not equal to {0.0, 0.0}. That's inefficient. With my code, you will just get notified when the location does change.
The original code was not thread safe. The handleeGPS latitude and longitude variables were set on the background thread, and accessed on the UI thread. That's not safe. Two threads should not be reading and writing the same piece of data at once. By changing the code to push location data to the GPSListener, it avoids this problem.
I uncommented the Dialog.alert() code you had inside your handleeGPS class, which would not have worked for you, because you're not allowed to make UI calls from the background. I surrounded those calls with UiApplication.getUiApplication().invokeLater() to make them safe.
To use this class, in your UI code somewhere, you would do this, instead of using a Thread to run your refreshCoordinates() method:
public void fieldChanged(Field field, int context)
// this is called when your location refresh button is clicked
GPSHandler.getInstance().setListener(this);
GPSHandler.getInstance().requestLocationUpdates();
busyDialog.setEscapeEnabled(false);
busyDialog.show();
}
...
public void onLocationReceived(Coordinates location) {
lblLatitude.setText(Double.toString(location.getLatitude()));
lblLongitude.setText(Double.toString(location.getLongitude()));
busyDialog.cancel();
}
Make sure the class where you put that code (above) also implements GPSListener, which is an interface, defined here:
public interface GPSListener {
public void onLocationReceived(Coordinates location);
}
and finally, the GPSHandler:
public class GPSHandler {
private GPSThread _gpsThread;
private Coordinates _location;
private boolean _gotLocation;
private GPSListener _listener;
/** this class will be a Singleton, as the device only has one GPS system */
private static GPSHandler _instance;
/** #return the Singleton instance of the GPSHandler */
public static GPSHandler getInstance() {
if (_instance == null) {
_instance = new GPSHandler();
}
return _instance;
}
/** not publicly accessible ... use getInstance() */
private GPSHandler() {
}
/** call this to trigger a new location fix */
public void requestLocationUpdates() {
if (_gpsThread == null || !_gpsThread.isAlive()) {
_gpsThread = new GPSThread();
_gpsThread.start();
}
}
public void setListener(GPSListener listener) {
// only supports one listener this way
_listener = listener;
}
private void setLocation(final Coordinates value) {
_location = value;
if (value.getLatitude() != 0.0 || value.getLongitude() != 0.0) {
_gotLocation = true;
if (_listener != null) {
// this assumes listeners are UI listeners, and want callbacks on the UI thread:
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
_listener.onLocationReceived(value);
}
});
}
}
}
private class GPSThread extends Thread {
private void getLocationFromGoogle() {
try {
int cellID = GPRSInfo.getCellInfo().getCellId();
int lac = GPRSInfo.getCellInfo().getLAC();
String urlString2 = "http://www.google.com/glm/mmap";
// Open a connection to Google Maps API
ConnectionFactory connFact = new ConnectionFactory();
ConnectionDescriptor connDesc;
connDesc = connFact.getConnection(urlString2);
HttpConnection httpConn2;
httpConn2 = (HttpConnection)connDesc.getConnection();
httpConn2.setRequestMethod("POST");
// Write some custom data to Google Maps API
OutputStream outputStream2 = httpConn2.openOutputStream();//getOutputStream();
writeDataGoogleMaps(outputStream2, cellID, lac);
// Get the response
InputStream inputStream2 = httpConn2.openInputStream();//getInputStream();
DataInputStream dataInputStream2 = new DataInputStream(inputStream2);
// Interpret the response obtained
dataInputStream2.readShort();
dataInputStream2.readByte();
final int code = dataInputStream2.readInt();
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
Dialog.alert(code + "");
}
});
if (code == 0) {
final double latitude = dataInputStream2.readInt() / 1000000D;
final double longitude = dataInputStream2.readInt() / 1000000D;
setLocation(new Coordinates(latitude, longitude, 0.0f));
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
Dialog.alert(latitude+"-----"+longitude);
}
});
dataInputStream2.readInt();
dataInputStream2.readInt();
dataInputStream2.readUTF();
} else {
System.out.println("Error obtaining Cell Id ");
}
outputStream2.close();
inputStream2.close();
} catch (Exception e) {
System.out.println("Error: " + e.getMessage());
}
}
private void tryGetLocationFromDevice() {
_gotLocation = false;
try {
Criteria myCriteria = new Criteria();
myCriteria.setCostAllowed(false);
LocationProvider myLocationProvider = LocationProvider.getInstance(myCriteria);
try {
Location myLocation = myLocationProvider.getLocation(300);
setLocation(myLocation.getQualifiedCoordinates());
} catch ( InterruptedException iex ) {
System.out.println(iex.getMessage());
} catch ( LocationException lex ) {
System.out.println(lex.getMessage());
}
} catch ( LocationException lex ) {
System.out.println(lex.getMessage());
}
if (!_gotLocation) {
getLocationFromGoogle();
}
}
public void run() {
int bbMapsHandle = CodeModuleManager.getModuleHandle("net_rim_bb_lbs"); // OS < 6.0
int bbMapsHandle60 = CodeModuleManager.getModuleHandle("net_rim_bb_maps"); // OS 6.0+
if (bbMapsHandle > 0 || bbMapsHandle60 > 0) {
tryGetLocationFromDevice();
} else {
getLocationFromGoogle();
}
}
}
private void writeDataGoogleMaps(OutputStream out, int cellID, int lac) throws IOException {
DataOutputStream dataOutputStream = new DataOutputStream(out);
dataOutputStream.writeShort(21);
dataOutputStream.writeLong(0);
dataOutputStream.writeUTF("en");
dataOutputStream.writeUTF("Android");
dataOutputStream.writeUTF("1.0");
dataOutputStream.writeUTF("Web");
dataOutputStream.writeByte(27);
dataOutputStream.writeInt(0);
dataOutputStream.writeInt(0);
dataOutputStream.writeInt(3);
dataOutputStream.writeUTF("");
dataOutputStream.writeInt(cellID);
dataOutputStream.writeInt(lac);
dataOutputStream.writeInt(0);
dataOutputStream.writeInt(0);
dataOutputStream.writeInt(0);
dataOutputStream.writeInt(0);
dataOutputStream.flush();
}
}
There's a lot of code that we can't see (e.g. getLatitude(), getLongitude(), refreshDetails()). So, there could be something going wrong there. Also, I don't see any Loading Screen in the code you posted, so I can't say why that isn't showing.
But, here's something that doesn't look right:
synchronized (Application.getEventLock())
{
busyDialog.show();
}
If you read this BlackBerry forum question, you'll see that trying to synchronize on the application event lock from the main (UI) thread can cause your app to freeze. The public void fieldChanged(Field field, int context) method is always called on the UI thread, because it's the UI thread that monitors buttons for clicks, and calls back your click handlers, like fieldChanged().
You can also read the BlackBerry API docs for Application, that explain that getEventLock() is for worker (also known as background) threads, not the main (aka UI) thread.
So, there's no need to use special techniques to get the event lock, in code that already runs on the UI thread. Instead of the code above, just do this:
busyDialog.show();
Both of these techniques:
synchronized (Application.getEventLock())
{
busyDialog.show();
}
or
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
busyDialog.show();
}
});
are ways to safely call UI methods from a background thread. But, you shouldn't use those in code that you know is running on the UI thread already.
Try fixing that, and see if your problem disappears.
Edit: also, your code is checking for a username and password before refreshing the location. Is that really what you want? I don't think this has anything to do with your problem, but normally, I wouldn't expect to need a username or password to access location services. Of course, I don't know your application, so this is really just a comment on my part.
I think thee is simple answer is error here:
((longi == "0.0" || lati == "0.0") || (longi.length() == 0 || lati.length()==0));
You have to use String.equals() instead of == operator.
After first call longi and lati have "0.0" value. But == will return false because it compare references by default and they are different because it's different objects.

Display a progress screen for BlackBerry app

How to display a progress screen when BlackBerry application is fetching data from remote server ?
I want an progress screen without animated gif without any button. (OK or Cancel )
public class ProgressDialog extends PopupScreen
{
public ProgressDialog(String waitString)
{
super(new VerticalFieldManager());
add(new LabelField(waitString,Field.FIELD_HCENTER));//add a string which u want to show for progressing
}
}
ProgressDialog progress = new ProgressDialog("Please Wait...");
//Add screen to UI
UiApplication.getUiApplication().pushScreen(progress);
//Remove screen from UI
progress.close();
ProgressBar progressBar = new ProgressBar("Waiting for location update....",50,1000);
progressBar.start(); // Start progress bar
progressBar.remove(); //remove progress bar
ProgressBar Thread
public class ProgressBar extends Thread {
Thread thd;
private int maximum, timeout;
private boolean useful = true;
private PopupScreen popup;
private int iterations = 0;
/**
* Object constructor
*
* #param title
* Text to display on popup area
* #param maximum
* Range / width of the gauge field of progress bar
* #param timeout
* Milliseconds to pause between updates to progress bar
* #see GaugeField
* #see Thread
* #see PopupScreen
*/
public ProgressBar(String title, int maximum, int timeout) {
this.maximum = maximum;
this.timeout = timeout;
VerticalFieldManager manager = new VerticalFieldManager();
popup = new PopupScreen(manager);
manager.add(new LabelField(title));
}
/**
* run() method for starting thread
*/
public void run() {
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
UiApplication.getUiApplication().pushScreen(popup);
}
});
int iterations = 0;
while (useful) {
System.out.println("I m here in while runn "+ useful);
try {
Thread.sleep(timeout);
} catch (Exception e) {
}
if (++iterations > maximum)
{
iterations = 1;
useful = false;
UiApplication.getUiApplication().invokeLater( new Runnable()
{
public void run ()
{
_locationProvider.reset();
Dialog.alert("Location not found.");
}
} );
}
// gaugeField.setValue(iterations);
}
if (popup.isDisplayed()) {
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
UiApplication.getUiApplication().popScreen(popup);
}
});
}
}
/**
* Method to shutdown the thread and remove the popup screen
*
*/
public synchronized void remove() {
useful = false;
}
}

BlackBerry - "Media unloaded while initializing" error

I am trying to play a video based on the videorecordingdemo sample from JDE7.0 (code below).
I am building for OS5.0 - which is why I cannot just run the whole demo app which is written for OS7.0.
I am using the emulator (9300) and have set up a folder to be used as my sd card. I have placed a .AVI video in there. I have also tried placing the .AVI into the resources, and streaming it from there.
In both cases, when I call Player.start(), the following exception is thrown:
net.rim.device.internal.media.RimMediaException: Media unloaded while initializing
I would like to know:
What does this error mean?
How can I fix it?
Alternatively are the any really special, stringent requirements for .AVI files to play?
Update: Tried the app on a real Torch device, and it gave
net.rim.device.internal.media.UnloadedMediaException
FWIW here is the sample code - as copied directly from the videorecordingdemo sample app.
package mypackage;
/*
* VideoPlaybackScreen.java
*
* Copyright © 1998-2011 Research In Motion Ltd.
*
* Note: For the sake of simplicity, this sample application may not leverage
* resource bundles and resource strings. However, it is STRONGLY recommended
* that application developers make use of the localization features available
* within the BlackBerry development platform to ensure a seamless application
* experience across a variety of languages and geographies. For more information
* on localizing your application, please refer to the BlackBerry Java Development
* Environment Development Guide associated with this release.
*/
import javax.microedition.media.Player;
import javax.microedition.media.PlayerListener;
import javax.microedition.media.control.VideoControl;
import javax.microedition.media.control.VolumeControl;
import java.io.IOException;
import java.io.InputStream;
import javax.microedition.io.Connector;
import javax.microedition.io.file.FileConnection;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.Dialog;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.container.MainScreen;
/**
* A screen for playing a video
*/
public class VideoPlaybackScreen extends MainScreen
{
private Player _videoPlayer;
private VideoControl _videoControl;
/**
* Constructs a screen to playback the video from a specified input stream
*
* #param inputStream The InputStream of the video to display
*
* #throws NullPointerException Thrown if <code>inputStream</code> is null
*/
public VideoPlaybackScreen(InputStream inputStream)
{
if (inputStream == null)
{
throw new NullPointerException("'inputStream' cannot be null");
}
try
{
_videoPlayer = javax.microedition.media.Manager.createPlayer(inputStream, "video/sbv");
initScreen();
}
catch( Exception e )
{
Dialog.alert("Exception while initializing the playback video player\n\n" + e);
}
}
/**
* Constructs the screen to playback the video from a file
*
* #param file A locator string in URI syntax that points to the video file
*/
public VideoPlaybackScreen(String file)
{
boolean notEmpty;
try
{
FileConnection fconn = (FileConnection) Connector.open(file);
notEmpty = fconn.exists() && fconn.fileSize() > 0;
fconn.close();
}
catch( IOException e )
{
Dialog.alert("Exception while accessing the video filesize:\n\n" + e);
notEmpty = false;
}
// Initialize the player if the video is not empty
if( notEmpty )
{
try
{
_videoPlayer = javax.microedition.media.Manager.createPlayer(file);
initScreen();
}
catch( Exception e )
{
Dialog.alert("Exception while initializing the playback video player\n\n" + e);
}
}
else
{
add(new LabelField("The video file you are trying to play is empty"));
}
}
/**
* Initializes the screen after the player has been created
*
* #throws Exception Thrown if an error occurs when initializing the video player, video display or volume control
*/
private void initScreen() throws Exception
{
_videoPlayer.realize();
_videoPlayer.addPlayerListener(new PlayerListener()
{
/**
* #see javax.microedition.media.PlayerListener#playerUpdate(Player, String, Object)
*/
public void playerUpdate(Player player, String event, Object eventData)
{
// Alert the user and close the screen after the video has
// finished playing.
if( event == PlayerListener.END_OF_MEDIA )
{
UiApplication.getUiApplication().invokeLater(new Runnable()
{
public void run()
{
Dialog.alert("Finished playing");
close();
}
});
}
}
});
// Set up the playback
_videoControl = (VideoControl) _videoPlayer.getControl("VideoControl");
Field vField = (Field) _videoControl.initDisplayMode(VideoControl.USE_GUI_PRIMITIVE,
"net.rim.device.api.ui.Field");
add(vField);
VolumeControl vol = (VolumeControl) _videoPlayer.getControl("VolumeControl");
vol.setLevel(30);
}
/**
* #see net.rim.device.api.ui.Field#onVisibilityChange(boolean)
*/
protected void onVisibilityChange(boolean visible)
{
// If the screen becomes visible and the video player was created, then
// start the playback.
if( visible && _videoPlayer != null )
{
try
{
_videoPlayer.start();
}
catch( final Exception e )
{
UiApplication.getUiApplication().invokeLater(new Runnable()
{
public void run()
{
// If starting the video fails, terminate the playback
Dialog.alert("Exception while starting the video\n\n" + e);
close();
}
});
}
}
}
/**
* #see net.rim.device.api.ui.Screen#onClose()
*/
public void close()
{
// Close the video player if it was created
if( _videoPlayer != null )
{
_videoPlayer.close();
}
super.close();
}
}

Resources