I'm writing an application that should scan a local area network for connected devices, and return the IP addresses of connected devices.
My scanner consists of "pinging" each IP within a range of IP addresses. This process of pining a range of IP addresses is time consuming.
Then I learned there is something called an ARP (address resolution protocol) cache on Windows machines which is basically a list of valid IP addresses, or IP addresses of connected devices.
So since Android isn't Windows, is there a way to access a similar table simply using an API or something?
Tl;Dr How can I query valid IP addresses on a network (not ping them) in Android
Best solution I came up with so far was to read the ARP file in the Android device at file path /proc/net/arp
Here's the main activity class for the app that displays the file content in a simple text view
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tv = (TextView) findViewById(R.id.textView);
// Get an array list of mac to IP address mapping
ArrayList<String> arpTableLines = getArpTableLines();
// Generate a string to display in the text view based on the mapping
String textViewText = getTextViewText(arpTableLines);
// Set the text view value
tv.setText(textViewText);
}
public ArrayList<String> getArpTableLines(){
ArrayList<String> lines = new ArrayList<>();
try{
String line = "";
BufferedReader localBufferdReader =
new BufferedReader(new FileReader(new File("/proc/net/arp")));
while ((line = localBufferdReader.readLine()) != null) {
String[] ipmac = line.split("[ ]+");
if (!ipmac[0].matches("IP")) {
String ip = ipmac[0];
String mac = ipmac[3];
lines.add(ip + " <~> " + mac);
}
}
}catch (FileNotFoundException ex){
Log.v("TAG",Log.getStackTraceString(ex));
} catch (IOException ex){
Log.v("TAG",Log.getStackTraceString(ex));
}
return lines;
}
public String getTextViewText(ArrayList<String> lines){
String result = "";
for(String line : lines) result += line + "\n";
return result;
}
}
Related
so I have an app that is running and on startup, I would like to be able to Get the IP address and display it as a String. I have been using the code below.
String ipAddress = "";
try{
ipAddress = Inet4Address.getLocalHost().getHostAddress();
}
catch(Exception e){
ipAddress = "IP address Cant be used";
}
every time this is run it will return "IP address Cant be used" so it's throwing an error.
If you are looking to get your public facing IP check out this answer. In short you cannot get your public facing IP because the Network Address Transation does not happen in your Kernel, i.e you dont assign your IP to yourself rather it will be given to you thanks to NAT and DHCP. The following code makes a request to amazons's aws IP API, to retrieve your IP
public static String getIp() throws Exception {
URL whatismyip = new URL("http://checkip.amazonaws.com");
BufferedReader in = null;
try {
in = new BufferedReader(new InputStreamReader(
whatismyip.openStream()));
String ip = in.readLine();
return ip;
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
I didn't find the right solution. The below code gives me local IP address (if I connected to Wifi, it gives IP address like 192.168.0.x), but I want public IP address (same as if I search in google " what is my IP ")
public static String getLocalIpAddress() {
try {
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
NetworkInterface intf = en.nextElement();
for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
InetAddress inetAddress = enumIpAddr.nextElement();
if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address) {
return inetAddress.getHostAddress();
}
}
}
} catch (SocketException ex) {
ex.printStackTrace();
}
return null;
}
OR
WifiManager wm = (WifiManager) getSystemService(WIFI_SERVICE);
String ip = Formatter.formatIpAddress(wm.getConnectionInfo().getIpAddress());
Can anyone help? Thanks!
Step #1: Create a Web service that returns the requester's IP address
Step #2: Call that Web service from your app.
A device does not know its public IP address (unless that device was seriously misconfigured).
You may use the WS https://api.whatismyip.com/ip.php from whatismyip.com : This would output only your IP address in the simple text. (No input required, output is optional)
You must be a Gold Level Member to access the API
Updated Answer
You can make use of the web service from ipify.org
Read through the documentation here
Use https://api.ipify.org/?format=json WS to get device public IP address. This would output your IP address in JSON format.
You should use ipify because:
You can use it without limit (even if you're doing millions of requests per minute).
It's always online and available, and its infrastructure is powered by Heroku, which means that regardless of whether the server running the API dies, or if there's an enormous tornado which destroys half of the east coast, ipify will still be running!
It works flawlessly with both IPv4 and IPv6 addresses, so no matter what sort of technology you're using, there won't be issues.
....................
....................
I found this simple solution:
public String getExternalIpAddress() throws Exception {
URL whatismyip = new URL("http://checkip.amazonaws.com");
BufferedReader in = null;
try {
in = new BufferedReader(new InputStreamReader(
whatismyip.openStream()));
String ip = in.readLine();
return ip;
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Remember that this must be run on a separate thread.
You can do this with a simple thread.
you need to create a function in Activity.class file, and need to request a url that will give your public IP in text form: "https://api.ipify.org/. Click to open.
Add this function call in your onCreate() function.
getPublicIP();
Add this function in your MainActivity.class.
private void getPublicIP() {
new Thread(new Runnable(){
public void run(){
//TextView t; //to show the result, please declare and find it inside onCreate()
try {
// Create a URL for the desired page
URL url = new URL("https://api.ipify.org/"); //My text file location
//First open the connection
HttpURLConnection conn=(HttpURLConnection) url.openConnection();
conn.setConnectTimeout(60000); // timing out in a minute
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
//t=(TextView)findViewById(R.id.TextView1); // ideally do this in onCreate()
String str;
while ((str = in.readLine()) != null) {
urls.add(str);
}
in.close();
} catch (Exception e) {
Log.d("MyTag",e.toString());
}
//since we are in background thread, to post results we have to go back to ui thread. do the following for that
PermissionsActivity.this.runOnUiThread(new Runnable(){
public void run(){
try {
Toast.makeText(PermissionsActivity.this, "Public IP:"+urls.get(0), Toast.LENGTH_SHORT).show();
}
catch (Exception e){
Toast.makeText(PermissionsActivity.this, "TurnOn wiffi to get public ip", Toast.LENGTH_SHORT).show();
}
}
});
}
}).start();
}
Make a call to a server like https://whatismyipaddress.com or http://howtofindmyipaddress.com/.
If you have the page source then parse the ip address out.
There are other servers who only return your ip address. Not a whole html page as above two. But i forgot which one...
How can I parse /proc/cpuinfo virtual file of my Android tablet to get information of the processor's core and clockspeed?
I don’t need all information provided by the above file; just these two bits.
Can someone please help?
It is not clear if you want this information inside your app, or just for your own use.
you can get this information on with adb:
adb shell cat /proc/cpuinfo
If you want to use this information in your app, create a simple function to return a Map<String,String>, for example,
public static Map<String, String> getCpuInfoMap() {
Map<String, String> map = new HashMap<String, String>();
try {
Scanner s = new Scanner(new File("/proc/cpuinfo"));
while (s.hasNextLine()) {
String[] vals = s.nextLine().split(": ");
if (vals.length > 1) map.put(vals[0].trim(), vals[1].trim());
}
} catch (Exception e) {Log.e("getCpuInfoMap",Log.getStackTraceString(e));}
return map;
}
Note, this will not get multiple cpus information, overwrites. Most of the values are similar anyways. or Modify to create List of CpuInfoMaps.
try,
Log.d("getCpuInfoMap test", getCpuInfoMap().toString());
I hope its not too late for an answer but, this is how i get the current frequency for a specific cpu core:
public class MainActivity extends Activity{
private static final int INSERTION_POINT = 27;
private static String getCurFrequencyFilePath(int whichCpuCore){
StringBuilder filePath = new StringBuilder("/sys/devices/system/cpu/cpu/cpufreq/scaling_cur_freq");
filePath.insert(INSERTION_POINT, whichCpuCore);
return filePath.toString();
}
public static int getCurrentFrequency(int whichCpuCore){
int curFrequency = -1;
String cpuCoreCurFreqFilePath = getCurFrequencyFilePath(whichCpuCore);
if(new File(cpuCoreCurFreqFilePath).exists()){
try {
BufferedReader br = new BufferedReader(new FileReader(new File(cpuCoreCurFreqFilePath)));
String aLine;
while ((aLine = br.readLine()) != null) {
try{
curFrequency = Integer.parseInt(aLine);
}
catch(NumberFormatException e){
Log.e(getPackageName(), e.toString());
}
}
if (br != null) {
br.close();
}
}
catch (IOException e) {
Log.e(getPackageName(), e.toString());
}
}
return curFrequency;
}
}
From here its a piece of cake, you simply call the method :-D
int core1CurrentFreq = getCurrentFrequency(1, this);
Sometimes the cores go offline, in which case the file path will not exist and -1 will be returned
NOTE. the returned value is in KHz
MHz value is core1CurrentFreq / 1e3
GHz value is core1CurrentFreq / 1e6
Some explainations on the getCurFrequencyFilePath() method since it is not all that clear.
Current frequency is usually stored in the file: scaling_cur_freq
The file path is:
"/sys/devices/system/cpu/cpu(XX)/cpufreq/scaling_cur_freq"
where (XX) is substituted for the cpu core number eg:
"/sys/devices/system/cpu/cpu2/cpufreq/scaling_cur_freq"
The INSERTION_POINT variable is nothing more than the index of (XX), the point at which we want to place the number corresponding to the cpu core
I suggest you take a look at some of the other files in the cpufreq folder, you can use them to get other information like maximum and minimum frequency, list of availables frequencies etc.
Click this
Link
and scroll down to heading 3
I need to calculate the following:
upload,
download speed
packet loss
jitter
latency to servers on all the continents
locally and details about mobile carriers
Could someone please tell me what is the best way to track these things?
I need accuracy to be high.
please find the code to get latency.and mark it as solution if it solve your problem ,so that it helps the other to find the answer.
public String getLatency()
{
String latency ="";
String ip = "ip address of the server";
String pingCmd = "ping -c 25 " + ip;
try {
Runtime r = Runtime.getRuntime();
Process p = r.exec(pingCmd);
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
String inputLine;
String latencyResult = null;
while ((inputLine = in.readLine()) != null)
{
latencyResult = inputLine;
}
String[] keyValue = latencyResult.split("=");
String[] value = keyValue[1].split("/");
latency = value[1];
}
catch (Exception e)
{
LogWrite.d(TAG, "Exception..."+e);
}
return latency ;
}`
I am developing shopping cart application in Android 2.1 . I want to print the order details ( customer details , cart details, order total) , when user submit the order . I want to use some WIFI printer for printing the data. Please help me with suitable examples ...
I assume you want to print on receipt-sized paper. If so, Star Micronics has an Android SDK with support for Wifi connections as well as USB and Bluetooth. Download it here: http://starmicronics.com/support/sdkdocumentation.aspx
If you're looking for a regular size printer, check out Google Cloud Print: https://developers.google.com/cloud-print/?hl=en
Create a Socket connection from ip address and port number.
String ip = "your printer ip address";
int port = port number;
private class printTCP extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
if (!ip.equals("")) {
if ((pref.getString(Const.PORT_CASH) != null) && (!pref.getString(Const.PORT_CASH).equals(""))) {
port = Integer.parseInt(pref.getString(Const.PORT_CASH));
try {
client = new Socket(ip, port);// ip address and port number of ur hardware device
String text = "Test Print";
byte[] bytes = text.getBytes(); //create a byte array
outputStream = client.getOutputStream();
outputStream.write(bytes, 0, bytes.length); //write file to the output stream byte by byte
outputStream.flush();
outputStream.close();
client.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
#Override
protected void onPostExecute(String result) {
}
}