Dont get angry on me please. I have two questions, I think on very similar theme, so I decided to merge them into one. I have my app on android that is using sensors to do some calculations. I am storing there sesults in my database. What i want to do is to send my data from my phone to my desktop app also with a database (on button click).
To be more precise, here is an example: My light sensor reads current light intensity. Lets say it is 1000lux. Now, when I click my button "Send" in my android app, it will send this value to my desktop apps database. That desktop app will read that value and will show it to user.
Is it possible via WIFI? or better via web, so i will not be limited with distance?
How can android manage this kind of communication?
And my second question is, if controlling media player on my PC is similar to what i said.
EDIT:
I did some research and found one Socket tutorial. I tried it exactly like it is there. So i have this in my android app:
public class Client extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_client);
Client myCli = new Client();
try {
myCli.run();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_client, menu);
return true;
}
public void run() throws Exception {
Socket mySkt = new Socket("192.168.1.6", 9999);
PrintStream myPS = new PrintStream(mySkt.getOutputStream());
myPS.println("Hello server");
BufferedReader myBR = new BufferedReader
(new InputStreamReader(mySkt.getInputStream()));
}
}
and this in netBeans:
//Author: WarLordTech
//Website: http://www.youtube.com/user/WarLordTech
import java.io.*;
import java.net.*;
public class Server {
public static void main(String[] args) throws Exception{
Server myServ = new Server();
myServ.run();
}
public void run() throws Exception{
ServerSocket mySS = new ServerSocket(9999);
Socket SS_accept = mySS.accept();
BufferedReader SS_BF= new BufferedReader(new InputStreamReader
(SS_accept.getInputStream()));
String temp = SS_BF.readLine();
System.out.println(temp);
if (temp!=null) {
PrintStream SSPS = new PrintStream(SS_accept.getOutputStream());
SSPS.println("Got something");
}
}
}
It still isnt workiong. Do I have to set up my network somehow?
You could do it using TCP Sockets. Many languages have implementations for Socket programming so you would "need" to program your desktop app in Java (of course that is always possible!).
Socket Tutorial in Java
This would work over the net and local wifi. You could use other methods for local wifi such as a UDP connection. You'd need to setup a TCP server and make sure you had access etc.
There may be other ways to do this but it's not such a trivial task to do!
Related
I have trouble with connecting to a local web interface (192.168.10.13:3671) that are connected to my KNX network from the emulator/phone in Android Studio.
I've tried to connect to the same web interface with a already developed app called KNXwizard and that works, but I see in the code that that app uses AsyncTask.
Always getting this error: Error creating KNXnet/IP tunneling link: tuwien.auto.calimero.KNXException: connecting from /192.168.163.198:3671 to /192.168.10.13:3671: socket failed: EPERM (Operation not permitted)
I've checked this posts
Socket failed 1
Socket failed 2
Tried everything there, added permissions to my AndroidManifest.xml, uninstalled, used physical phone etc. But nothing works.
It could be my code, I've tried searching for an alternative method for AsyncTask. So it could be that the code is written wrong. Hope someone could help me out.
MainActivity:
public class MainActivity extends AppCompatActivity {
private static InetSocketAddress local = new InetSocketAddress("192.168.163.198", 3671);
private static InetSocketAddress server = new InetSocketAddress("192.168.10.13",
KNXnetIPConnection.DEFAULT_PORT);
Button btn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = (Button)findViewById(R.id.button);
ExecutorService executorService = Executors.newSingleThreadExecutor();
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
executorService.execute(new Runnable() {
#Override
public void run() {
//doInBackground
System.out.println("This example establishes a tunneling connection to the KNXnet/IP server " + server);
// A KNX tunneling link supports NAT (Network Address Translation) if required.
// We also indicate that the KNX installation uses twisted-pair (TP) medium, with TP1 being the most common.
// KNXNetworkLink is the base interface implemented by all supported Calimero links to a KNX network.
try (KNXNetworkLink knxLink = KNXNetworkLinkIP.newTunnelingLink(local, server, false, TPSettings.TP1)) {
System.out.println("Connection established to server " + knxLink.getName());
System.out.println("Close connection again");
} catch (KNXException | InterruptedException e) {
// KNXException: all Calimero-specific checked exceptions are subtypes of KNXException
// InterruptedException: longer tasks that might block are interruptible, e.g., connection procedures. In
// such case, an instance of InterruptedException is thrown.
// If a task got interrupted, Calimero will clean up its internal state and resources accordingly.
// Any deviation of such behavior, e.g., where not feasible, is documented in the Calimero API.
System.out.println("Error creating KNXnet/IP tunneling link: " + e);
}
}
});
}
});
}
I figured it out.
It was a stupid mistake with the IP address, should have seen that before. I just change the IP address to that I have on the phone I was connected to (192.168.10.15).
I've taken every step described here in Fiddler site for capturing my application (running in emulator) network packets. The strange thing is that I can decode http/https sent from browser but not https packets from my app. It's more interesting that requests get successful responses! Any idea what might be the problem?
I'm completely stocked and have no idea what should I have done which didn't.
First topic, that I've found on Xamarin forum was Why can't Fiddler detect traffic from Xamarin apps?. The answer is to set DefaultWebProxy:
public override void OnCreate()
{
// get IP from fiddler's internet icon at the top right, or via ipconfig for VirtualBox used by Genymotion
WebRequest.DefaultWebProxy = new WebProxy("192.168.56.1", 8888);
base.OnCreate();
...
}
I put it in MainActivity, but it didn't solve my problem.
Which helped me is Debugging HttpClient Calls with fiddler in PCL:
You will need to change your code to use a HttpClientHandler and a proxy
HttpClientHandler handler = new HttpClientHandler ()
{
Proxy = new WebProxy (new Uri("http://[Computer IP]:[Fiddler port number]")),
UseProxy = true
};
using (var client = new HttpClient(handler))
{
// Make your call in here
}
Looks simple enough only PCLs dont include the Web proxy class in its bundled System.Net dll for whatever reason so you will need to write your own by extending the System.Net.IWebProxy interface
like so
public class WebProxy : System.Net.IWebProxy
{
public System.Net.ICredentials Credentials
{
get;
set;
}
private readonly Uri _proxyUri;
public WebProxy(Uri proxyUri)
{
_proxyUri = proxyUri;
}
public Uri GetProxy(Uri destination)
{
return _proxyUri;
}
public bool IsBypassed(Uri host)
{
return false;
}
}
After all this stuff, I was able to capture requests from my Xamarin.Forms app on Android Emulator.
All Bluetooth projects I have previously done, had an Android device acting as the Master, with a Bluetooth dongle or chip acting as a single Slave. The project I am working on will have an Android Tablet acting as the Master, then have several other Android Devices acting as the Slaves.
What is the best practice in this situation? Should I write two separate applications? One for the master, another for the slaves? Or would it be plausible to use one application for both rolls?
The best way to do this would be to just make one application and then just have different code logic based on if the device is a master or a slave.
Instead of doing just a simple SPP connection, you could create a sort of bluetooth "Server" and wait until x number of devices connect to the server and then do whatever it is you want to do in your app.
An example (From the developer guide: Here)
private class AcceptThread extends Thread {
private final BluetoothServerSocket mmServerSocket;
public AcceptThread() {
// Use a temporary object that is later assigned to mmServerSocket,
// because mmServerSocket is final
BluetoothServerSocket tmp = null;
try {
// MY_UUID is the app's UUID string, also used by the client code
tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
} catch (IOException e) { }
mmServerSocket = tmp;
}
public void run() {
BluetoothSocket socket = null;
// Keep listening until exception occurs or a socket is returned
while (true) {
try {
socket = mmServerSocket.accept();
} catch (IOException e) {
break;
}
// If a connection was accepted
if (socket != null) {
// Do work to manage the connection (in a separate thread)
manageConnectedSocket(socket);
//in your case you wouldn't want to close the server socket since you want to
//connect more than one device. So keep listening until you get all the devices.
//you're also going to have to use different UUID's for each new device.
// mmServerSocket.close();
break;
}
}
}
/** Will cancel the listening socket, and cause the thread to finish */
public void cancel() {
try {
mmServerSocket.close();
} catch (IOException e) { }
}
}
In this code the server is closed as soon as one connection is made, in your case you would just keep listening for more sockets until you get all the sockets. You're going to need multiple threads to handle all the connections and some synchronization for handling all the data from all the connections depending on what you intend on doing.
I have a GoPro Hero3 Black Edition and after reading their user forums, I got these 2 url commands that can control the shutter button while the GoPro is acting as a hotspot.
Record/shoot Command
On http://10.5.5.9:80/bacpac/SH?t=WIFIPASSWORD&p=%01
Off http://10.5.5.9:80/bacpac/SH?t=WIFIPASSWORD&p=%00
I have tried using the URLs in my Nexus 7's Chrome Browser but I want to integrate these 2 commands in a button in my Android app when my Nexus 7 connects via wifi to the GoPro.
How do I do this? Thanks in advance.
It's not that tough. Create an activity class and a couple of buttons to fire the HTTP commands.
Keep in mind that these are network calls and have to be made from a separate background thread (not the main thread).
btnToggle.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// Toggle the camera power
new OperateCamera().execute();
}
});
Create a new AsyncTask class:
class OperateCamera extends AsyncTask<String, Void, Boolean> {
protected Boolean doInBackground(String... urls) {
return triggerShutter();
}
// Method to trigger the shutter
boolean triggerShutter(){
try {
// Make network call
return true;
}
catch (Exception e) {
return false;
}
}
}
Just use the legacy URLConnection or some lib like OkHttp to access these urls and trigger the shutter. I'd recommend the second ;)
I'm developing an android app using socket. But Socket soc=new Socket(ip,port) always give me a SocketTimeoutException. I use socket in a java project, it's Ok. But not in an android project.
public static void main(String[] args) {
try{
Socket soc=new Socket("192.168.177.103",8888);
}catch(Exception e){
e.printStackTrace();
}
}
This is all right, but not in an android project. Why?
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mmmm);
new Thread(){
public void run(){
try{
Socket soc=new Socket("192.168.177.103",8888);
}catch(Exception e){
e.printStackTrace();
}
}
}.start();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_mmmm, menu);
return true;
}
Could someone tell me why? Thank you very much.
The Exception details when use socket in android:
java.net.SocketTimeoutException: Connection timed out
at org.apache.harmony.luni.platform.OSNetworkSystem.connect(Native Method)
at dalvik.system.BlockGuard$WrappedNetworkSystem.connect(BlockGuard.java:361)
at org.apache.harmony.luni.net.PlainSocketImpl.connect(PlainSocketImpl.java:204)
at org.apache.harmony.luni.net.PlainSocketImpl.connect(PlainSocketImpl.java:183)
at java.net.Socket.startupSocket(Socket.java:732)
at java.net.Socket.tryAllAddresses(Socket.java:152)
at java.net.Socket.<init>(Socket.java:211)
at java.net.Socket.<init>(Socket.java:178)
at com.example.mmmmm.MMMMActivity$1.run(MMMMActivity.java:26)
Your server 192.168.177.103 is not responding in timely manner, or at all. It may also be that the port 8888 is closed by its firewall. So this is actually not the Android device problem.
If the returned content is HTTP based, use some desktop PC connected to the same LAN to check if the server responds to the ordinary browser request. Also, try
adb shell ping 192.168.177.103
This would allow to verify if the server is accessible. However ping may be disabled on your server, especially if it is a Windows machine.
If the server is accessible from desktop connected through the wired network and is still not accessible from Android, it may also be great to check how the firewall of your wireless router is configured.