I have an android app that automatically turns on device Bluetooth and connects to a paired device. The device sends data which is updated constantly. If the user presses an enable device button, which is used to initialize the device and begin the operation, before the connection is established, all the previous data is reset.
This is an Android project I was given from an outsourced company so I didn't write the code originally. I have
private void initialize() {
// initializing and launching the Equipment layer api
try {
Utility.writeLogs(this, getString(R.string.info), TAG,
"Initializing EState Manager");
EStateManager.getInstance().launch(getResources());
getInfo();
requestConfiguration();
findViewById(R.id.btn_enable).setVisibility(View.VISIBLE);
handleConnectionDialog();
} catch (Exception e) {
e.printStackTrace();
Utility.writeLogs(this, getString(R.string.error), TAG,
"EStateManger initialization failed");
Utility.writeLogs(this, getString(R.string.error), TAG, e);
}
}
private void handleConnectionDialog() {
ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();
exec.scheduleAtFixedRate(() -> {
// do stuff
if (!EStateManager.getInstance().isDataReceived()) {
if (!new PrefUtil(this).isConnectionDialogEnabled()) {
runOnUiThread(() ->
onShowPopup(Utility.POPUP_MAP.get(14)));
}
} else {
if (!buttonPressed) {
findViewById(R.id.btn_enable).setVisibility(View.VISIBLE);
}
EStateManager.getInstance().setDataReceived(false);
}
}, 5, 5, TimeUnit.SECONDS);
}
I would like to disable the button until Bluetooth is successfully connected to ensure that saved parameters are not changed.
Configure a broadcast receiver to listen for ACTION_STATE_CHANGED
Then check the extra EXTRA_CONNECTION_STATE and enable the button if it is STATE_CONNECTED
Also in the ACTION_STATE_CHANGED receiver, check for STATE_DISCONNECTED, and disabled the button.
Response to comment:
findViewById should be allowed in the receiver if it is defined in the MainActivity.java like so
public class HomeActivity extends Activity {
...
private final BroadcastReceiver mRadioReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
button = (Button) findViewById(R.id.button1);
String action = intent.getAction();
switch (action) {
case ACTION__DEVICE_CONNECTED:
button.setEnabled(true);
break;
case ACTION_DEVICE_DISCONNECTED:
button.setEnabled(false);
break;
}
}
};
Related
I create a new thread, and y need to interrupt, I use the thread.interrup(), but when I throw request thread interrupt is not working on ios, works fine on simulator or in Android device.
I Attach code to try it.
My temporal solution is use a Flag to break while, but I want to use the InterruptedException
package com.kandy.forms;
import com.codename1.io.Log;
import com.codename1.ui.Button;
import com.codename1.ui.Dialog;
import com.codename1.ui.Display;
import com.codename1.ui.Form;
import com.codename1.ui.layouts.BoxLayout;
public class Interrup extends Form {
private Form previous;
private Thread thread = null;
public Interrup() {
setLayout(new BoxLayout(BoxLayout.Y_AXIS));
Button newThread = new Button ("Start Thread");
newThread.addActionListener((e) -> {
thread = new Thread(new Runnable() {
#Override
public void run() {
while (true) {
try {
Thread.sleep(1000);
Log.p("thread working");
} catch (InterruptedException ie) {
Dialog.show("Message", "Interruption received", "Ok", null);
break;
}
}
}
});
//thread start
thread.start();
});
Button interruptTreath = new Button ("Interrupt");
interruptTreath.addActionListener((e) -> {
Log.p("Interrupt Sended");
thread.interrupt();
});
add(newThread);
add(interruptTreath);
}
public void show() {
previous = Display.getInstance().getCurrent();
super.show();
}
public void goBack(){
previous.showBack();
}
}
This isn't supported on iOS. Neither is stop etc. as those are pretty hard to get working consistently across platforms. This is especially true for iOS and the thread implementation in the JavaScript port.
I am using the MapContainer(cn1lib). so in android devices low relsolution the zoom works fine. But in android devices high resolution the zoom not works fine. The zoom in stay far. i attach a screen with the to max zoom in, it is a bug or i'm wrong?
SCREENSHOT
GUI-DESIGN
public class StateMachine extends StateMachineBase {
MapContainer mapContainer;
public StateMachine(String resFile) {
super(resFile);
// do not modify, write code in initVars and initialize class members there,
// the constructor might be invoked too late due to race conditions that might occur
}
/**
* this method should be used to initialize variables instead of the
* constructor/class scope to avoid race conditions
*/
protected void initVars(Resources res) {
}
#Override
protected void beforeShow(Form f) {
try {
this.mapContainer.setShowMyLocation(true);
this.mapContainer.zoom(new Coord(20.640086, -103.432207), 17);
this.mapContainer.setCameraPosition(new Coord(20.640086, -103.432207));
this.mapContainer.addMarker(
EncodedImage.createFromImage(fetchResourceFile().getImage("pin.png"), false),
new Coord(20.640086, -103.432207),
"Hi marker", "Optional long description",
new ActionListener() {
public void actionPerformed(ActionEvent evt) {
Dialog.show("Marker Clicked!", "You clicked the marker", "OK", null);
}
}
);
this.mapContainer.addPointerDraggedListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
mapContainer.clearMapLayers();
mapContainer.addMarker(EncodedImage.createFromImage(fetchResourceFile().getImage("pin.png"), false), mapContainer.getCameraPosition(), "Hi marker", "Optional long description", new ActionListener() {
public void actionPerformed(ActionEvent evt) {
Dialog.show("Marker Clicked!", "You clicked the marker", "OK", null);
}
});
}
});
} catch (Exception ex) {
ex.printStackTrace();
}
super.beforeShow(f); //To change body of generated methods, choose Tools | Templates.
}
#Override
protected Component createComponentInstance(String componentType, Class cls) {
if (cls == MapComponent.class) {
this.mapContainer = new MapContainer();
return this.mapContainer;
}
return super.createComponentInstance(componentType, cls); //To change body of generated methods, choose Tools | Templates.
}
}
That is a MapComponent not a native map, so it uses the old open street maps support and relatively simple map rendering even on the device. We have support for native google maps which isn't exposed in the GUI builder but you can add it thru code.
This will embed the actual native GUI into place which will both look and feel better on the device although it will look the same on the simulator.
IDE: NetBeans
Desktop OS Windows 10
Simulator Android/iOS
Device Android/iOS
I am able to get authentication to work with connection request. I am having to get header information and then in another part of the app, send that same information back to the cgi-bin. Below is my code and I commented on the parts where I believe I need to do something with a header and or cookie. I'm very new to this and It's been difficult finding even a basic header/cookie tutorial.
/**
* Your application code goes here<br>
* This file was generated by Codename One for the purpose
* of building native mobile applications using Java.
*/
package userclasses;
import com.codename1.io.ConnectionRequest;
import com.codename1.io.Cookie;
import com.codename1.io.NetworkEvent;
import com.codename1.io.NetworkManager;
import com.codename1.io.Storage;
import com.codename1.notifications.LocalNotification;
import generated.StateMachineBase;
import com.codename1.ui.*;
import com.codename1.ui.events.*;
import com.codename1.ui.util.Resources;
import java.util.Timer;
import java.util.TimerTask;
//import org.apache.commons.httpclient.UsernamePasswordCredentials;
//import org.apache.commons.httpclient.auth.AuthScope;
/**
*
* #John Barrett
*/
public class StateMachine extends StateMachineBase {
public StateMachine(String resFile) {
super(resFile);
// do not modify, write code in initVars and initialize class members there,
// the constructor might be invoked too late due to race conditions that might occur
}
/**
* this method should be used to initialize variables instead of
* the constructor/class scope to avoid race conditions
*/
protected void initVars(Resources res) {
}
boolean stop = false;
boolean notify = false;
String OnOff;
#Override // Starts monitor action.
protected void onMain_ButtonAction(Component c, ActionEvent event){
// starts a timer to repeat monitor every minute.
Timer timer = new Timer();
String text = (String) Storage.getInstance().readObject("SavedData");
timer.schedule( new TimerTask(){
#Override
public void run(){
if (stop == true){
cancel();//Monitor ends
}
//Starts a connection with the URL to monitor
ConnectionRequest r = new ConnectionRequest();
r.setUrl("http://vault.infinitevault.com/cgi-bin/absentmedia?customer=" + text.toLowerCase().trim());
r.setPost(true);
// Post Header/Cookie information to URL for access NEED HELP WITH THIS!
r.setHttpMethod("HEAD");
r.setContentType("text/xml");
r.setCookiesEnabled(true);
findCodeLabel(c).setText("Monitoring: " + text.toUpperCase());
r.addResponseListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent ev){
// Monitor starts
try{
NetworkEvent event = (NetworkEvent) ev;
// Need to post header/cookie information here? HELP!
Cookie.isAutoStored();
byte[] data= (byte[]) event.getMetaData();
String decodedData = new String(data,"UTF-8");
boolean none;
none = decodedData.endsWith("NONE\n");
if (!none){
System.out.println(decodedData);
findCodeTextArea(c).setText(decodedData);
LocalNotification n = new LocalNotification();
n.setId("OSStorage");
n.setAlertBody(decodedData);
n.setAlertTitle("Absent Media");
Display.getInstance().scheduleLocalNotification(
n,
System.currentTimeMillis() + 10 * 1000, // fire date/time
LocalNotification.REPEAT_MINUTE // Whether to repeat and what frequency
);
if (notify != true){
Display.getInstance().vibrate(5000);
}
Storage.getInstance().writeObject("MonitorData", decodedData);
}
else{
System.out.println("None");
findCodeTextArea(c).setText("System is Good");
}
}
catch (Exception ex){
ex.printStackTrace();
}
}
});
NetworkManager.getInstance().addToQueue(r);
}
}, 0, 60*1000);
}
#Override // Stops the monitoring action.
protected void onMain_StopButtonAction(Component c, ActionEvent event) {
super.onMain_StopButtonAction(c, event);//To change body of generated methods, choose Tools | Templates.
stop = true;
findCodeLabel(c).setText("Monitor Stopped");
findCodeTextArea(c).setText("");
findCodeTextArea(c).setHint("System information will show here");
Storage.getInstance().deleteStorageFile("MonitorData");
}
#Override // Saves the settings to storage.
protected void onSettings_SetSaveAction(Component c, ActionEvent event) {
String Station = findSetStation(c).getText();
Storage.getInstance().writeObject("SavedData", Station);
String LoadStation = (String) Storage.getInstance().readObject("SavedData");
findStationLabel(c).setText("Saved Station is " + LoadStation);
}
#Override // Sets what is saved to appear when in settings.
protected void beforeSettings(Form f) {
String LoadStation = (String) Storage.getInstance().readObject("SavedData");
findStationLabel(f).setText("Saved Station is " + LoadStation);
findSetStation(f).setText(LoadStation);
String CurrentNotify = (String) Storage.getInstance().readObject("OnOff");
findSetNotifyLabel(f).setText("Vibration is " + CurrentNotify);
}
#Override // Sets what is saved to appear when in monitor screen.
protected void beforeMain(Form f) {
String LoadStation = (String) Storage.getInstance().readObject("SavedData");
findCodeLabel(f).setText(LoadStation);
if (findCodeTextArea(f) != null){
String foundData = (String) Storage.getInstance().readObject("MonitorData");
findCodeTextArea(f).setText(foundData);
}
}
#Override // Sets notification for turning vibration on.
protected void onSettings_SetNotifyOnAction(Component c, ActionEvent event) {
notify = false;
OnOff = "ON";
Storage.getInstance().writeObject("NotifyOn", notify);
Storage.getInstance().writeObject("OnOff", OnOff);
findSetNotifyLabel(c).setText("Vibration is " + OnOff);
}
#Override // Sets notification for turning vibration off.
protected void onSettings_SetNotifyOffAction(Component c, ActionEvent event) {
notify = true;
OnOff = "OFF";
Storage.getInstance().writeObject("NotifyOn", notify);
Storage.getInstance().writeObject("OnOff", OnOff);
findSetNotifyLabel(c).setText("Vibration is " + OnOff);
}
#Override // Sets message for monitoring or not.
protected void beforeStartPage(Form f) {
Storage.getInstance().deleteStorageFile("MonitorData");
String LoadStation = (String) Storage.getInstance().readObject("SavedData");
}
#Override // Login button pressed after entering username and password.
protected void onLogin_LoginAction(Component c, ActionEvent event) {
// Gets the username and password entered.
String userName = findUsename().getText();
String passWord = findPassword().getText();
// Establishes a conneciton to authentication.
ConnectionRequest req=new ConnectionRequest();
req.setPost(false);
req.setUrl("http://authentication.infinitevault.com/validate.php");
req.addArgument("username",userName);
req.addArgument("password",passWord);
req.addArgument("grant_type","client_credentials");
// To get the Header/Cookie information.
req.getHttpMethod();
req.setCookiesEnabled(true);
Cookie.setAutoStored(true);
Cookie.isAutoStored();
// Sends message to user that system is verifying.
findDenied(c).setText("Verifying");
NetworkManager.getInstance().addToQueueAndWait(req);
if (req.getResponseData() != null) {
String token = new String(req.getResponseData());
token = token.substring(token.indexOf('=') + 1);
System.out.println(token);
// Checks credentials if response is denied, goes back,
// If response is authenticated goes to main monitor form.
if (token.endsWith("denied")){
/*try {
Thread.sleep(2000); //1000 milliseconds is one second.
} catch(InterruptedException e) {
Thread.currentThread().interrupt();
}*/
back();
}
else {
showForm("Main",null);
}
}
}
}//end of app
Just override the connection request method cookieReceived(Cookie c) and handle the logic of each cookie there.
I use C#, Winforms.
From MainForm, I instantiate MailSendForm dialog form which sends an email, the send method is in it's OnLoad method, there is progress bar on this form that shows the sending progress.
The problem is that the form doesn't show up, untill the send finishes and the message box that shows "Success", is closed.
Is there a way to show the sending form before the send begins?
//--- MainForm
private void SendOrder(...)
{
var sm = new MailSendForm(...);
sm.ShowDialog();
}
//--- MailSendForm
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
SendEmail();
}
private void SendEmail()
{
....
// Send mail.
var success = mailman.SendEmail(email);
if (success)
{
MessageBox.Show("email sent successfully");
}
else
{
MessageBox.Show(mailman.LastErrorText);
}
}
public void mailman_OnPercentDone(object source, Chilkat.PercentDoneEventArgs args)
{
progressBar.EditValue = args.PercentDone;
if (_cancelled)
{
args.Abort = true;
}
Application.DoEvents();
}
the Shown event solved my problem.
Thank you EirĂkur Fannar Torfason.
I'm trying to develop socket based application on wp7 (client) and WPF (server) and I have issue that I don't understand.
I've written "Server" class which should handle connecting with client and recieving strings.
The problem is that server recieving just first string sent by client and then the connection is breaking, I have to reset my client app (only client). I'm assuming it's server side problem because I'm rewriting server application using Async calls. Before that client works well. My server side code:
public class StateObject
{
public byte[] Buffer { get; set; }
public Socket WorkSocket { get; set; }
}
public class MessageRecievedEventArgs : EventArgs
{
public string Message { get; set; }
}
public class Server
{
ManualResetEvent _done;
TcpListener _listener;
public event EventHandler<MessageRecievedEventArgs> OnMessageRecieved;
public Server()
{
_done = new ManualResetEvent(false);
_listener = new TcpListener(IPAddress.Any, 4124);
}
public void Start()
{
Thread th = new Thread(StartListening);
th.IsBackground = true;
th.Start();
}
private void StartListening()
{
_listener.Start();
while (true)
{
_done.Reset();
_listener.BeginAcceptTcpClient(new AsyncCallback(OnConnected), _listener);
_done.WaitOne();
}
}
private void OnConnected(IAsyncResult result)
{
TcpListener listener = result.AsyncState as TcpListener;
Socket socket = listener.EndAcceptSocket(result);
byte[] buffer = new byte[256];
StateObject state = new StateObject { Buffer = buffer, WorkSocket = socket };
socket.BeginReceive(state.Buffer, 0, state.Buffer.Length, SocketFlags.None, new AsyncCallback(OnRead), state);
}
private void OnRead(IAsyncResult result)
{
var state = (StateObject)result.AsyncState;
int buffNum = state.WorkSocket.EndReceive(result);
string message = Encoding.UTF8.GetString(state.Buffer, 0, buffNum);
if (OnMessageRecieved != null)
{
MessageRecievedEventArgs args = new MessageRecievedEventArgs();
args.Message = message;
OnMessageRecieved(this, args);
}
_done.Set();
}
}
Client:
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
try
{
base.OnNavigatedTo(e);
_socketEventArgs = new SocketAsyncEventArgs() { RemoteEndPoint = App.Connection.RemoteEndPoint };
Send("{ECHO}");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void Send(string key)
{
var bytes = Encoding.UTF8.GetBytes(key + "$");
_socketEventArgs.SetBuffer(bytes, 0, bytes.Count());
if (Socket.Connected)
Socket.SendAsync(_socketEventArgs);
else
MessageBox.Show("Application is not connected. Please reset connection (press 'back' key and 'connect' button). It may be needed to restart server application");
}
The "{ECHO}" message is sent by client and recieved by server - each next is sent, but not recieved. I assuming that I don't understand sockets async calls mechanism... can someone enlighten me? :)
It seems like you are only reading once. Probably you want to call read repeatedly to deplete the entire stream.