I'm developing an android app which I want it to display all the IP addresses on the network, I have used it in a java application which works well but when I use it in an android app it crashes when it arrives at InetAddress.getLocalHost(), can this work on an android app or is there another way to do it?
code
InetAddress localhost = null;
try {
localhost = InetAddress.getLocalHost(); // it crashes here
System.out.println("after");
} catch (UnknownHostException e1) {
// TODO Auto-generated catch block
System.out.println("the application stoped here");
e1.printStackTrace();
}
System.out.println("3");
// this code assumes IPv4 is used
byte[] ip = localhost.getAddress();
for (int i = 0; i <= 254; i++) {
ip[3] = (byte) i;
InetAddress address = null;
try {
address = InetAddress.getByAddress(ip);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
PingThread p = new PingThread(address);
p.start();
}
You can solve this problem by adding this to your code before the try/catch:
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
...and this to your AndroidManifest file:
<uses-permission android:name="android.permission.INTERNET" >
</uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" >
</uses-permission>
Refer to the Android Docs for more details about the StrictMode.
Related
I'm trying to check if server is available but when running this code I get error that server is not available or sometimes application freezes even server is properly running:
InetAddress in;
in = null;
try {
in = InetAddress.getByAddress(new byte[] { (byte)192, (byte)168, (byte)16, (byte)48});
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
if (in.isReachable(5000)) {
loadProduct();
} else
{
showAlertBox("Warning", "Server not available!");
}
} catch (IOException e) {
showAlertBox("Warning", "Server not available!");
}
Is there any better way to check if server is online?
Is there any better way to check if server is online
Yes. Try to connect to it. That is an infallible test. Don't do it until you need to, of course. Don't try to predict the future. Just connect and handle the failure.
I have tried with this
Socket socket = null;
boolean reachable = false;
try {
socket = new Socket("192.168.16.48", 80);
reachable = true;
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
showAlertBox("Warning", "Server not available!");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
showAlertBox("Warning", "Server not available!");
} finally {
if (socket != null) try { socket.close(); } catch(IOException e) { }
}
It works, but sometimes I get meesage that that applications is not responding, even if socket timeout is adjusted.
You can try to locate the server using its host name. The advantage: unlike the dynamic ip address, the host name probably has a longer validity. In the following example, both network interfaces can refer to the same host.
byte[] b = { 10, 0, 0, 1 };
String name = "Hostname";
InetAddress ia = Inet4Address.getByAddress(b);
InetAddress ia2 = Inet4Address.getByName(name);
Another possible solution: before using network operations on android, you must get the corresponding permissions from the android manifest. I don't know exactly, which of the following are must-haves:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
Below is the receive method that implements a socket server and works perfectly.
private void Receive(){
log.info("Server started - waiting for the clients.");
try {
Boolean end = false;
ServerSocket ss = new ServerSocket(12345);
while(!end){
//Server is waiting for client here, if needed
Socket s = ss.accept();
BufferedReader input = new BufferedReader(new InputStreamReader(s.getInputStream()));
PrintWriter output = new PrintWriter(s.getOutputStream(),true); //Autoflush
String st = input.readLine();
JSONObject jsonObj;
try {
jsonObj = new JSONObject(st);
long id = jsonObj.optLong("DeviceID", count.addAndGet(1) );
String name = jsonObj.toString();
table.put(id, name);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
etResult.setText(st);
Log.d("Tcp Example", "From client: "+st);
output.println("Response from Sever: Connectivity ok");
s.close();
if (st != null ){ end = true; }
}
ss.close();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
The only problem is, when I hit the button to call that method, the socket starts listening and waits for a client messages. While it does not happen, the app remains freezes and I try to hit any other button, the app may crashes.
Does anyone have a hint about how could handle it and leave the socket listening in "background" withou locking the entire screen?
thank you
Make a thread or AsyncTask and do all the socket functions on that. IF it's something you're going to rarely do and want to fire it off and process the results, use an AsyncTask. If it's something you're going to want to do constantly and don't want to run multiple workers at the same time or have multiple workers queued up, use a Thread.
I can receive my mails with Imap with this code sample :
URLName server = new URLName("imaps://" + username + ":"+ password + "#imap.gmail.com/INBOX");
Session session = Session.getDefaultInstance(new Properties(), null);
Folder folder = session.getFolder(server);
if (folder == null)
{
System.exit(0);
}
folder.open(Folder.READ_ONLY);
Message[] messages = folder.getMessages();
But sometimes Imap doesn't give any service and at those times I want to use Pop but I couldn't use it with my code. It is different the other codes for using receive mail. But in Android only this code is working.
What should I change in this code to work with Pop?
First, there's a nice URLName constructor that takes all the component pieces as separate parameters, so you don't have to do string concatenation.
Switch from IMAP to POP3 requires changing the protocol name as well as the host name. See the JavaMail FAQ for examples. The protocol name is "pop3s" and the host name is "pop.gmail.com".
Finally, you should use Session.getInstance instead of Session.getDefaultInstance. Compare the javadocs for the two methods to understand why.
How about this one.Really worked for me!!(Source:here)
String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
Properties pop3Props = new Properties();
pop3Props.setProperty("mail.pop3.socketFactory.class", SSL_FACTORY);
pop3Props.setProperty("mail.pop3.socketFactory.fallback", "false");
pop3Props.setProperty("mail.pop3.port", "995");
pop3Props.setProperty("mail.pop3.socketFactory.port", "995");
URLName url = new URLName("pop3", "pop.gmail.com", 995, "","youremailid#gmail.com",yourpassword);
Session session = Session.getInstance(pop3Props, null);
Store store = new POP3SSLStore(session, url);
try {
store.connect();
} catch (MessagingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Folder folder = null;
try {
folder = store.getDefaultFolder();
folder = folder.getFolder("INBOX");
} catch (MessagingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (folder == null) {
System.exit(0);
}
try {
folder.open(Folder.READ_ONLY);
} catch (MessagingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Try retreiving folder via store object.And also mention that the folder you wish to retreive is INBOX!Also note that in settings,port number is 995 form pop.(You may leave the first six lines as they are.)
I'm developing a UDP responder to handle basic SSDP commands. The purpose of this piece of code is to do auto discovery, so when the server sends a multicast to a specific group all other subscribed devices should send back a UDP packet announcing its presence to the host and port of who sent the multicast. My android device receives and sends the packet just fine but because it takes too long to get back the SocketAddress object from getSocketAddress() method the server times out, closes the listening port and never gets a packet back from the android device.
Here's my code:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
MulticastSocket ms = null;
byte[] packBuf = new byte[128];
try {
ms = new MulticastSocket(32410);
ms.joinGroup(InetAddress.getByName("239.255.255.250"));
} catch (IOException e3) {
// TODO Auto-generated catch block
e3.printStackTrace();
}
while (true)
{
DatagramPacket receivedPack = new DatagramPacket(packBuf, packBuf.length);
try {
ms.receive(receivedPack);
Log.d(TAG, "Received data");
} catch (IOException e3) {
// TODO Auto-generated catch block
e3.printStackTrace();
}
String responseStr = "HTTP/1.0 200 OK\n" +
"Content-Type: app\n" +
"Resource-Identifier: 945e7dd5913ab45f1db4f271a1620b9471fb7d4d\n" +
"Name: Test App\n" +
"Port: 8888\n" +
"Updated-At: 1319511680\n" +
"Version: 0.9.3.4-29679ad\n" +
"Content-Length: 23\n\n" +
"<message>test</message>";
byte[] response = responseStr.getBytes();
DatagramSocket sendSocket = null;
try {
sendSocket = new DatagramSocket();
} catch (IOException e2) {
// TODO Auto-generated catch block
Log.e(TAG,"Erro",e2);
}
DatagramPacket outPack;
try {
outPack = new DatagramPacket(response, responseStr.length(), receivedPack.getSocketAddress());
sendSocket.send(outPack);
} catch (UnknownHostException e1) {
Log.e(TAG,"Erro",e1);
}
catch (IOException e) {
Log.e(TAG,"Erro",e);
}
catch (Exception e)
{
Log.e(TAG,"Erro",e);
}
}
}
Any ideas?
thanks in advance,
fbr
The most likely problem is that getSocketAddress() is trying to resolve the DNS name of the IP address, which is timing out either due to it being a multicast address or just general DNS lag.
The InetSocketAddress class has a constructor option needResolved which can control this behavior. Unfortunately, it does not appear that DatagramPacket.getSocketAddress() allows you to specify that you want that set to false.
This is apparently a known issue, with some recent discussion of it here:
Issue 12328: DatagramChannel - cannot receive without a hostname lookup
The thread suggests that this has been fixed in Android 3.0, and offers a couple of workarounds for Android 2.0 which may or may not work.
In your case, you could try creating an InetSocketAddress set to INADDR_ANY and port 0 with needsResolved set to 0, and then pass that in when you create receivedPack. Hopefully receive() will reuse that and remember the setting.
2 things come to mind...
1) What happens when you change:
outPack = new DatagramPacket(response, responseStr.length(), receivedPack.getSocketAddress());
to
outPack = new DatagramPacket(response, responseStr.length(), receivedPack.getAddress(), receivedPack.getPort());
2) I remember having this sort of problem with an embedded Java on a Home Automation system. Our short term solution was to put most of the machine and multicast addresses in the hosts file. Long term we ended up with a local DNS server.
There is a parameter somewhere in the Java Network stack that tells it how long to cache DNS failures in memory. We cranked that number up to, I think, 5 minutes instead of 10 seconds.
I want to code an Android app, which will connect to a network printer with a specific IP address, and then make a printing.
For printing I know that I need to write my own Postscript for specific files types, and connecting to a network is not a problem over WIFI.
How to connect to the network printer?
Any device connected to a network will communicate via their IP and Ports / sockets. The simplest way to connect via telnet or socket and write the data to their socket buffers.
try
{
Socket sock = new Socket("192.168.1.222", 9100);
PrintWriter oStream = new PrintWriter(sock.getOutputStream());
oStream.println("HI,test from Android Device");
oStream.println("\n\n\n");
oStream.close();
sock.close();
}
catch (UnknownHostException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
You might be able to use lpdspooler, that is, if the printer supports LPR/LPD. If you can give some more details about the environment (printer, etc), I might be able to give more information.
Just Add This Code After oncreate Method
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy =
new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
Star has an Android SDK which has port discovery. It'll find any of their wifi receipt printers on your network. http://starmicronics.com/support/SDKDocumentation.aspx
Try to use PrintManager: https://developer.android.com/training/printing/custom-docs
private void doPrint() {
// Get a PrintManager instance
PrintManager printManager = (PrintManager) getActivity()
.getSystemService(Context.PRINT_SERVICE);
// Set job name, which will be displayed in the print queue
String jobName = getActivity().getString(R.string.app_name) + " Document";
// Start a print job, passing in a PrintDocumentAdapter implementation
// to handle the generation of a print document
printManager.print(jobName, new MyPrintDocumentAdapter(getActivity()),
null); //
}
My solution. I used Epson TM series. I think the port is 9100 for default.
In Manifest add:
<uses-permission android:name="android.permission.INTERNET"/>
in the activity use a Thread otherwise u you can the android.os.NetworkOnMainThreadException error.
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try {
Socket sock = new Socket("192.168.1.168", 9100);
PrintWriter oStream = new PrintWriter(sock.getOutputStream());
oStream.println("Hi, test from Android Device");
oStream.println("\n");
oStream.close();
sock.close();
} catch (UnknownHostException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
}});
If not enough, add in manifest these:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
Well, you cant connect any devices directly as you will need the driver installed. there are 3rd party apps like Google Cloud print that works seamlessly with Android though.