Can somebody tell me how to close the Screen (which opened by the BarcodeScanner) and show the mainscreen again after the barcodeDecoded method was invoked?
I can't get it right. I tried a lot, one of them was this:
public void barcodeDecoded(String rawText) {
final String result = rawText;
try
{
final UiApplication ui = UiApplication.getUiApplication();
final MainScreen current = (MainScreen) ui.getActiveScreen();
System.out.println("Current: " + current.toString());
if (UiApplication.isEventDispatchThread()) {
getText(result);
ui.popScreen(current);
System.out.println("Close Window by active screen");
ui.pushScreen(_frm);
System.out.println("Push screen frmMain");
}else{
ui.invokeLater(new Runnable() {
public void run() {
getText(result); <-- Abstract method to use within the main app.
ui.popScreen(current);
ui.pushScreen(_frm);
}
});
}
}catch(Exception err){
System.out.println(err.getMessage());
}
}
the abstract method when i start the Scanner
private MenuItem mnuCamera = new MenuItem("Scan", 1, 1){
public void run(){
frmMain f = (frmMain)getScreen();
_decode = new BarcodeDecoderClass(f) {
public void getText(String tekst) {
setScannedText(tekst);
}
};
_decode.Start();
}
};
Ok, for the people who are stuck with the same problem. I found it out. Below you find the complete code:
The BarcodeScanner class:
public abstract class BarcodeDecoderClass implements BarcodeDecoderListener {
private Hashtable _hints;
private Vector _formats;
private BarcodeScanner _scanner;
private BarcodeDecoder _decoder;
private Field _viewFinder;
private MainScreen _screen;
public abstract void getText(String tekst, Screen screen);
public BarcodeDecoderClass(){
_hints = new Hashtable();
_formats = new Vector();
_formats.addElement(BarcodeFormat.QR_CODE);
_hints.put(DecodeHintType.POSSIBLE_FORMATS, _formats);
_decoder = new BarcodeDecoder(_hints);
try
{
_scanner = new BarcodeScanner(_decoder, this);
_scanner.getVideoControl().setDisplayFullScreen(true);
_viewFinder = _scanner.getViewfinder();
}catch(Exception err){
System.out.println(err.getMessage());
}
}
public void Start(){
try
{
_screen = new MainScreen();
_screen.add(_viewFinder);
UiApplication.getUiApplication().pushScreen(_screen);
_scanner.startScan();
}catch(Exception err){
System.out.println(err.getMessage());
}
}
public synchronized void Close(){
if(_scanner.isScanning()){
try{
_scanner.stopScan();
}catch(Exception err){
Dialog.alert(err.getMessage());
}
}
_scanner.getVideoControl().setVisible(false);
_scanner.getPlayer().close();
}
public void barcodeDecoded(String rawText) {
try
{
getText(rawText, _screen);
}catch(Exception err){
System.out.println(err.getMessage());
}
}
}
The MainScreen from which I start the BarcodeScanner (i just copied the method)
private MenuItem mnuCamera = new MenuItem("Scan", 1, 1){
public void run(){
final Screen f = getScreen();
_decode = new BarcodeDecoderClass() {
public void getText(String tekst, final Screen _screen) {
setScannedText(tekst);
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
_decode.Close();
_screen.close();
}
});
}
};
_decode.Start();
}
};
May be help full this code.
import java.util.Hashtable;
import java.util.Vector;
import net.rim.device.api.barcodelib.BarcodeDecoder;
import net.rim.device.api.barcodelib.BarcodeDecoderListener;
import net.rim.device.api.barcodelib.BarcodeScanner;
import net.rim.device.api.system.KeyListener;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.FieldChangeListener;
import net.rim.device.api.ui.Keypad;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.ButtonField;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.container.FullScreen;
import net.rim.device.api.ui.container.MainScreen;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.DecodeHintType;
public class BarcodeScanSample extends MainScreen{
private FullScreen _barcodeScreen;
private BarcodeScanner _scanner;
private LabelField lblBarcodeText;
private ButtonField btnScan;
public BarcodeScanSample(String barcodeText){
lblBarcodeText = new LabelField(barcodeText);
add(lblBarcodeText);
btnScan = new ButtonField("Scan");
btnScan.setChangeListener(new FieldChangeListener() {
public void fieldChanged(Field field, int context) {
scanBarcode();
}
});
add(btnScan);
}
private void scanBarcode() {
// If we haven't scanned before, we will set up our barcode scanner
if (_barcodeScreen == null) {
// First we create a hashtable to hold all of the hints that we can
// give the API about how we want to scan a barcode to improve speed
// and accuracy.
Hashtable hints = new Hashtable();
// The first thing going in is a list of formats. We could look for
// more than one at a time, but it's much slower. and set Barcode Format.
Vector formats = new Vector();
formats.addElement(BarcodeFormat.QR_CODE);
formats.addElement(BarcodeFormat.CODE_128);
formats.addElement(BarcodeFormat.CODE_39);
formats.addElement(BarcodeFormat.DATAMATRIX);
formats.addElement(BarcodeFormat.EAN_13);
formats.addElement(BarcodeFormat.EAN_8);
formats.addElement(BarcodeFormat.ITF);
formats.addElement(BarcodeFormat.PDF417);
formats.addElement(BarcodeFormat.UPC_A);
formats.addElement(BarcodeFormat.UPC_E);
hints.put(DecodeHintType.POSSIBLE_FORMATS, formats);
// We will also use the "TRY_HARDER" flag to make sure we get an
// accurate scan
hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
// We create a new decoder using those hints
BarcodeDecoder decoder = new BarcodeDecoder(hints);
// Finally we can create the actual scanner with a decoder and a
// listener that will handle the data stored in the barcode. We put
// that in our view screen to handle the display.
try {
_scanner = new BarcodeScanner(decoder, new MyBarcodeDecoderListener());
_barcodeScreen = new MyBarcodeScannerViewScreen(_scanner);
} catch (Exception e) {
System.out.println("Could not initialize barcode scanner: " + e);
return;
}
}
// If we get here, all the barcode scanning infrastructure should be set
// up, so all we have to do is start the scan and display the viewfinder
try {
_scanner.startScan();
UiApplication.getUiApplication().pushScreen(_barcodeScreen);
} catch (Exception e) {
System.out.println("Could not start scan: " + e);
}
}
/***
* MyBarcodeScannerViewScreen
* <p>
* This view screen is simply an extension of MainScreen that will hold our
* scanner's viewfinder, and handle cleanly stopping the scan if the user
* decides they want to abort via the back button.
*
* #author PBernhardt
*
*/
private class MyBarcodeScannerViewScreen extends MainScreen {
public MyBarcodeScannerViewScreen(BarcodeScanner scanner) {
super();
try {
// Get the viewfinder and add it to the screen
_scanner.getVideoControl().setDisplayFullScreen(true);
Field viewFinder = _scanner.getViewfinder();
this.add(viewFinder);
// Create and add our key listener to the screen
this.addKeyListener(new MyKeyListener());
} catch (Exception e) {
System.out.println("Error creating view screen: " + e);
}
}
/***
* MyKeyListener
* <p>
* This KeyListener will stop the current scan cleanly when the back
* button is pressed, and then pop the viewfinder off the stack.
*
* #author PBernhardt
*
*/
private class MyKeyListener implements KeyListener {
public boolean keyDown(int keycode, int time) {
// First convert the keycode into an actual key event, taking
// modifiers into account
int key = Keypad.key(keycode);
// From there we can compare against the escape key constant. If
// we get it, we stop the scan and pop this screen off the stack
if (key == Keypad.KEY_ESCAPE) {
try {
_scanner.stopScan();
} catch (Exception e) {
System.out.println("Error stopping scan: " + e);
}
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
UiApplication.getUiApplication().popScreen(_barcodeScreen);
}
});
return true;
}
// Otherwise, we'll return false so as not to consume the
// keyDown event
return false;
}
// We will only act on the keyDown event
public boolean keyChar(char key, int status, int time) {
return false;
}
public boolean keyRepeat(int keycode, int time) {
return false;
}
public boolean keyStatus(int keycode, int time) {
return false;
}
public boolean keyUp(int keycode, int time) {
return false;
}
}
}
/***
* MyBarcodeDecoderListener
* <p>
* This BarcodeDecoverListener implementation tries to open any data encoded
* in a barcode in the browser.
*
* #author PBernhardt
*
**/
private class MyBarcodeDecoderListener implements BarcodeDecoderListener {
public void barcodeDecoded(final String rawText) {
// First pop the viewfinder screen off of the stack so we can see
// the main app
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
UiApplication.getUiApplication().popScreen(_barcodeScreen);
}
});
_barcodeScreen.invalidate();
//Display this barcode on LabelField on BarcodeScanSample MainScreen we can also set whatever field here.
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
UiApplication.getUiApplication().popScreen();
UiApplication.getUiApplication().pushScreen(new BarcodeScanSample(rawText));
_barcodeScreen.close();
_barcodeScreen=null;
}
});
}
}
}
Related
I am learning Java and have encountered an unexpected problem:
variable i is getting updated in mouse listener but updated value is not getting passed back to main program. But if I uncomment Thread.sleep(1) block everything is back to normal.
Here is the program:
import java.awt.*;
import java.awt.event.*;
public class MouseEventDemo extends Frame
implements MouseListener {
String msg = "";
int mouseX = 0, mouseY = 0; // coordinates of mouse
static int i=0;//State variable
public MouseEventDemo()
{
addMouseListener(this);
addWindowListener(new MyWindowAdapter());
}
// Handle mouse clicked.
public void mouseClicked(MouseEvent me)
{
i=1;
msg = "Click received. i= "+i;
mouseX = me.getX();
mouseY = me.getY();
repaint();
}
public void mouseMoved(MouseEvent me)
{
}
public void mouseDragged(MouseEvent me)
{
}
public void mouseExited(MouseEvent me)
{
}
public void mouseEntered(MouseEvent me)
{
}
public void mouseReleased(MouseEvent me)
{
}
public void mousePressed(MouseEvent me)
{
}
// Display msg in the window at current X,Y location.
public void paint(Graphics g)
{
g.drawString(msg, mouseX, mouseY);
}
public static void main(String[] args)
{
MouseEventDemo appwin = new MouseEventDemo();
appwin.setSize(new Dimension(300, 300));
appwin.setTitle("MouseEventDemo");
appwin.setVisible(true);
while (true)
{
if(i==1)
{
System.out.println("Value of i is: "+i);
i=0;
}
/*
try
{
Thread.sleep(1);
}
catch(Exception e)
{
System.out.println(e);
};
*/
}
}
}
class MyWindowAdapter extends WindowAdapter
{
public void windowClosing(WindowEvent we)
{
System.exit(0);
}
}
This program behaves not like I have expected, but with Thread.sleep(1) it changes it behaviour
I'm a student doing an Android Things project, which is about connecting Rasperi pi with an Accelerometer sensor to get acceleration data, I finished the coding part in Android Studio and the sensor is working fine, then I tried to connect my project to the cloud by following this tutorial: http://blog.blundellapps.co.uk/tut-google-cloud-iot-core-mqtt-on-android/
I think I have to publish the accelerometer data to the cloud by calling this method below in MainActivity class, I did that but still have an error, see the update I did at end of this question please.
#Override
public void onSensorChanged(SensorEvent event) {
Log.d(TAG, "Accel X " + event.values[0]);
Log.d(TAG, "Accel Y " + event.values[1]);
Log.d(TAG, "Accel Z " + event.values[2]);
}
Also, do I have to do something in the cloud platform to receive the data?, I already set up the communication with my Google IoT Core details as shown in the below code:
communicator = new IotCoreCommunicator.Builder()
.withContext(this)
.withCloudRegion("us-central1")
.withProjectId("my-first-project-198704")
.withRegistryId("vibration")
.withDeviceId("my-device")
.withPrivateKeyRawFileId(R.raw.rsa_private)
.build();
This is what I'm seeing in the cloud:
And this is the acceleration data I have in Android Studio:
My project consists of two modules but here I will attach only the second module because the question is limited to 3000 characters only and the second module is what I need to edit I think.
sample module:
AccelerometerActivity class:
package com.cacaosd.sample;
import android.app.Activity;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.util.Log;
import com.cacaosd.adxl345.ADXL345SensorDriver;
import com.cacaosd.sample.BoardDefaults;
import java.io.IOException;
public class AccelerometerActivity extends Activity implements SensorEventListener {
private static final String TAG = AccelerometerActivity.class.getSimpleName();
private ADXL345SensorDriver mSensorDriver;
private SensorManager mSensorManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mSensorManager.registerDynamicSensorCallback(new SensorManager.DynamicSensorCallback() {
#Override
public void onDynamicSensorConnected(Sensor sensor) {
if (sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
mSensorManager.registerListener(AccelerometerActivity.this,
sensor, SensorManager.SENSOR_DELAY_NORMAL);
}
}
});
try {
mSensorDriver = new ADXL345SensorDriver(BoardDefaults.getI2CPort());
mSensorDriver.registerAccelerometerSensor();
} catch (IOException e) {
Log.e(TAG, "Error configuring sensor", e);
}
}
#Override
protected void onDestroy() {
super.onDestroy();
Log.i(TAG, "Closing sensor");
if (mSensorDriver != null) {
mSensorManager.unregisterListener(this);
try {
mSensorDriver.close();
} catch (IOException e) {
Log.e(TAG, "Error closing sensor", e);
} catch (Exception e) {
e.printStackTrace();
} finally {
mSensorDriver = null;
}
}
}
#Override
public void onSensorChanged(SensorEvent event) {
Log.d(TAG, "Accel X " + event.values[0]);
Log.d(TAG, "Accel Y " + event.values[1]);
Log.d(TAG, "Accel Z " + event.values[2]);
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
Log.i(TAG, "sensor accuracy changed: " + accuracy);
}
}
BoardDefaults class:
package com.cacaosd.sample;
import android.os.Build;
import com.google.android.things.pio.PeripheralManagerService;
import java.util.List;
/**
* Created by cagdas on 20.12.2016.
*/
#SuppressWarnings("WeakerAccess")
public class BoardDefaults {
private static final String DEVICE_EDISON_ARDUINO = "edison_arduino";
private static final String DEVICE_EDISON = "edison";
private static final String DEVICE_RPI3 = "rpi3";
private static final String DEVICE_NXP = "imx6ul";
private static String sBoardVariant = "";
/**
* Return the preferred I2C port for each board.
*/
public static String getI2CPort() {
switch (getBoardVariant()) {
case DEVICE_EDISON_ARDUINO:
return "I2C6";
case DEVICE_EDISON:
return "I2C1";
case DEVICE_RPI3:
return "I2C1";
case DEVICE_NXP:
return "I2C2";
default:
throw new IllegalStateException("Unknown Build.DEVICE " + Build.DEVICE);
}
}
private static String getBoardVariant() {
if (!sBoardVariant.isEmpty()) {
return sBoardVariant;
}
sBoardVariant = Build.DEVICE;
// For the edison check the pin prefix
// to always return Edison Breakout pin name when applicable.
if (sBoardVariant.equals(DEVICE_EDISON)) {
PeripheralManagerService pioService = new PeripheralManagerService();
List<String> gpioList = pioService.getGpioList();
if (gpioList.size() != 0) {
String pin = gpioList.get(0);
if (pin.startsWith("IO")) {
sBoardVariant = DEVICE_EDISON_ARDUINO;
}
}
}
return sBoardVariant;
}
}
IotCoreCommunicator class:
package com.cacaosd.sample1;
import android.content.Context;
import android.util.Log;
import java.util.concurrent.TimeUnit;
import org.eclipse.paho.android.service.MqttAndroidClient;
import org.eclipse.paho.client.mqttv3.IMqttActionListener;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.IMqttToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
public class IotCoreCommunicator {
private static final String SERVER_URI = "ssl://mqtt.googleapis.com:8883";
public static class Builder {
private Context context;
private String projectId;
private String cloudRegion;
private String registryId;
private String deviceId;
private int privateKeyRawFileId;
public Builder withContext(Context context) {
this.context = context;
return this;
}
public Builder withProjectId(String projectId) {
this.projectId = projectId;
return this;
}
public Builder withCloudRegion(String cloudRegion) {
this.cloudRegion = cloudRegion;
return this;
}
public Builder withRegistryId(String registryId) {
this.registryId = registryId;
return this;
}
public Builder withDeviceId(String deviceId) {
this.deviceId = deviceId;
return this;
}
public Builder withPrivateKeyRawFileId(int privateKeyRawFileId) {
this.privateKeyRawFileId = privateKeyRawFileId;
return this;
}
public IotCoreCommunicator build() {
if (context == null) {
throw new IllegalStateException("context must not be null");
}
if (projectId == null) {
throw new IllegalStateException("projectId must not be null");
}
if (cloudRegion == null) {
throw new IllegalStateException("cloudRegion must not be null");
}
if (registryId == null) {
throw new IllegalStateException("registryId must not be null");
}
if (deviceId == null) {
throw new IllegalStateException("deviceId must not be null");
}
String clientId = "projects/" + projectId + "/locations/" + cloudRegion + "/registries/" + registryId + "/devices/" + deviceId;
if (privateKeyRawFileId == 0) {
throw new IllegalStateException("privateKeyRawFileId must not be 0");
}
MqttAndroidClient client = new MqttAndroidClient(context, SERVER_URI, clientId);
IotCorePasswordGenerator passwordGenerator = new IotCorePasswordGenerator(projectId, context.getResources(), privateKeyRawFileId);
return new IotCoreCommunicator(client, deviceId, passwordGenerator);
}
}
private final MqttAndroidClient client;
private final String deviceId;
private final IotCorePasswordGenerator passwordGenerator;
IotCoreCommunicator(MqttAndroidClient client, String deviceId, IotCorePasswordGenerator passwordGenerator) {
this.client = client;
this.deviceId = deviceId;
this.passwordGenerator = passwordGenerator;
}
public void connect() {
monitorConnection();
clientConnect();
subscribeToConfigChanges();
}
private void monitorConnection() {
client.setCallback(new MqttCallback() {
#Override
public void connectionLost(Throwable cause) {
Log.e("TUT", "connection lost", cause);
}
#Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
Log.d("TUT", "message arrived " + topic + " MSG " + message);
// You need to do something with messages when they arrive
}
#Override
public void deliveryComplete(IMqttDeliveryToken token) {
Log.d("TUT", "delivery complete " + token);
}
});
}
private void clientConnect() {
try {
MqttConnectOptions connectOptions = new MqttConnectOptions();
// Note that the the Google Cloud IoT Core only supports MQTT 3.1.1, and Paho requires that we explicitly set this.
// If you don't, the server will immediately close its connection to your device.
connectOptions.setMqttVersion(MqttConnectOptions.MQTT_VERSION_3_1_1);
// With Google Cloud IoT Core, the username field is ignored, however it must be set for the
// Paho client library to send the password field. The password field is used to transmit a JWT to authorize the device.
connectOptions.setUserName("unused-but-necessary");
connectOptions.setPassword(passwordGenerator.createJwtRsaPassword());
IMqttToken iMqttToken = client.connect(connectOptions);
iMqttToken.setActionCallback(new IMqttActionListener() {
#Override
public void onSuccess(IMqttToken asyncActionToken) {
Log.d("TUT", "success, connected");
}
#Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
Log.e("TUT", "failure, not connected", exception);
}
});
iMqttToken.waitForCompletion(TimeUnit.SECONDS.toMillis(30));
Log.d("TUT", "IoT Core connection established.");
} catch (MqttException e) {
throw new IllegalStateException(e);
}
}
/**
* Configuration is managed and sent from the IoT Core Platform
*/
private void subscribeToConfigChanges() {
try {
client.subscribe("/devices/" + deviceId + "/config", 1);
} catch (MqttException e) {
throw new IllegalStateException(e);
}
}
public void publishMessage(String subtopic, String message) {
String topic = "/devices/" + deviceId + "/" + subtopic;
String payload = "{msg:\"" + message + "\"}";
MqttMessage mqttMessage = new MqttMessage(payload.getBytes());
mqttMessage.setQos(1);
try {
client.publish(topic, mqttMessage);
Log.d("TUT", "IoT Core message published. To topic: " + topic);
} catch (MqttException e) {
throw new IllegalStateException(e);
}
}
public void disconnect() {
try {
Log.d("TUT", "IoT Core connection disconnected.");
client.disconnect();
} catch (MqttException e) {
throw new IllegalStateException(e);
}
}
}
IotCorePasswordGenerator class:
package com.cacaosd.sample1;
import android.content.res.Resources;
import android.util.Base64;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.time.Duration;
import java.time.Instant;
import java.util.Date;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
class IotCorePasswordGenerator {
private final String projectId;
private final Resources resources;
private final int privateKeyRawFileId;
IotCorePasswordGenerator(String projectId, Resources resources, int privateKeyRawFileId) {
this.projectId = projectId;
this.resources = resources;
this.privateKeyRawFileId = privateKeyRawFileId;
}
char[] createJwtRsaPassword() {
try {
byte[] privateKeyBytes = decodePrivateKey(resources, privateKeyRawFileId);
return createJwtRsaPassword(projectId, privateKeyBytes).toCharArray();
} catch (NoSuchAlgorithmException e) {
throw new IllegalStateException("Algorithm not supported. (developer error)", e);
} catch (InvalidKeySpecException e) {
throw new IllegalStateException("Invalid Key spec. (developer error)", e);
} catch (IOException e) {
throw new IllegalStateException("Cannot read private key file.", e);
}
}
private static byte[] decodePrivateKey(Resources resources, int privateKeyRawFileId) throws IOException {
try(InputStream inStream = resources.openRawResource(privateKeyRawFileId)) {
return Base64.decode(inputToString(inStream), Base64.DEFAULT);
}
}
private static String inputToString(InputStream is) {
java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
}
private static String createJwtRsaPassword(String projectId, byte[] privateKeyBytes) throws NoSuchAlgorithmException, InvalidKeySpecException {
return createPassword(projectId, privateKeyBytes, "RSA", SignatureAlgorithm.RS256);
}
private static String createPassword(String projectId, byte[] privateKeyBytes, String algorithmName, SignatureAlgorithm signatureAlgorithm) throws NoSuchAlgorithmException, InvalidKeySpecException {
Instant now = Instant.now();
// Create a JWT to authenticate this device. The device will be disconnected after the token
// expires, and will have to reconnect with a new token. The audience field should always be set
// to the GCP project id.
JwtBuilder jwtBuilder =
Jwts.builder()
.setIssuedAt(Date.from(now))
.setExpiration(Date.from(now.plus(Duration.ofMinutes(20))))
.setAudience(projectId);
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(privateKeyBytes);
KeyFactory kf = KeyFactory.getInstance(algorithmName);
return jwtBuilder.signWith(signatureAlgorithm, kf.generatePrivate(spec)).compact();
}
}
MainActivity class:
package com.cacaosd.sample1;
import android.app.Activity;
import android.hardware.SensorEvent;
import android.os.Bundle;
import android.os.HandlerThread;
import android.os.Handler;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.util.Log;
import com.cacaosd.sample.AccelerometerActivity;
import com.cacaosd.sample.R;
import com.cacaosd.sample1.IotCoreCommunicator;
import com.google.android.things.pio.Gpio;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
public class MainActivity extends Activity {
AccelerometerActivity mAccelerometerActivity = new AccelerometerActivity();
private IotCoreCommunicator communicator;
private Handler handler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Setup the communication with your Google IoT Core details
communicator = new IotCoreCommunicator.Builder()
.withContext(this)
.withCloudRegion("us-central1") // ex: europe-west1
.withProjectId("my-first-project-198704") // ex: supercoolproject23236
.withRegistryId("vibration") // ex: my-devices
.withDeviceId("my-device") // ex: my-test-raspberry-pi
.withPrivateKeyRawFileId(R.raw.rsa_private)
.build();
HandlerThread thread = new HandlerThread("MyBackgroundThread");
thread.start();
handler = new Handler(thread.getLooper());
handler.post(connectOffTheMainThread); // Use whatever threading mechanism you want
}
private final Runnable connectOffTheMainThread = new Runnable() {
#Override
public void run() {
communicator.connect();
handler.post(sendMqttMessage);
}
};
private final Runnable sendMqttMessage = new Runnable() {
private int i;
/**
* We post 100 messages as an example, 1 a second
*/
#Override
public void run() {
if (i == 100) {
return;
}
SensorEvent event = null;
// events is the default topic for MQTT communication
String subtopic = "events";
// Your message you want to send
String message = "Hello World " + i++;
communicator.publishMessage(subtopic, message);
handler.postDelayed(this, TimeUnit.SECONDS.toMillis(1));
}
};
#Override
protected void onDestroy() {
communicator.disconnect();
super.onDestroy();
}
MainActivity class:
package com.cacaosd.sample1;
import android.app.Activity;
import android.hardware.SensorEvent;
import android.os.Bundle;
import android.os.HandlerThread;
import android.os.Handler;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.util.Log;
import com.cacaosd.sample.AccelerometerActivity;
import com.cacaosd.sample.R;
import com.cacaosd.sample1.IotCoreCommunicator;
import com.google.android.things.pio.Gpio;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
public class MainActivity extends Activity {
AccelerometerActivity mAccelerometerActivity = new AccelerometerActivity();
private IotCoreCommunicator communicator;
private Handler handler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Setup the communication with your Google IoT Core details
communicator = new IotCoreCommunicator.Builder()
.withContext(this)
.withCloudRegion("us-central1") // ex: europe-west1
.withProjectId("my-first-project-198704") // ex: supercoolproject23236
.withRegistryId("vibration") // ex: my-devices
.withDeviceId("my-device") // ex: my-test-raspberry-pi
.withPrivateKeyRawFileId(R.raw.rsa_private)
.build();
HandlerThread thread = new HandlerThread("MyBackgroundThread");
thread.start();
handler = new Handler(thread.getLooper());
handler.post(connectOffTheMainThread); // Use whatever threading mechanism you want
}
private final Runnable connectOffTheMainThread = new Runnable() {
#Override
public void run() {
communicator.connect();
handler.post(sendMqttMessage);
}
};
private final Runnable sendMqttMessage = new Runnable() {
private int i;
/**
* We post 100 messages as an example, 1 a second
*/
#Override
public void run() {
if (i == 100) {
return;
}
SensorEvent event = null;
// events is the default topic for MQTT communication
String subtopic = "events";
// Your message you want to send
String message = "Hello World " + i++;
communicator.publishMessage(subtopic, message);
handler.postDelayed(this, TimeUnit.SECONDS.toMillis(1));
}
};
#Override
protected void onDestroy() {
communicator.disconnect();
super.onDestroy();
}
}
Update:
I added a third input (int acceleration) on publishMessage() method inside IotCoreCommunicator class like below:
public void publishMessage(String subtopic, String message, int acceleration) {
String topic = "/devices/" + deviceId + "/" + subtopic;
String payload = "{msg:\"" + message + "\"}";
MqttMessage mqttMessage = new MqttMessage(payload.getBytes());
mqttMessage.setQos(1);
try {
client.publish(topic, mqttMessage);
Log.d("TUT", "IoT Core message published. To topic: " + topic);
} catch (MqttException e) {
throw new IllegalStateException(e);
}
}
Then I call it on run() method inside the MainActivity class like below:
public void run() {
if (i == 100) {
return;
}
SensorEvent event = null;
// events is the default topic for MQTT communication
String subtopic = "events";
// Your message you want to send
String message = "Hello World " + i++;
int acceleration = mAccelerometerActivity.onSensorChanged(SensorEvent event.values);
communicator.publishMessage(subtopic, message, acceleration);
handler.postDelayed(this, TimeUnit.SECONDS.toMillis(1));
}
};
But I still have this error in the below screenshot:
(';' or ) expected)
Also the third input I added is shown like never been used as you see in the screenshot below, is this has any effect?
Thank you.
Eclipse keeps telling me about invoke problems. This is the message i get as can be seen below. Please help me resolve this problem. What code should i put to get rid of the invoke problem. thanks.
Warning!: method 'parsepack.xmlparsing.navigationClick(int,int)' not invoked.
Warning!: method 'parsepack.xmlparsing.insert(String,int)' not invoked.
here is the method navigationClick()
protected boolean navigationClick(int status, int time)
{
try
{
//navigate here to another screen
ui.pushScreen(new ResultScreen());
}
catch(Exception e)
{
System.out.println("Exception:- : navigationClick() "+e.toString());
}
return true;
}
here is the method insert()
public void insert(String toInsert, int index)
{
listElements.addElement(toInsert);
}
here is the class xmlparsing.java
package parsepack;
import java.io.IOException;
import java.io.InputStream;
import java.util.Vector;
import javax.microedition.io.Connector;
import javax.microedition.io.StreamConnection;
import net.rim.device.api.system.Bitmap;
import net.rim.device.api.system.Display;
import net.rim.device.api.ui.DrawStyle;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.FieldChangeListener;
import net.rim.device.api.ui.Graphics;
import net.rim.device.api.ui.Manager;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.ListField;
import net.rim.device.api.ui.component.ListFieldCallback;
import net.rim.device.api.ui.container.MainScreen;
import net.rim.device.api.ui.container.VerticalFieldManager;
import net.rim.device.api.xml.parsers.DocumentBuilder;
import net.rim.device.api.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class xmlparsing extends UiApplication implements ListFieldCallback, FieldChangeListener
{
public static void main(String[] args)
{
xmlparsing app = new xmlparsing();
app.enterEventDispatcher();
}
public long mycolor ;
Connection _connectionthread;
private static ListField _list;
private static Vector listElements = new Vector();
public MainScreen screen = new MainScreen();
VerticalFieldManager mainManager;
VerticalFieldManager subManager;
UiApplication ui = UiApplication.getUiApplication();
public xmlparsing()
{
super();
pushScreen(screen);
final Bitmap backgroundBitmap = Bitmap.getBitmapResource("blackbackground.png");
mainManager = new VerticalFieldManager(Manager.NO_VERTICAL_SCROLL | Manager.NO_VERTICAL_SCROLLBAR )
{
public void paint(Graphics graphics)
{
graphics.drawBitmap(0, 0, Display.getWidth(),Display.getHeight(),backgroundBitmap, 0, 0);
super.paint(graphics);
}
};
subManager = new VerticalFieldManager(Manager.VERTICAL_SCROLL | Manager.VERTICAL_SCROLLBAR )
{
protected void sublayout( int maxWidth, int maxHeight )
{
int displayWidth = Display.getWidth();
int displayHeight = Display.getHeight();
super.sublayout( displayWidth, displayHeight);
setExtent( displayWidth, displayHeight);
}
};
screen.add(mainManager);
_list = new ListField()
{
public void paint(Graphics graphics)
{
graphics.setColor((int) mycolor);
super.paint(graphics);
}
};
mycolor = 0x00FFFFFF;
_list.invalidate();
_list.setEmptyString("* Feeds Not Available *", DrawStyle.HCENTER);
_list.setRowHeight(50);
_list.setCallback(this);
mainManager.add(subManager);
listElements.removeAllElements();
_connectionthread = new Connection();
_connectionthread.start();
}
protected boolean navigationClick(int status, int time)
{
try
{
//navigate here to another screen
ui.pushScreen(new ResultScreen());
}
catch(Exception e)
{
System.out.println("Exception:- : navigationClick() "+e.toString());
}
return true;
}
private class Connection extends Thread
{
public Connection()
{
super();
}
public void run() {
Document doc;
StreamConnection conn = null;
InputStream is = null;
try {
conn = (StreamConnection) Connector.open("http://imforchange.org/international-movement-for-change/testing/data.xml"+";deviceside=true");
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
docBuilderFactory.setIgnoringElementContentWhitespace(true);
docBuilderFactory.setCoalescing(true);
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
docBuilder.isValidating();
is = conn.openInputStream();
doc = docBuilder.parse(is);
doc.getDocumentElement().normalize();
NodeList list = doc.getElementsByTagName("eventName");
for (int i = 0; i < list.getLength(); i++)
{
Node textNode = list.item(i).getFirstChild();
listElements.addElement(textNode.getNodeValue());
}
} catch (Exception e) {
System.out.println(e.toString());
} finally {
if (is != null) {
try {
is.close();
} catch (IOException ignored) {
}
}
if (conn != null) {
try {
conn.close();
}
catch (IOException ignored) {
}
}
}
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
_list.setSize(listElements.size());
subManager.add(_list);
screen.invalidate();
}
});
}
}
public void drawListRow(ListField list, Graphics g, int index, int y, int w)
{
String tes = (String)listElements.elementAt(index);
int yPos = 0+y;
g.drawLine(0, yPos, w, yPos);
g.drawText(tes, 5, 15+y, 0, w);
}
public Object get(ListField list, int index)
{
return listElements.elementAt(index);
}
public int indexOfList(ListField list, String prefix, int string)
{
return listElements.indexOf(prefix, string);
}
public int getPreferredWidth(ListField list)
{
return Display.getWidth();
}
public void insert(String toInsert, int index) {
listElements.addElement(toInsert);
}
public void fieldChanged(Field field, int context) {
}
}
ResultScreen.java
package parsepack;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.container.MainScreen;
public class ResultScreen extends MainScreen {
public ResultScreen() {
LabelField resultLabel = new LabelField("Result: ");
add(resultLabel);
}
}
First of all, those messages you're seeing are warnings, not errors. Warnings are not always a problem, but sometimes they are. In this case, I think that at least the first message is a problem, so you'll want to fix it.
1) First, the navigationClick() method. The compiler is telling you that you have an implementation for the method navigationClick() that is never called from any of your code, or by the BlackBerry OS infrastructure. That's probably not what you want. Normally, navigationClick() is a method that you override in a class you write that extends one of the BlackBerry Field classes. For example, a ButtonField subclass. navigationClick() will be called, in that case, when the button is clicked.
But, you placed your navigationClick() method in the main UIApplication subclass. That's not what you want. You need that method to override the navigationClick() method in a field class. I'm not sure which field you want to have call this method when the user clicks. But, for example, you might do something like this:
_list = new ListField()
{
public void paint(Graphics graphics)
{
graphics.setColor((int) mycolor);
super.paint(graphics);
}
protected boolean navigationClick(int status, int time)
{
try
{
//navigate here to another screen
ui.pushScreen(new ResultScreen());
}
catch(Exception e)
{
System.out.println("Exception:- : navigationClick() "+e.toString());
}
return true;
}
};
That would make navigationClick() get called when your list is clicked, and it will get rid of the warning.
2) Regarding the warning about insert(), that's just because you're not using it anywhere. It look like you've added that method to allow code outside the xmlparsing class to be able to insert items into the list. Maybe that's what you want, but you just haven't yet written the other code to use that method. I see you having at least a few choices:
remove or comment out the insert() method until you need it. this will get rid of the warning.
add some more code that does use this method.
ignore the warning, just making sure you understand that the warning is telling you that you have some code that is not (yet) necessary, since it's unused
you can suppress warnings in Java programs, by doing this, or this, in the Eclipse preferences, if you know the warning is not a problem, and you don't want excessive warnings to hide real problems. I normally don't recommend this. Usually, it's better to fix the warning, than to hide it.
I am using finish() to close current activity before quit application in Android.
However, I cannot close screen in blackberry.
public class Main_AllLatestNews extends MainScreen {
public Main_AllLatestNews() {
super(USE_ALL_WIDTH);
}
private boolean Dialog() {
final Bitmap logo = Bitmap.getBitmapResource("icon.png");
d = new Dialog("确定离开?", new String[] { "是", "否" }, new int[] {
Dialog.OK, Dialog.CANCEL }, Dialog.OK,
logo) {
public void setChangeListener(FieldChangeListener listener) {
if (d.getSelectedValue() == Dialog.OK) {
} else {
d.close();
}
};
};
d.show();
return (d.doModal() == Dialog.OK);
}
public boolean onClose(){
if(Dialog()){
System.exit(0);
return true;
}else
return false;
}
}
Here is my Main class
public class Main extends UiApplication {
public static void main(String[] args) {
Main theApp = new Main();
theApp.enterEventDispatcher();
}
public Main() {
pushScreen(new MyScreen());
}
public final class MyScreen extends MainScreen {
private Bitmap logo = Bitmap.getBitmapResource("logo_page.png");
private BitmapField bmfield;
public MyScreen() {
setTitle("Oriental Daily");
bmfield = new BitmapField(logo, Field.FIELD_HCENTER
| BitmapField.FOCUSABLE) {
protected boolean navigationClick(int status, int time) {
Main.this.pushScreen(new Main_AllLatestNews());
Main.this.popScreen(MyScreen.this);
return true;
}
};
}
}
It depends on exactly how you want your close behaviour to work. Also, I can only read English, so I'm not 100% sure what your Dialog says. I'm assuming it's something to do with closing the app (yes or no)?
Anyway, usually, my apps close by overriding the onClose() method in the MainScreen subclass. You don't actually need to listen for the escape key. onClose() will get called normally when the user escapes all the way out of the app, or presses the little button with the blackberry icon, and then selects Close.
public final class MyScreen extends MainScreen {
/** #return true if the user chooses to close the app */
private boolean showDialog() {
Bitmap logo = Bitmap.getBitmapResource("icon.png");
Dialog d = new Dialog("确定离开?",
new String[] { "是", "否" },
new int[] { Dialog.OK, Dialog.CANCEL },
Dialog.OK,
logo);
return (d.doModal() == Dialog.OK);
}
/** Shutdown the app? */
public boolean onClose() {
if (showDialog()) {
System.exit(0);
return true;
} else {
// the user does not want to exit yet
return false;
}
}
}
I want to create an call recorder application in blackberry. While searching in this forum i have got call-recorder-in-blackberry this link. The code given in the below link is fairly understood.
It might be a silly question to you experts but my question is how to us that piece of code. I mean the MyScreen object will work on UIApplication. But how can i make my module start while starting the device, and run in background waiting for the phone call listener to invoke.
I have used this below code, it records the call but only if the call is on loud speaker mode. Now how can i do the same without putting in loud speaker mode.
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import javax.microedition.io.Connector;
import javax.microedition.io.file.FileConnection;
import javax.microedition.media.Manager;
import javax.microedition.media.Player;
import javax.microedition.media.control.RecordControl;
import net.rim.blackberry.api.phone.Phone;
import net.rim.blackberry.api.phone.PhoneCall;
import net.rim.blackberry.api.phone.PhoneListener;
import net.rim.device.api.system.Application;
import net.rim.device.api.ui.component.Dialog;
public class CatchCall extends Application implements PhoneListener {
Player player;
RecordControl recorder;
private ByteArrayOutputStream output;
byte[] data;
boolean yes = false;
int st;
public CatchCall() {
Phone.addPhoneListener(this);
}
public static void main(String[] args) {
new CatchCall().enterEventDispatcher();
}
public void callAdded(int callId) {
}
public void callAnswered(int callId) {
}
public void callConferenceCallEstablished(int callId) {
}
public void callConnected(int callId) {
// TODO Auto-generated method s
PhoneCall phoneCall = Phone.getCall(callId);
if (phoneCall != null) {
if (yes)
initPlay();
}
}
public void callDirectConnectConnected(int callId) {
}
public void callDirectConnectDisconnected(int callId) {
}
public void callDisconnected(int callId) {
// TODO Auto-generated method stub
if (yes) {
try {
recorder.commit();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
player.close();
data = output.toByteArray();
saveRecordedFile(data);
}
}
public void callEndedByUser(int callId) {
}
public void callFailed(int callId, int reason) {
}
public void callHeld(int callId) {
}
public void callIncoming(int callId) {
Dialog.ask(Dialog.D_YES_NO, "Are u sure to record this call");
}
public void callInitiated(int callid) {
PhoneCall phoneCall = Phone.getCall(callid);
if (phoneCall != null) {
st = Dialog.ask(Dialog.D_YES_NO, "Are u sure to record this call");
if (st == Dialog.YES)
yes = true;
else
yes = false;
}
}
public void callRemoved(int callId) {
}
public void callResumed(int callId) {
}
public void callWaiting(int callid) {
}
public void conferenceCallDisconnected(int callId) {
}
private void initPlay() {
try {
player = Manager.createPlayer("capture://audio");
player.realize();
recorder = (RecordControl) player.getControl("RecordControl");
output = new ByteArrayOutputStream();
recorder.setRecordStream(output);
recorder.startRecord();
player.start();
} catch (Exception e) {
Dialog.alert(e + "");
}
}
public static boolean saveRecordedFile(byte[] data) {
try {
String filePath1 = System.getProperty("fileconn.dir.music");
String fileName = "Call Recorder(";
boolean existed = true;
for (int i = 0; i < Integer.MAX_VALUE; i++) {
try {
FileConnection fc = (FileConnection) Connector.open(filePath1 + fileName + i + ").amr");
if (!fc.exists()) {
existed = false;
}
fc.close();
} catch (IOException e) {
Dialog.alert("unable to save");
return existed;
}
if (!existed) {
fileName += i + ").amr";
filePath1 += fileName;
break;
}
}
System.out.println(filePath1);
System.out.println("");
FileConnection fconn = (FileConnection) javax.microedition.io.Connector .open(filePath1, javax.microedition.io.Connector.READ_WRITE);
if (fconn.exists())
fconn.delete();
fconn.create();
OutputStream outputStream = fconn.openOutputStream();
outputStream.write(data);
outputStream.close();
fconn.close();
return true;
} catch (Exception e) {
}
return false;
}
}
Actually direct call recording not possible with blackberry. AFAIK that posted code is call recording when call on speakerphone. That means If mobile have the loud speaker, then put a call to loud speaker and record that voice. And look at this discussion, Call recorder in Blackberry.
It's not possible to record the audio of a phone call (other than with a loud speakerphone) as you are trying to do. This is intentional. You would need another approach off the device to do this. However, I can answer your other questions:
To make your application autostart, you can follow these steps: http://supportforums.blackberry.com/t5/Java-Development/Configure-an-application-to-start-automatically-when-the/ta-p/444748
Also, as this application above doesn't extend from UiApplication, you should check the "run as a system module" box as well, when you follow the directions above. That way it won't appear on the ribbon or as an icon in the list of applications.