newbie to android !
basically i trying to make a proprietary app for my product which runs on BT SPP Protocol !
so i decided use https://github.com/akexorcist/BluetoothSPPLibrary a class which handles bt service for outgoing / incoming data from bt device
Sending data is ok !
but when i trying receiving data simply cannot call / receive data inside activity class
here is my snippets of my code !
BTSpp.java
public interface OnDataReceivedListener {
public void onDataReceived(byte[] data, String message); /// for sending back data to the activity
}
...
//this is not executing cause log is not running when receives data
public void setOnDataReceivedListener (OnDataReceivedListener listener) {
Log.d("TAG", "setOnDataReceivedListener() returned: " );
if(null == mDataReceivedListener)
mDataReceivedListener = listener;
}
...
//Here is the snippet for reading data from bt service and
//it is showing log whenever i receives data from spp device
case BluetoothState.MESSAGE_READ:
byte[] readBuf = (byte[]) msg.obj;
String readMessage = new String(readBuf);
if(readBuf != null && readBuf.length > 0) {
if(mDataReceivedListener != null){
Log.d("TAG", "handleMessage() returned: "+mDataReceivedListener ); //executes
mDataReceivedListener.onDataReceived(readBuf, readMessage);}
}
break;
and in my activity window onCreate method
not at all executing this method
MainActivity.java
BluetoothSPP bt=new BluetoothSPP(this); //initialized
{...}
bt.setOnDataReceivedListener(new BluetoothSPP.OnDataReceivedListener() {
#Override
public void onDataReceived(byte[] data, String message) {
Log.d(TAG, "onDataReceived() returned: " );
Log.i(TAG, "onDataReceived: "+message);
Log.i(TAG, "onDataReceived: "+data);
processIncomingdata(message);
}
});
maybe this function doesn't call from service class . i literally can't find any clue !
can anyone give me some suggestion about this !
Thank you in advance !
Related
Good Afternoon, I am still very new to ESP32/android studio coding so I apologize for my beginner terminology. I am currently coding a project where I can control multiple stepper motors at the same exact time from the press of a button on my android application and the motors are connected to certain ESP32 GPIO pins, I am using the okhttp3 client as well. My code is below.
public class Connectivity {
public static String geturl (String url_esp32){
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(url_esp32)
.build();
try
{
Response response = client.newCall(request).execute();
return response.body().string();
} catch(IOException error) {
return error.toString();
}
}
}
above is my connectivity page for connecting to the requests for the esp32.
PBNow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// request information from esp32
// PB sandwich now, disable jelly motor
request_to_url("STEP");
request_to_url("DIR");
request_to_url("STEP2");
request_to_url("DIR2");
request_to_url("STEP4");
request_to_url("DIR4");
request_to_url("ledRED");
request_to_url("ledGREEN");
}
});
above is how im calling the requests for the esp32.
The problem I am having is that when these request_to_url lines are going line by line but I want them to all run at the exact same time. Is this possible.
Below are also my request_to_url function and request_data function.
public void request_to_url (String command) {
ConnectivityManager connMgr = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if(networkInfo != null && networkInfo.isConnected()) {
new request_data().execute("http://" + ip_address + "/" + command);
}else {
Toast.makeText(activity_2.this, "Not connected ", Toast.LENGTH_LONG).show();
}
}
private class request_data extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... url)
{
return Connectivity.geturl(url[0]);
}
#Override
protected void onPostExecute(String result_data) {
if(result_data != null)
{
}else{
Toast.makeText(activity_2.this, "Null data", Toast.LENGTH_LONG).show();
}
}
}
I apologize if the code is very sloppy, I am still very new. Thank you very much.
Besides the messy code in your app required to fire off multiple requests, the ESP32 has very limited network stack and resources, and cannot handle many simultaneous connections. If your app opens too many HTTP connections to the ESP32 at once, some will likely fail or have to wait for others to close.
Instead, you can do it all in a single request and tell the ESP32 to do multiple things at once. Pass the requests as parameters in the URL, like so:
http://ip-address/cmd?step=1&dir=0&ledGREEN=0&ledRED=1
Just have the handler on the ESP32 for the path /cmd look for the presence of each possible parameter and respond to it appropriately.
first post here. I've tried to look for a question I have but no luck so I figure I ask it myself.
I am working on 2 programs. An Android app in Java and a C# Windows Form App on windows. They are both simply scorekeeping calculators to keep track of the score of 2 players.
The goal of the 2 programs is to use a Bluetooth connection to send data back and forth between each other so that they are "synced". Android app is a client, c# app is a server (32feet library).
Using the Bluetooth Chat example on Android and some code i put together in VS, I managed to get the 2 programs to connect and send and receive data to each other, great!
But now my main goal is that I need to find out a way to take the incoming data coming from the Android app and change the appropriate labels/text on the windows app.
So for example:
on the Windows App, there are 2 Labels: one for Player1, one for Player2 that both say "10".
On the Android App, I have 2 buttons that separately subtract from either Player1 or Player2's score.
On the android app, if I touch the button that subtracts(-) 1 from Player1 it would be 9. I now want that change to apply to Player1's score label on the windows app, where it would also show 9.
I then want the same thing for Player2's score.
This is the best I can describe my goal, and I would like to know if it's possible, and if so, be pointed in the right direction.
Here is some provided code for what I have so far:
C# windows form app:
private void button1_Click(object sender, EventArgs e)
{
if (serverStarted == true)
{
updateUI("Server already started");
return;
}
if (radioButton1.Checked)
{
connectAsClient();
}
else
{
connectAsServer();
}
}
private void connectAsServer()
{
Thread bluetoothServerThread = new Thread(new ThreadStart(ServerConnectThread)); //creates new thread and runs "ServerConnectThread"
bluetoothServerThread.Start();
}
private void connectAsClient()
{
throw new NotImplementedException();
}
Guid mUUID = new Guid("fa87c0d0-afac-11de-8a39-0800200c9a66");
bool serverStarted = false;
public void ServerConnectThread()
{
serverStarted = true;
updateUI("Server started, waiting for client");
BluetoothListener blueListener = new BluetoothListener(mUUID);
blueListener.Start();
BluetoothClient conn = blueListener.AcceptBluetoothClient();
updateUI("Client has connected");
Stream mStream = conn.GetStream();
while (true)
{
try
{
//handle server connection
byte[] received = new byte[1024];
mStream.Read(received, 0, received.Length);
updateUI("Received: " + Encoding.ASCII.GetString(received));
byte[] sent = Encoding.ASCII.GetBytes("hello world");
mStream.Write(sent, 0, sent.Length);
}
catch (IOException exception)
{
updateUI("Client disconnected");
}
}
}
private void updateUI(string message)
{
Func<int> del = delegate ()
{
textBox1.AppendText(message + Environment.NewLine);
return 0;
};
Invoke(del);
}
}
Android App (snippet from the Bluetooth Chat example - i think this is the only relevant part):
/**
* Sends a message.
*
* #param message A string of text to send.
*/
private void sendMessage(String message) {
// Check that we're actually connected before trying anything
if (mChatService.getState() != BluetoothChatService.STATE_CONNECTED) {
Toast.makeText(getActivity(), R.string.not_connected, Toast.LENGTH_SHORT).show();
return;
}
// Check that there's actually something to send
if (message.length() > 0) {
// Get the message bytes and tell the BluetoothChatService to write
byte[] send = message.getBytes();
mChatService.write(send);
// Reset out string buffer to zero and clear the edit text field
mOutStringBuffer.setLength(0);
mOutEditText.setText(mOutStringBuffer);
}
}
You will want to have to add the clients to alist of streams for reference and also store the scores of each client on a list and then send the data coming from each client to the rest of the clients
so from the server youd have basically something like this
List<Stream> clients=new List<Stream>();
List<String> client_scores=new List<String>();
public void ServerConnectThread()
{
serverStarted = true;
updateUI("Server started, waiting for client");
BluetoothListener blueListener = new BluetoothListener(mUUID);
blueListener.Start();
BluetoothClient conn = blueListener.AcceptBluetoothClient();
updateUI("Client has connected");
Stream mStream = conn.GetStream();
clients.add(mStream);
client_scores.add(new Random().Next()+"");
int index_cnt = clients.IndexOf(mStream);
while (true)
{
try
{
//handle server connection
byte[] received = new byte[1024];
mStream.Read(received, 0, received.Length);
updateUI("Received: " + Encoding.ASCII.GetString(received));
client_scores[client_scores.FindIndex(ind=>ind.Equals(index_cnt))] = Encoding.ASCII.GetString(received);
byte[] sent = Encoding.ASCII.GetBytes("hello world");
mStream.Write(sent, 0, sent.Length);
foreach(Stream str in clients)
{
byte[] my_score = Encoding.ASCII.GetBytes(clients.ToArray()[index_cnt]+"");
str.Write(my_score, 0, my_score.Length);
}
}
catch (IOException exception)
{
updateUI("Client disconnected");
}
}
}
You can then serialize the data being sent in some sort of json so as to send multiple fields of data comfortably for example :
{
"data type": "score",
"source_id": "client_unique_id",
"data": "200"
}
On your displaying side,just get the values of (in our example case source_id and data) and display on a label
Iam using Google Retriver API for automatic sms verification, now everthings works fine.
Iam receiving sms message from Broadcast receiver class.
This is my sms message..
<#> Waahan: Your verification code is:1453 jtN03jdhD6p
I want to extract only the otp from the message..
SMSBroadcastReceiver.java
public class SMSBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (SmsRetriever.SMS_RETRIEVED_ACTION.equals(intent.getAction())) {
Bundle extras = intent.getExtras();
Status status = (Status) extras.get(SmsRetriever.EXTRA_STATUS);
switch(status.getStatusCode())
{
case CommonStatusCodes.SUCCESS:
String message = (String) extras.get(SmsRetriever.EXTRA_SMS_MESSAGE);
break;
case CommonStatusCodes.TIMEOUT:
break;
}
}
}
}
I have searched, but every one is using telephony.. iam using retrievel API..
Thanks in advance..
case CommonStatusCodes.SUCCESS:
String message = (String) extras.get(SmsRetriever.EXTRA_SMS_MESSAGE);
String OTP = message.substring(message.lastIndexOf(":") + 1);
possible using SubString(Start,End) Function
I'm trying to implement automating player sign in to Google Play games in my Android app. Firstly, as mentioned here, I try to sign in silently:
#Override
protected void onResume() {
super.onResume();
signInSilently();
}
private void signInSilently() {
mGoogleSignInClient.silentSignIn().addOnCompleteListener(this, task -> {
if (task.isSuccessful())
//everything ok
else {
final ApiException exception = (ApiException) task.getException();
if (BuildConfig.DEBUG)
Log.d(TAG, "Silent Sign In failure: ", exception);
if (exception.getStatusCode() == CommonStatusCodes.SIGN_IN_REQUIRED)
startSignInIntent();
}
});
Every time I got an exception with code 4 (CommonStatusCodes.SIGN_IN_REQUIRED). So in this case I try to sign in with ui:
private void startSignInIntent() {
startActivityForResult(mGoogleSignInClient.getSignInIntent(), RC_SIGN_IN);
}
#Override
protected void onActivityResult(int request, int response, Intent data) {
super.onActivityResult(request, response, data);
if (request == RC_SIGN_IN) {
final GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
if (result.isSuccess()) {
// everything is ok, get account from result
} else if (result.getStatus().hasResolution()) {
resolveManually(result.getStatus());
} else {
String message = result.getStatus().getStatusMessage();
if (BuildConfig.DEBUG)
Log.d(TAG, "status code" + result.getStatus().getStatusCode());
if (message == null || message.isEmpty()) {
message = "other error";
}
new AlertDialog.Builder(this).setMessage(message)
.setNeutralButton(android.R.string.ok, null).show();
}
}
}
And here everytime I get message with other error! The status code is again 4 (CommonStatusCodes.SIGN_IN_REQUIRED). How can I get this code when I try to sign in using intent? So, my app are in infinite loop because onResume is called everytime my activity loads after receiving a result, and everytime the status code is CommonStatusCodes.SIGN_IN_REQUIRED. So, where is the problem?
In Google samples there is no information how can I handle automatic sign in, only manual with sign in buttons. But google recommends to use automating sign in. Please help anybody to understand what is wrong here.
You must not start the login screen from your onResume method. It is a silent login which works if the user wants it (by tapping a button). That's why the examples show it only this way.
There was wrong OAuth 2.0 client ID for the debug version of my app! Don't know why there is SIGN_IN_REQUIRED status code in this situation, it is really confusing!
So I'm building a signup procedure that needs the user to verify their phone number by receiving a code by sms. I'm using Parse as the backend system and I'm using Twilio service which comes included in Parse to take care of the sms function. I have been successful in sending the verification code to user's number.
This is my parse cloud code:
var client = require('twilio')('ACb3....', '2b3....');
//Send an SMS text message
Parse.Cloud.define("sendVerificationCode", function(request, response) {
var verificationCode = Math.floor(Math.random()*999999);
client.sendSms({
From: "+61437877758",
To: request.params.phoneNumber,
Body: "Your verification code is " + verificationCode + "."
}, function(err, responseData) {
if (err) {
response.error(err);
} else {
response.success("Success");
}
});
});
This is the code from the app:
HashMap<String, Object> params = new HashMap<String, Object>();
params.put("phoneNumber", userNumber);
ParseCloud.callFunctionInBackground("sendVerificationCode", params, new FunctionCallback<String>() {
public void done(String result, ParseException e) {
if (e == null) {
Log.d("Parse", result);
Intent i = new Intent(SignupActivity.this, PhoneVerificationActivity.class);
startActivity(i);
} else {
Toast.makeText(SignupActivity.this, "there was a problem with connection", Toast.LENGTH_LONG).show();
}
}
});
Now I would like to know how can I send that verification code back to my android app from Parse Cloud after success, so tat I can check the verification code against the code user puts in the EditText
if (err) {
response.error(err);
} else {
*//So the code for sending the verification code back goes here:*
response.success("Success");
}
Do I need to use Json and Rest API?, how can I call and grab this verification code from the app?.
I would really appreciate your help. Thanks.
One way would be to return it in response.success...
response.success({ status: "success", verificationCode: ... });
Another way, a better way, is to not trust the client with this. Store a record of it on an object on the server... When the user enters the validation code, call back into another function to check if it is valid. An example of this type of system can be seen in this old out-dated GitHub login example: https://github.com/ParsePlatform/CloudCodeOAuthGitHubTutorial/blob/master/cloud/main.js#L116