I'm new in Android programming and there is this project I'm working on to be able to turn on my computer using my phone. I have written my codes where by when an item in a list-view is clicked, it will fetch mac address and use it to turn on computer. The problem is that, the packet is never sent, I'm using Emulator. I have tried to search solutions in Google but couldn't find enough break through. Really need your help.
Here are my codes:
package black.cheetah.blackcheetah;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import android.os.Bundle;
import android.os.StrictMode;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Toast;
public class ComputerTurnOnList extends Activity {
public static final int PORT = 9;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_computer_turn_on_list);
if (android.os.Build.VERSION.SDK_INT > 8) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll()
.build();
StrictMode.setThreadPolicy(policy);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void buttonClick(View view) {
String broadcastIP = "192-168-43-171";
String mac = "3C-97-0E-82-3D-BD";
Log.d("Read mac= ", mac);
Log.d("Read ip=", broadcastIP);
ComputerTurnOnList.wakeup(broadcastIP, mac);
}
private static byte[] getMacBytes(String mac) throws IllegalArgumentException {
Log.d("GetMacBytes", "method started");
// TODO Auto-generated method stub
byte[] bytes = new byte[6];
String[] hex = mac.split("(\\:|\\-)");
if (hex.length != 6) {
throw new IllegalArgumentException("Invalid MAC address.");
}
try {
for (int i = 0; i < 6; i++) {
bytes[i] = (byte) Integer.parseInt(hex[i], 16);
Log.d("GetMacbytes", "calculated");
Log.d("GetMacBytes (bytes)", new String(bytes));
}
}
catch (NumberFormatException e) {
Log.e("GetMacBytes","error");
}
return bytes;
}
public static void wakeup(String broadcastIP, String mac) {
Log.d("wakeup", "method started");
if (mac == null) {
Log.d("Mac error at wakeup", "mac = null");
return;
}
try {
byte[] macBytes = getMacBytes(mac);
Log.d("wakeup (bytes)", new String(macBytes));
byte[] bytes = new byte[6 + 16 * macBytes.length];
for (int i = 0; i < 6; i++) {
bytes[i] = (byte) 0xff;
}
for (int i = 6; i < bytes.length; i += macBytes.length) {
System.arraycopy(macBytes, 0, bytes, i, macBytes.length);
}
Log.d("wakeup", "calculating completed, sending...");
InetAddress address = InetAddress.getByName(broadcastIP);
DatagramPacket packet = new DatagramPacket(bytes, bytes.length,address,9);
DatagramSocket socket = new DatagramSocket();
socket.send(packet);
socket.close();
Toast.makeText(null, "Time up! Couldn't find Computer", Toast.LENGTH_SHORT ).show();
Log.d("wakeup", "Magic Packet sent");
}
catch (Exception e) {
Log.e("wakeup", "error" + e.getMessage());
}
}
}
When I run it here come an error:
05-30 06:26:15.607: D/Read mac=(1755): XX-XX-XX-XX-XX-XX
05-30 06:26:15.617: D/Read ip=(1755): xxx-xxx-xx-xxx
05-30 06:26:15.617: D/wakeup(1755): method started
05-30 06:26:15.617: D/GetMacBytes(1755): method started
05-30 06:26:15.617: D/GetMacbytes(1755): calculated
05-30 06:26:15.617: D/GetMacBytes (bytes)(1755): <����������
05-30 06:26:15.617: D/GetMacbytes(1755): calculated
05-30 06:26:15.657: D/GetMacBytes (bytes)(1755): <���������
05-30 06:26:15.657: D/GetMacbytes(1755): calculated
05-30 06:26:15.657: D/GetMacBytes (bytes)(1755): <�������
05-30 06:26:15.667: D/GetMacbytes(1755): calculated
05-30 06:26:15.667: D/GetMacBytes (bytes)(1755): <������
05-30 06:26:15.667: D/GetMacbytes(1755): calculated
05-30 06:26:15.667: D/GetMacBytes (bytes)(1755): <��=��
05-30 06:26:15.667: D/GetMacbytes(1755): calculated
05-30 06:26:15.667: D/GetMacBytes (bytes)(1755): <��=�
05-30 06:26:15.667: D/wakeup (bytes)(1755): <��=�
05-30 06:26:15.667: D/wakeup(1755): calculating completed, sending...
05-30 06:26:15.667: E/wakeup(1755): errorUnable to resolve host "xxx-xxx-xx-xxx": No address associated with hostname
I don't think you can send UDP via emulator or at least it is not that simple. Try it on your real device.
I got it working with this
public class WakeOnLAN {
public static final int DEFAULT_PORT = 9;
private static final String TAG = WakeOnLAN.class.getSimpleName();
private static final String MAC_REGEX = "([0-9a-fA-F]{2}[-:]){5}[0-9a-fA-F]{2}";
public static int sendPacket(String ipStr, String macStr) {
return sendPacket(ipStr, macStr, DEFAULT_PORT);
}
public static int sendPacket(String ipStr, String macStr, int port) throws IllegalArgumentException {
if (port < 0 || port > 65535) {
throw new IllegalArgumentException("Port must be in the range [0, 65535]. Magic packet is usually used on port 7 or 9");
}
byte[] macBytes = getMacBytes(macStr);
byte[] bytes = new byte[6 + 16 * macBytes.length];
try {
for (int i = 0; i < 6; i++) {
bytes[i] = (byte) 0xff;
}
for (int i = 6; i < bytes.length; i += macBytes.length) {
System.arraycopy(macBytes, 0, bytes, i, macBytes.length);
}
InetAddress address = InetAddress.getByName(ipStr);
DatagramPacket packet = new DatagramPacket(bytes, bytes.length, address, port);
DatagramSocket socket = new DatagramSocket();
socket.send(packet);
socket.close();
Log.d(TAG, "Wake-on-LAN packet sent.");
return 0;
} catch (Exception e) {
Log.e(TAG, "Failed to send Wake-on-LAN packet:" + e);
return -1;
}
}
private static byte[] getMacBytes(String macStr) throws IllegalArgumentException {
if (!macStr.matches(MAC_REGEX)) {
throw new IllegalArgumentException("Invalid MAC address");
}
byte[] bytes = new byte[6];
String[] hex = macStr.split("(:|\\-)");
try {
for (int i = 0; i < 6; i++) {
bytes[i] = (byte) Integer.parseInt(hex[i], 16);
}
} catch (NumberFormatException e) {
// Should not happen, the regex forbids it, but it doesn't compile otherwise.
throw new IllegalArgumentException("Invalid hex digit in MAC address.");
}
return bytes;
}
}
And the Activity
public class WakeOnLanActivity extends AppCompatActivity implements View.OnClickListener {
private static final String TEST_IP = "192.168.1.255";
private static final String MAC = "74:D4:35:E7:BA:DC";
private Button btnSend;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.wake_on_lan_demo);
setWidgetConnections();
}
private void setWidgetConnections() {
btnSend = (Button) findViewById(R.id.btnSend);
btnSend.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
new WakeOnLanTask(TEST_IP, MAC, 9).execute();
}
});
}
class WakeOnLanTask extends AsyncTask<Void, Void, Integer> {
private String IP;
private String MAC;
private int port;
public WakeOnLanTask(String ip, String mac, int port) {
this.IP = ip;
this.MAC = mac;
this.port = port;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Integer doInBackground(Void... args) {
return WakeOnLAN.sendPacket(IP, MAC, port);
}
#Override
protected void onPostExecute(Integer integer) {
super.onPostExecute(integer);
}
}
#Override
public void onClick(View view) {
}
}
Related
I'm fairly new to java but am trying to create an app that collects WiFi information periodically, displays it to the user and sends it to a database.
I have Wifi collection working, it collects the SSID, BSSID, RSSI and a timestamp. It displays it to the user and i can even send information to the server.
ui
However, the current code i have does not send the data to the server correctly. It sends the data, but gets stuck on one SSID, BSSID and RSSI. For example if there are 20 wireless networks, the app would send 19 of the same entries and possibly have the next entry as the 20th.
database
I believe it is something to do with the asynctask inside the function InsertData, perhaps it is running quicker than the wifithing function. But i am unsure how to resolve this.
Thanks for all responses!
Update
Hey all!
There are two functions being used here wifithing() and InsertData() which contains a async task for sending data to a mysql database, wifithing() works perfectly and assigns the SSID, BSSID and RSSI to a device to be displayed elsewhere, it does this in a loop to cycle through all the available networks.
Now InsertData() is called by the button press, and uses a loop to cycle through all the available networks. This does work, but am seeing some strange results on the database, first of all an duplicate entry is added at the beginning and secondly on the second button press no data is sent, on the third press it works, then on the fourth it doesn't..
database with duplicate
Edited wififragment.java
package com.example.joe.ratscanner;
import android.Manifest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiManager;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.Toast;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.Executor;
//return inflater.inflate(R.layout.fragment_wifi, container, false);
/**
* A simple {#link Fragment} subclass.
*/
public class wififragment extends Fragment {
int count= 0;
Timer t;
String ServerURL = "http://ratscanner.duckdns.org/get_data.php" ;
String TempWifi;
String TempBSSID;
String Templevel;
String test;
String isthishappening;
TimerTask timer= new TimerTask(){
#Override
public void run() {
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
//count--;
//if (count >= 0) {
if(count == 0) {
//Toast.makeText(getActivity(),"this updated",Toast.LENGTH_SHORT).show();
// wifithing();
//InsertData(); //probably remove this later
}
}
});
//if (count <= 0) {
// t.cancel();
//}
}
};
public class device{
CharSequence name;
public String setName(CharSequence name) {
this.name = name;
return null;
}
public CharSequence getName (){
return name;
}
}
final private int REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS = 125;
List<ScanResult> wifiList;
private WifiManager wifi;
List<device> values = new ArrayList<device>();
int netCount=0;
int AnetCount=0;
RecyclerView recyclerView;
WifiScanAdapter wifiScanAdapter;
public wififragment() {
// Required empty public constructor
}
public static wififragment newInstance() {
wififragment fragment = new wififragment();
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
//Make instance of Wifi
Button btnScan= (Button) getActivity().findViewById(R.id.wifiScan);
wifi = (WifiManager) getActivity().getApplicationContext().getSystemService(Context.WIFI_SERVICE);
//Check wifi enabled or not
if (wifi.isWifiEnabled() == false)
{
Toast.makeText(getActivity(), "Wifi is disabled enabling...", Toast.LENGTH_LONG).show();
wifi.setWifiEnabled(true);
}
//register Broadcast receiver
getActivity().registerReceiver(new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
wifiList=wifi.getScanResults();
netCount=wifiList.size();
AnetCount=wifiList.size();
// wifiScanAdapter.notifyDataSetChanged();
Log.d("Wifi","Total Wifi Network"+netCount);
}
},new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
wifiScanAdapter=new WifiScanAdapter(values,getContext());
recyclerView= (RecyclerView) getActivity().findViewById(R.id.wifiRecyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.setAdapter(wifiScanAdapter);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
checkandAskPermission();
} else {
wifithing();
}
btnScan.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
wifithing();
InsertData();
InsertData();
Toast.makeText(getContext(), netCount +"\n"+ AnetCount , Toast.LENGTH_SHORT).show();
}
});
}
/* public void wifithing(){
SimpleDateFormat dateformat = new SimpleDateFormat("dd-MMM-yyyy");
wifi.startScan();
values.clear();
try {
netCount = netCount - 1;
while (netCount >= 0) {
String currentDateTimeString = dateformat.getDateTimeInstance().format(new Date());
device d = new device();
d.setName(wifiList.get(netCount).SSID.toString()+"\n"+ wifiList.get(netCount).BSSID +" "+ wifiList.get(netCount).level +"\n" + currentDateTimeString );
//TempWifi = d;//returns nothing, need to make it return ssid
//TempWifi = "";// clears the old data
TempWifi = wifiList.get(netCount).SSID.toString(); //adds the new ssid
TempBSSID = wifiList.get(netCount).BSSID.toString(); //adds the new bssid
Templevel = Integer.toString(wifiList.get(netCount).level);// adds the new level
//currently have issue where one/two ssids are put in database
// maybe see how many "SSIDS" database recieves and how many show up on scan
// 20 on server, 20 on app
//20 on server, 20 on app
//19 on server, 19 on app
isthishappening = "This is from wifithing";
InsertData();// calls the method which sends the data to server
Log.d("WiFi",d.getName().toString());
values.add(d);
wifiScanAdapter.notifyDataSetChanged();
netCount=netCount -1;
}
}
catch (Exception e){
Log.d("Wifi", e.getMessage());
}
}*/
public void wifithing(){
SimpleDateFormat dateformat = new SimpleDateFormat("dd-MMM-yyyy");
wifi.startScan();
values.clear();
try {
netCount = netCount - 1;
while (netCount >= 0) {
String currentDateTimeString = dateformat.getDateTimeInstance().format(new Date());
device d = new device();
d.setName(wifiList.get(netCount).SSID.toString()+"\n"+ wifiList.get(netCount).BSSID +" "+ wifiList.get(netCount).level +"\n" + currentDateTimeString );
//TempWifi = d;//returns nothing, need to make it return ssid
//currently have issue where one/two ssids are put in database
// maybe see how many "SSIDS" database recieves and how many show up on scan
// 20 on server, 20 on app
//20 on server, 20 on app
//19 on server, 19 on app
isthishappening = "This is from wifithing";
//InsertData();// calls the method which sends the data to server
Log.d("WiFi",d.getName().toString());
values.add(d);
wifiScanAdapter.notifyDataSetChanged();
netCount=netCount -1;
}
}
catch (Exception e){
Log.d("Wifi", e.getMessage());
}
}
//this code is responsible for sending data to the server through PHP////////////////////////////////////////////////////////
public void InsertData(){
class SendPostReqAsyncTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
try {
AnetCount = AnetCount - 1;
while (AnetCount >= 0) {
TempWifi = wifiList.get(AnetCount).SSID.toString(); //adds the new ssid
TempBSSID = wifiList.get(AnetCount).BSSID.toString(); //adds the new bssid
Templevel = Integer.toString(wifiList.get(AnetCount).level);// adds the new level
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("SSID", TempWifi));
nameValuePairs.add(new BasicNameValuePair("MAC", TempBSSID));
nameValuePairs.add(new BasicNameValuePair("level", Templevel));
try {
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(ServerURL);
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
} catch (ClientProtocolException e) {
} catch (IOException e) {
}
AnetCount = AnetCount - 1;
}
}
catch (Exception e){
Log.d("Wifi", e.getMessage());
}
return "Data Inserted Successfully";
}
#Override
protected void onPostExecute(String result) {
isthishappening = "This is from async";
Log.d("wifi", isthishappening);
//Log.d("wifi", result);
super.onPostExecute(result);
//Toast.makeText(getContext(), TempWifi, Toast.LENGTH_SHORT).show();
}
}
SendPostReqAsyncTask sendPostReqAsyncTask = new SendPostReqAsyncTask();
sendPostReqAsyncTask.execute();
}///////////////////////////////////////////////////////////////////////////////////////////////////////////////
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
t = new Timer();
t.scheduleAtFixedRate(timer , 10000 , 10000);
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_wifi, container, false);
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions,
int[] grantResults) {
switch (requestCode) {
case REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS: {
Map<String, Integer> perms = new HashMap<String, Integer>();
perms.put(Manifest.permission.ACCESS_COARSE_LOCATION, PackageManager.PERMISSION_GRANTED);
for (int i = 0; i < permissions.length; i++)
perms.put(permissions[i], grantResults[i]);
if (perms.get(Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
wifi.startScan();
} else {
// Permission Denied
Toast.makeText(getContext(), "Some Permission is Denied", Toast.LENGTH_SHORT)
.show();
}
}
}
}
private void checkandAskPermission() {
List<String> permissionsNeeded = new ArrayList<String>();
final List<String> permissionsList = new ArrayList<String>();
if (!addPermission(permissionsList, Manifest.permission.ACCESS_COARSE_LOCATION))
permissionsNeeded.add("Network");
if (permissionsList.size() > 0) {
if (permissionsNeeded.size() > 0) {
// Need Rationale
String message = "You need to grant access to " + permissionsNeeded.get(0);
for (int i = 0; i < permissionsNeeded.size(); i++)
message = message + ", " + permissionsNeeded.get(i);
showMessageOKCancel(message,
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
}
});
return;
}
requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
return;
}
// initVideo();
}
private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) {
new AlertDialog.Builder(getActivity())
.setMessage(message)
.setPositiveButton("OK", okListener)
.setNegativeButton("Cancel", okListener)
.create()
.show();
}
private boolean addPermission(List<String> permissionsList, String permission) {
if (getActivity().checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
permissionsList.add(permission);
if (!shouldShowRequestPermissionRationale(permission))
return false;
}
return true;
}
public void onDetach() {
super.onDetach();
count = 1;
t.cancel();
//timer was created at top of page as infinite, never cancelled even when the fragment closed -
// t.cancel(): stops the timer and allows the page to switch without crashing
}
}
before code snippet from wififragment.java
public void wifithing(){
SimpleDateFormat dateformat = new SimpleDateFormat("dd-MMM-yyyy");
wifi.startScan();
values.clear();
try {
netCount = netCount - 1;
while (netCount >= 0) {
String currentDateTimeString = dateformat.getDateTimeInstance().format(new Date());
device d = new device();
d.setName(wifiList.get(netCount).SSID.toString()+"\n"+ wifiList.get(netCount).BSSID +" "+ wifiList.get(netCount).level +"\n" + currentDateTimeString );
//TempWifi = d;//returns nothing, need to make it return ssid
//TempWifi = "";// clears the old data
TempWifi = wifiList.get(netCount).SSID.toString(); //adds the new ssid
TempBSSID = wifiList.get(netCount).BSSID.toString(); //adds the new bssid
Templevel = Integer.toString(wifiList.get(netCount).level);// adds the new level
//currently have issue where one/two ssids are put in database
// maybe see how many "SSIDS" database recieves and how many show up on scan
// 20 on server, 20 on app
//20 on server, 20 on app
//19 on server, 19 on app
InsertData();// calls the method which sends the data to server
Log.d("WiFi",d.getName().toString());
values.add(d);
wifiScanAdapter.notifyDataSetChanged();
netCount=netCount -1;
}
}
catch (Exception e){
Log.d("Wifi", e.getMessage());
}
}
//this code is responsible for sending data to the server through PHP////////////////////////////////////////////////////////
public void InsertData(){
class SendPostReqAsyncTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("SSID", TempWifi));
nameValuePairs.add(new BasicNameValuePair("MAC", TempBSSID));
nameValuePairs.add(new BasicNameValuePair("level", Templevel));
try {
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(ServerURL);
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
} catch (ClientProtocolException e) {
} catch (IOException e) {
}
return "Data Inserted Successfully";
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
//Toast.makeText(getContext(), TempWifi, Toast.LENGTH_SHORT).show();
}
}
SendPostReqAsyncTask sendPostReqAsyncTask = new SendPostReqAsyncTask();
sendPostReqAsyncTask.execute();
}///////////////////////////////////////////////////////////////////////////////////////////////////////////////
So I had my project working. I am sending objects through a socket connection so I had to add a class to my client side (android project). Now I get this exception:
java.lang.ClassNotFoundException: [LDB.LuceneSearchEngine$LuceneSearchResults;
at java.lang.Class.classForName(Native Method)
at java.lang.Class.forName(Class.java:324)
at java.io.ObjectInputStream.resolveClass(ObjectInputStream.java:2258)
at java.io.ObjectInputStream.readNewClassDesc(ObjectInputStream.java:1641)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:657)
at java.io.ObjectInputStream.readNewArray(ObjectInputStream.java:1418)
at java.io.ObjectInputStream.readNonPrimitiveContent(ObjectInputStream.java:759)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:1983)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:1940)
at com.shoppiness.radu.jshoppiness.Client.run(Client.java:82)
at com.shoppiness.radu.jshoppiness.MainActivity$connectTask.doInBackground(MainActivity.java:77)
at com.shoppiness.radu.jshoppiness.MainActivity$connectTask.doInBackground(MainActivity.java:61)
at android.os.AsyncTask$2.call(AsyncTask.java:295)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.lang.ClassNotFoundException: Didn't find class "DB.LuceneSearchEngine$LuceneSearchResults" on path: DexPathList[[zip file "/data/app/com.shoppiness.radu.jshoppiness-1/base.apk"],nativeLibraryDirectories=[/data/app/com.shoppiness.radu.jshoppiness-1/lib/arm, /vendor/lib, /system/lib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
at java.lang.Class.classForName(Native Method)
at java.lang.Class.forName(Class.java:324)
at java.io.ObjectInputStream.resolveClass(ObjectInputStream.java:2258)
at java.io.ObjectInputStream.readNewClassDesc(ObjectInputStream.java:1641)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:657)
at java.io.ObjectInputStream.readNewArray(ObjectInputStream.java:1418)
at java.io.ObjectInputStream.readNonPrimitiveContent(ObjectInputStream.java:759)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:1983)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:1940)
at com.shoppiness.radu.jshoppiness.Client.run(Client.java:82)
at com.shoppiness.radu.jshoppiness.MainActivity$connectTask.doInBackground(MainActivity.java:77)
at com.shoppiness.radu.jshoppiness.MainActivity$connectTask.doInBackground(MainActivity.java:61)
at android.os.AsyncTask$2.call(AsyncTask.java:295)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
Suppressed: java.lang.ClassNotFoundException: DB.LuceneSearchEngine$LuceneSearchResults
at java.lang.Class.classForName(Native Method)
at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
... 19 more
Caused by: `java.lang.NoClassDefFoundError`: Class is not found using the boot class loader; no stack trace available
LuceneSearchEngine.java is the class I just added. There is another class declared inside LuceneSearchEngine which is LuceneSearchResults.
I tried to delete this classes and create them again with a slightly different name. When I run I get that exception even if I remove that class from the project.
The strange thing is that I created a new project and pasted old classes. Then I added LuceneSearchEngine and LuceneSearchEngineResults but named them differently. I got exactly the same exception even though those classes were never added to the new project.
I tried cleaning and rebuilding but it doesn't work.
MANIFEST:
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
package com.shoppiness.radu.jshoppiness;
import java.io.File;
// TODO: create final strings for hardcodede stuff...
public class LuceneSearchEngine {
public static class LuceneSearchResults
{
private static String userSearch = "";
public String getUserSearch() {
return userSearch;
}
public static void setUserSearch(String userSearch1) {
userSearch = userSearch1;
}
private String product_code;
private String adv_name;
private String category;
private String manufacturer;
private String gift_included;
private String product_name;
private String product_desc;
private String product_aff_link;
private String product_pic;
private String price_no_vat;
private String price_vat;
private String free_shipping;
public LuceneSearchResults()
{
product_code = null;
adv_name = "";
category = null;
}
private static int productScore(LuceneSearchResults result)
{
int score = 0;
if(LuceneSearchResults.userSearch.contains(result.product_code))
return 666;
else
{
if(LuceneSearchResults.userSearch.contains(result.adv_name))
score+=4;
if(LuceneSearchResults.userSearch.contains(result.manufacturer))
score+=3;
if(LuceneSearchResults.userSearch.contains(result.category))
score+=2;
if(LuceneSearchResults.userSearch.contains(result.product_name))
score++;
return score;
}
}
// quicksort
private static int partition(LuceneSearchResults results[], int left, int right)
{
int i = left, j = right;
LuceneSearchResults tmp;
int pivot = productScore(results[(left + right) / 2]);
while (i <= j) {
while (productScore(results[i]) < pivot)
i++;
while (productScore(results[j]) > pivot)
j--;
if (i <= j) {
tmp = results[i];
results[i] = results[j];
results[j] = tmp;
i++;
j--;
}
};
return i;
}
public static void quickSort(LuceneSearchResults results[], int left, int right) {
int index = partition(results, left, right);
if (left < index - 1)
quickSort(results, left, index - 1);
if (index < right)
quickSort(results, index, right);
}
//
// getters and setters
public String getProduct_code() {
return product_code;
}
public void setProduct_code(String product_code) {
this.product_code = product_code;
}
public String getAdv_name() {
return adv_name;
}
public void setAdv_name(String adv_name) {
this.adv_name = adv_name;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public String getManufacturer() {
return manufacturer;
}
public void setManufacturer(String manufacturer) {
this.manufacturer = manufacturer;
}
public String getGift_included() {
return gift_included;
}
public void setGift_included(String string) {
this.gift_included = string;
}
public String getProduct_name() {
return product_name;
}
public void setProduct_name(String product_name) {
this.product_name = product_name;
}
public String getProduct_desc() {
return product_desc;
}
public void setProduct_desc(String product_desc) {
this.product_desc = product_desc;
}
public String getProduct_aff_link() {
return product_aff_link;
}
public void setProduct_aff_link(String product_aff_link) {
this.product_aff_link = product_aff_link;
}
public String getProduct_pic() {
return product_pic;
}
public void setProduct_pic(String product_pic) {
this.product_pic = product_pic;
}
public String getPrice_no_vat() {
return price_no_vat;
}
public void setPrice_no_vat(String string) {
this.price_no_vat = string;
}
public String getPrice_vat() {
return price_vat;
}
public void setPrice_vat(String string) {
this.price_vat = string;
}
public String getFree_shipping() {
return free_shipping;
}
public void setFree_shipping(String string) {
this.free_shipping = string;
}
}
public static final File INDEX_DIRECTORY = new File("IndexDirectory");
public int getHitsCount()
{
return -1;
}
public void createIndex() {
}
public LuceneSearchResults[] search() {
return null;
}
public static void main(String[] args) {
}
}
Client.java // here
package com.shoppiness.radu.shoppiness;
import android.util.Log;
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
public class Client {
private LuceneEngine.LuceneSearchResults[] serverMessage;
public static String SERVERIP = "5.15.110.111" ; // your computer IP
// address
public static final int SERVERPORT = 3316;
private OnMessageReceived mMessageListener = null;
private boolean mRun = false;
PrintWriter out;
ObjectInputStream in;
/**
* Constructor of the class. OnMessagedReceived listens for the messages
* received from server
*/
public Client(OnMessageReceived listener) {
mMessageListener = listener;
}
/**
* Sends the message entered by client to the server
*
* #param message
* text entered by client
*/
public void sendMessage(String message) {
if (out != null && !out.checkError()) {
out.println(message);
out.flush();
}
}
public void stopClient() {
mRun = false;
}
public void run() {
mRun = true;
try {
// here you must put your computer's IP address.
InetAddress serverAddr = InetAddress.getByName(SERVERIP);
Log.e("serverAddr", serverAddr.toString());
Log.e("TCP Client", "C: Connecting...");
// create a socket to make the connection with the server
Socket socket = new Socket(serverAddr, SERVERPORT);
Log.e("TCP Server IP", SERVERIP);
try {
// send the message to the server
out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())), true);
Log.e("TCP Client", "C: Sent.");
Log.e("TCP Client", "C: Done.");
// receive the message which the server sends back
in = new ObjectInputStream(socket.getInputStream());
// in this while the client listens for the messages sent by the
// server
while (mRun) {
serverMessage = new LuceneEngine.LuceneSearchResults[1000];
serverMessage = (LuceneEngine.LuceneSearchResults[]) in.readObject();
if (serverMessage != null && mMessageListener != null) {
// call the method messageReceived from MyActivity class
Log.d("Radu:", "Object recieved!");
mMessageListener.messageReceived(serverMessage[0].getAdv_name());
Log.d("WIN::", serverMessage[0].getAdv_name());
}
serverMessage = null;
}
Log.e("RESPONSE FROM SERVER", "S: Received Message: '"
+ serverMessage + "'");
} catch (Exception e) {
Log.e("TCP", "S: Error", e);
} finally {
// the socket must be closed. It is not possible to reconnect to
// this socket
// after it is closed, which means a new socket instance has to
// be created.
socket.close();
}
} catch (Exception e) {
Log.e("TCP", "C: Error", e);
}
}
// Declare the interface. The method messageReceived(String message) will
// must be implemented in the MyActivity
// class at on asynckTask doInBackground
public interface OnMessageReceived {
public void messageReceived(Object message);
}
}
connectTask.java
public class connectTask extends AsyncTask<String,String,Client> {
#Override
protected Client doInBackground(String... message) {
//we create a Client object and
Log.d("Radu:", "new client");
mClient = new Client(new Client.OnMessageReceived() {
#Override
//here the messageReceived method is implemented
public void messageReceived(Object message) {
//this method calls the onProgressUpdate
Log.d("Radu:", "publishProgress...");
publishProgress(message.toString());
}
});
mClient.run();
return null;
}
#Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
//in the arrayList we add the messaged received from server
arrayList.add(values[0]);
Log.e("OBJECT_RECIEVED:", values[0].toString());
// notify the adapter that the data set has changed. This means that new message received
// from server was added to the list
}
}
The log is very clear about it:
java.lang.ClassNotFoundException: DB.LuceneSearchEngine$LuceneSearchResults
You are trying to load the class LuceneSearchEngine$LuceneSearchResults from package DB.
In the code posted the package for that class is com.shoppiness.radu.jshoppiness.
Also from the log the error start at com.shoppiness.radu.jshoppiness.MainActivity$connectTask.doInBackground(MainActivity.java:61) so it's better to look there for the error.
Update
You send the "wrong" object and when you read it in the following line you get the class cast exception:
serverMessage = (LuceneEngine.LuceneSearchResults[]) in.readObject();
The problem is the package of the class.
I facing to problem when use Google Cloud Printing when Print Button was clicked.
This's error show in debug mode
Uncaught TypeError: Cannot read property 'o' of null", source: https://www.google.com/cloudprint/client/2026774633-dialog_mobile__vi.js (295)
Does anyone has a solution for this problem?
Edit 1
This's my code for class PrintDialogActivity.java
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.ContentResolver;
import android.content.Intent;
import android.os.Bundle;
import android.util.Base64;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
#SuppressLint("SetJavaScriptEnabled")
public class PrintDialogActivity extends Activity {
private static final String PRINT_DIALOG_URL = "https://www.google.com/cloudprint/dialog.html";
private static final String JS_INTERFACE = "AndroidPrintDialog";
private static final String CONTENT_TRANSFER_ENCODING = "base64";
private static final String ZXING_URL = "http://zxing.appspot.com";
private static final int ZXING_SCAN_REQUEST = 65743;
/**
* Post message that is sent by Print Dialog web page when the printing dialog
* needs to be closed.
*/
private static final String CLOSE_POST_MESSAGE_NAME = "cp-dialog-on-close";
/**
* Web view element to show the printing dialog in.
*/
private WebView dialogWebView;
/**
* Intent that started the action.
*/
Intent cloudPrintIntent;
#SuppressLint("JavascriptInterface") #Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.print_dialog);
dialogWebView = (WebView) findViewById(R.id.webview);
cloudPrintIntent = this.getIntent();
WebSettings settings = dialogWebView.getSettings();
settings.setJavaScriptEnabled(true);
settings.setDomStorageEnabled(true);
dialogWebView.setWebViewClient(new PrintDialogWebClient());
dialogWebView.addJavascriptInterface(
new PrintDialogJavaScriptInterface(), JS_INTERFACE);
dialogWebView.loadUrl(PRINT_DIALOG_URL);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
if (requestCode == ZXING_SCAN_REQUEST && resultCode == RESULT_OK) {
dialogWebView.loadUrl(intent.getStringExtra("SCAN_RESULT"));
}
}
final class PrintDialogJavaScriptInterface {
public String getType() {
return cloudPrintIntent.getType();
}
public String getTitle() {
return cloudPrintIntent.getExtras().getString("title");
}
public String getContent() {
try {
ContentResolver contentResolver = getContentResolver();
InputStream is = contentResolver.openInputStream(cloudPrintIntent.getData());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[4096];
int n = is.read(buffer);
while (n >= 0) {
baos.write(buffer, 0, n);
n = is.read(buffer);
}
is.close();
baos.flush();
return Base64.encodeToString(baos.toByteArray(), Base64.DEFAULT);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return "";
}
public String getEncoding() {
return CONTENT_TRANSFER_ENCODING;
}
public void onPostMessage(String message) {
if (message.startsWith(CLOSE_POST_MESSAGE_NAME)) {
finish();
}
}
}
private final class PrintDialogWebClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url.startsWith(ZXING_URL)) {
Intent intentScan = new Intent("com.google.zxing.client.android.SCAN");
intentScan.putExtra("SCAN_MODE", "QR_CODE_MODE");
try {
startActivityForResult(intentScan, ZXING_SCAN_REQUEST);
} catch (ActivityNotFoundException error) {
view.loadUrl(url);
}
} else {
view.loadUrl(url);
}
return false;
}
#Override
public void onPageFinished(WebView view, String url) {
if (PRINT_DIALOG_URL.equals(url)) {
// Submit print document.
view.loadUrl("javascript:printDialog.setPrintDocument(printDialog.createPrintDocument("
+ "window." + JS_INTERFACE + ".getType(),window." + JS_INTERFACE + ".getTitle(),"
+ "window." + JS_INTERFACE + ".getContent(),window." + JS_INTERFACE + ".getEncoding()))");
// Add post messages listener.
view.loadUrl("javascript:window.addEventListener('message',"
+ "function(evt){window." + JS_INTERFACE + ".onPostMessage(evt.data)}, false)");
}
}
}
}
Now, I found solution for my issue:
Maybe the problem come from the Android SDK version. You can see this link: https://developers.google.com/cloud-print/docs/android. (It's mean GCP only support for Android version 4.3 below).
Although, I tested on the emulator 4.2 but it still unlucky.
So that, I changed the direction to the Android Print Framework with a little difficult.
Firstly, I must install Cloud Print Services on emulator.
Secondly, I login Google Account Services for printing function enable and connect to my printer.
Thirdly, I use this code for exec print action
private void printDoc() {
PrintManager printManager = (PrintManager) this.getSystemService(Context.PRINT_SERVICE);
String jobName = mFileName;
Intent myIntent = getIntent();
Uri docUri = myIntent != null ? myIntent.getData() : null;
PrintDocumentAdapter pda = new PrintDocumentAdapter(){
#Override
public void onLayout(PrintAttributes oldAttributes, PrintAttributes newAttributes, CancellationSignal cancellationSignal, LayoutResultCallback callback, Bundle extras){
if (cancellationSignal.isCanceled()) {
callback.onLayoutCancelled();
//return;
}
// Compute the expected number of printed pages
int pages = computePageCount(newAttributes);
PrintDocumentInfo pdi = new PrintDocumentInfo.Builder(mFileName).setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT).setPageCount(pages).build();
callback.onLayoutFinished(pdi, true);
}
#Override
public void onWrite(PageRange[] pages, ParcelFileDescriptor destination, CancellationSignal cancellationSignal, WriteResultCallback callback){
InputStream input = null;
OutputStream output = null;
try {
input = new FileInputStream(docUri.toString());
output = new FileOutputStream(destination.getFileDescriptor());
byte[] buf = new byte[1024];
int bytesRead;
while ((bytesRead = input.read(buf)) > 0) {
output.write(buf, 0, bytesRead);
}
callback.onWriteFinished(pages);
} catch (FileNotFoundException ee){
//Catch exception
} catch (Exception e) {
//Catch exception
} finally {
try {
input.close();
output.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
};
printManager.print(jobName, pda, null);
}
EDIT: My solution was to have a constant class with this code:
static EditText Port = (EditText) MainActivity.mDialog.findViewById(R.id.txtPort); static int mPort = Integer.parseInt(Port.getText().toString()); public static final int PORT = mPort;
I've tried to see the other questions and I understand that I've gotta do something with the UIThread? Honestly, I understand nothing. Im new with android.
The app (chat app) worked fine until I wanted to have multiple ports options depending if I'm hosting (port 5050) or joining (port 80) a chat room. From the beginning i just had a constant value of the port (public static final int PORT) but now i cant have that ofc. If you guys have any other suggestions on how i can have two values of PORT, please share your tips.
Anyway, after trying EVERYTHING I decided to put a method in my main class, and just declare it in other classes. This is the mothod for the value of the port:
public int getPORT() {
txtPORT = (EditText) findViewById(R.id.txtPort);
//String txtPORTa = txtPORT.getText().toString();
int dennaPORT = 0;
if (mJoin.isChecked()) {
dennaPORT = Integer.parseInt(txtPORT.getText().toString());
return dennaPORT;
}
else if (mHost.isChecked()) {
dennaPORT = 5050;
return dennaPORT;
}
return dennaPORT;
}
This is my MainActivity
package chat.chris.android.se.chatup;
import android.app.Activity;
import android.app.Dialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.inputmethod.EditorInfo;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.RadioButton;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
import android.widget.Toast;
import java.util.ArrayList;
import chat.chris.android.se.chatup.Listeners.ChatListener;
import chat.chris.android.se.chatup.Listeners.ConnectionListener;
import chat.chris.android.se.chatup.Networking.Client;
import chat.chris.android.se.chatup.Networking.Server;
import chat.chris.android.se.chatup.Utilities.ServerUtils;
import static chat.chris.android.se.chatup.R.id.rdioHost;
import static chat.chris.android.se.chatup.R.id.rdioJoin;
public class MainActivity extends Activity {
private Adapter chatAdapter;
private Button btnSendMessage;
private EditText txtMessage;
private ListView lstMessages;
private static Dialog mDialog;
private Client mClient;
private Server mServer;
private EditText txtPORT;
private RadioButton mJoin;
private RadioButton mHost;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
showChatSelection();
chatAdapter = new Adapter(this, new ArrayList<ChatItem>());
lstMessages = (ListView) findViewById(R.id.lstChat);
lstMessages.setAdapter(chatAdapter);
txtMessage = (EditText) findViewById(R.id.txtSay);
txtMessage.setOnEditorActionListener(txtMessageEditorActionListener);
btnSendMessage = (Button) findViewById(R.id.btnSend);
btnSendMessage.setOnClickListener(btnSendMessageClickListener);
Client.setOnChatListener(chatListener);
Client.setOnConnectionListener(connectionListener);
}
public void showChatSelection() {
mDialog = new Dialog(this);
mDialog.setContentView(R.layout.layout_chat_choose);
mDialog.setTitle("Chat Room");
mDialog.setCancelable(false);
final EditText txtServer = (EditText) mDialog.findViewById(R.id.txtAddress);
final TextView lblServer = (TextView) mDialog.findViewById(R.id.lblAddress);
final TextView txtPort = (EditText) mDialog.findViewById(R.id.txtPort);
final RadioButton mHost = (RadioButton) mDialog.findViewById(rdioHost);
final RadioButton mJoin = (RadioButton) mDialog.findViewById(rdioJoin);
try {
lblServer.setText(ServerUtils.getLocalIp(this));
} catch (NullPointerException e) {
mHost.setEnabled(false);
mHost.setChecked(false);
lblServer.setText("Wifi must be enabled to host");
mJoin.setChecked(true);
txtServer.setVisibility(View.VISIBLE);
txtPort.setVisibility(View.VISIBLE);
}
mDialog.findViewById(R.id.btnChoose).setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
mDialog.findViewById(R.id.progLoading).setVisibility(View.VISIBLE);
new SetupChat().execute(mHost.isChecked(), mJoin.isChecked() ? txtServer.getText().toString() : "");
}
});
mHost.setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
mJoin.setChecked(false);
txtServer.setVisibility(View.INVISIBLE);
txtPort.setVisibility(View.INVISIBLE);
lblServer.setVisibility(View.VISIBLE);
}
}
});
mJoin.setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
mHost.setChecked(false);
txtServer.setVisibility(View.VISIBLE);
txtPort.setVisibility(View.VISIBLE);
lblServer.setVisibility(View.INVISIBLE);
}
}
});
mDialog.show();
}
private final OnClickListener btnSendMessageClickListener = new OnClickListener() {
#Override
public void onClick(View v) {
sendMessage();
}
};
private final OnEditorActionListener txtMessageEditorActionListener = new OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int id, KeyEvent event) {
if (id == EditorInfo.IME_ACTION_NEXT || id == EditorInfo.IME_ACTION_DONE)
sendMessage();
return true;
}
};
private final ChatListener chatListener = new ChatListener() {
#Override
public void onChat(String message) {
chatAdapter.addItem(new ChatItem("<html>" + message + "</html>", "Friend"));
}
};
private final ConnectionListener connectionListener = new ConnectionListener() {
#Override
public void onDisconnect(Client client) {
chatAdapter.addItem(new ChatItem(client.getName() + " left the chat room", ""));
}
#Override
public void onJoin(Client client) {
chatAdapter.addItem(new ChatItem(client.getName() + " joined the chat room", ""));
}
};
public void sendMessage() {
String message = txtMessage.getText().toString();
if(message == null || message.isEmpty())
return;
message = message.replace(">", ">");
message = message.replace("<", "<");
try {
if (mServer != null) {
mServer.sendMessage(message);
chatAdapter.addItem(new ChatItem(message, "You"));
} else if (mClient != null) {
mClient.sendMessage(message);
chatAdapter.addItem(new ChatItem(message, "You"));
} else {
return;
}
} catch (Exception e) {
chatAdapter.addItem(new ChatItem(e.getMessage(), "<font color='red'>Error</font>"));
return;
}
txtMessage.setText("");
}
public int getPORT() {
txtPORT = (EditText) findViewById(R.id.txtPort);
//String txtPORTa = txtPORT.getText().toString();
int dennaPORT = 0;
if (mJoin.isChecked()) {
dennaPORT = Integer.parseInt(txtPORT.getText().toString());
return dennaPORT;
}
else if (mHost.isChecked()) {
dennaPORT = 5050;
return dennaPORT;
}
return dennaPORT;
}
private class SetupChat extends AsyncTask<Object,Void, Boolean> {
#Override
protected Boolean doInBackground(Object... args) {
try {
if ((Boolean)args[0]) {
mServer = new Server();
new Thread(mServer).start();
} else {
String address = args[1].toString();
mClient = Client.connect(address);
if (mClient == null)
return true;
new Thread(mClient).start();
}
} catch (Exception e) {
e.printStackTrace();
return true;
}
return false;
}
#Override
protected void onPostExecute(Boolean errors) {
if (errors)
Toast.makeText(getApplicationContext(), "Någonting gick fel\nSkrev du in allting rätt?", Toast.LENGTH_LONG).show();
else
mDialog.dismiss();
}
}
}
This is the client class
package chat.chris.android.se.chatup.Networking;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import chat.chris.android.se.chatup.Listeners.ChatListener;
import chat.chris.android.se.chatup.Listeners.ConnectionListener;
import chat.chris.android.se.chatup.MainActivity;
import chat.chris.android.se.chatup.Utilities.Crypto;
public class Client implements Runnable {
private BufferedReader reader;
private DataOutputStream writer;
private boolean disconnecting;
private byte[] cryptoKey;
private String name;
private static ChatListener chatListener;
private static ConnectionListener connectionListener;
//Instansierar ny klient
public Client(Socket s) throws IOException {
cryptoKey = new byte[16];
try {
reader = new BufferedReader(new InputStreamReader(s.getInputStream()));
writer = new DataOutputStream(s.getOutputStream());
} catch (IOException e) {
disconnect();
return;
}
}
//Ger klienten ett namn
public String getName() {
return name;
}
//Sätter namnet
public void setName(String name) {
this.name = name;
}
public static void setOnChatListener(ChatListener listener) {
chatListener = listener;
}
public static void setOnConnectionListener(ConnectionListener listener) {
connectionListener = listener;
}
public BufferedReader getReader() {
return reader;
}
public byte[] getKey(){
return cryptoKey;
}
public void setKey(byte[] key) {
cryptoKey = key;
}
#Override
public void run() {
if (connectionListener != null) {
connectionListener.onJoin(this);
}
try {
while (!disconnecting) {
String read;
if ((read = reader.readLine()) != null) {
if (chatListener != null) {
chatListener.onChat(Crypto.decrypt(read, cryptoKey));
}
}
else{
return;
}
Thread.sleep(5);
}
} catch (IOException e) {
disconnect();
} catch (Exception e) {
e.printStackTrace();
disconnect();
}
}
//Connectar till adressen och returnerar klienten
public static Client connect(String address) throws IOException {
MainActivity porten = new MainActivity();
int PORT;
PORT = porten.getPORT();
InetAddress localAddress = InetAddress.getByName(address);
InetSocketAddress localSocketAddress = new InetSocketAddress(localAddress, PORT);
Socket socket = new Socket();
socket.connect(localSocketAddress, 5000);
Client client = new Client(socket);
socket.getInputStream().read(client.cryptoKey, 0, 16);
System.out.println("Client -> " + new String(client.cryptoKey));
return client;
}
public void sendMessage(String message) throws Exception {
if(message == null || message.isEmpty())
return;
writer.writeUTF(Crypto.encrypt(message, cryptoKey));
}
public void disconnect() {
if (connectionListener != null) {
connectionListener.onDisconnect(this);
}
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
reader = null;
writer = null;
}
}
And this is the server class
package chat.chris.android.se.chatup.Networking;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Random;
import chat.chris.android.se.chatup.MainActivity;
import static chat.chris.android.se.chatup.Utilities.Constants.MAX_USERS;
//import static chat.chris.android.se.chatup.Utilities.Constants.PORT;
public class Server implements Runnable {
private ArrayList<Client> clientList;
private ServerSocket mSocket;
private byte[] cryptoKey;
private boolean shuttingDown;
MainActivity porten = new MainActivity();
//Instansierar en ny server chatt
public Server() throws IOException {
int PORT = porten.getPORT();
mSocket = new ServerSocket(PORT);
clientList = new ArrayList<>();
Random mRand = new SecureRandom();
cryptoKey = new byte[16];
mRand.nextBytes(cryptoKey);
System.out.println("Server ->" + new String(cryptoKey));
}
public boolean isShuttingDown() {
return shuttingDown;
}
public void setShuttingDown(boolean shuttingDown) {
this.shuttingDown = shuttingDown;
}
#Override
public void run() {
while (!shuttingDown) {
Socket socket = null;
Client client;
try {
socket = this.mSocket.accept();
if (clientList.size() >= MAX_USERS) {
socket.close();
return;
}
socket.getOutputStream().write(cryptoKey);
client = new Client(socket);
client.setKey(cryptoKey);
new Thread(client).start();
clientList.add(client);
} catch (IOException e) {
e.printStackTrace();
try {
if (socket != null)
socket.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
public void sendMessage(String message) throws Exception {
for (Client client : clientList) {
if (shuttingDown)
return;
client.sendMessage(message);
}
}
public void shutdown() {
shuttingDown = true;
try {
mSocket.close();
} catch (IOException e) {
} finally {
mSocket = null;
}
}
}
With this setup im getting these errors:
05-04 00:41:58.969 12319-12370/chat.chris.android.se.chatup W/System.err﹕ java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
05-04 00:41:58.970 12319-12370/chat.chris.android.se.chatup W/System.err﹕ at android.os.Handler.<init>(Handler.java:200)
05-04 00:41:58.975 12319-12370/chat.chris.android.se.chatup W/System.err﹕ at android.os.Handler.<init>(Handler.java:114)
05-04 00:41:58.975 12319-12370/chat.chris.android.se.chatup W/System.err﹕ at android.app.Activity.<init>(Activity.java:793)
05-04 00:41:58.975 12319-12370/chat.chris.android.se.chatup W/System.err﹕ at chat.chris.android.se.chatup.MainActivity.<init>(MainActivity.java:32)
05-04 00:41:58.976 12319-12370/chat.chris.android.se.chatup W/System.err﹕ at chat.chris.android.se.chatup.Networking.Server.<init>(Server.java:21)
05-04 00:41:58.976 12319-12370/chat.chris.android.se.chatup W/System.err﹕ at chat.chris.android.se.chatup.MainActivity$SetupChat.doInBackground(MainActivity.java:229)
05-04 00:41:58.976 12319-12370/chat.chris.android.se.chatup W/System.err﹕ at chat.chris.android.se.chatup.MainActivity$SetupChat.doInBackground(MainActivity.java:221)
05-04 00:41:58.976 12319-12370/chat.chris.android.se.chatup W/System.err﹕ at android.os.AsyncTask$2.call(AsyncTask.java:288)
05-04 00:41:58.976 12319-12370/chat.chris.android.se.chatup W/System.err﹕ at java.util.concurrent.FutureTask.run(FutureTask.java:237)
05-04 00:41:58.976 12319-12370/chat.chris.android.se.chatup W/System.err﹕ at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
05-04 00:41:58.976 12319-12370/chat.chris.android.se.chatup W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
05-04 00:41:58.976 12319-12370/chat.chris.android.se.chatup W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
05-04 00:41:58.976 12319-12370/chat.chris.android.se.chatup W/System.err﹕ at java.lang.Thread.run(Thread.java:818)
NEVER create an instance of an Activity, Service, or ContentProvider yourself. Those are always created by the framework. Delete:
MainActivity porten = new MainActivity();
Pass the port into the strangely-named Server class by some other means, such as a constructor parameter or setter method.
I'm trying to implement a function to listen to door 1900 and catch alive message and device ip, I tried to use some libs I found but my applications crashes all the time just trying to initiate the app.
this is my main function
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.splash_screen_layout);
//----------SSDP para identificação da STB--------------------------------
SSDPSocket sock;
try {
sock = new SSDPSocket();
while (true) {
DatagramPacket dp = sock.receive(); **//crashes here**
String c = new String(dp.getData());
System.out.println(c);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//---------------------------------------------------------------------
rest of the lib code
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.MulticastSocket;
import java.net.NetworkInterface;
import java.net.SocketAddress;
public class SSDPSocket {
SocketAddress mSSDPMulticastGroup;
MulticastSocket mSSDPSocket;
public SSDPSocket() throws IOException {
InetAddress localInAddress = InetAddress.getLocalHost(); **//crashes here first**
System.out.println("Local address: " + localInAddress.getHostAddress());
mSSDPMulticastGroup = new InetSocketAddress(SSDP.ADDRESS, SSDP.PORT);
mSSDPSocket = new MulticastSocket(new InetSocketAddress(localInAddress,
0));
NetworkInterface netIf = NetworkInterface
.getByInetAddress(localInAddress);
mSSDPSocket.joinGroup(mSSDPMulticastGroup, netIf);
}
/* Used to receive SSDP packet */
public DatagramPacket receive() throws IOException {
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf, buf.length);
mSSDPSocket.receive(dp);
return dp;
}
public void close() {
if (mSSDPSocket != null) {
mSSDPSocket.close();
}
}
}
public class SSDP {
/* New line definition */
public static final String NEWLINE = "\r\n";
public static final String ADDRESS = "239.255.255.250";
public static final int PORT = 1900;
/* Definitions of start line */
public static final String SL_NOTIFY = "NOTIFY * HTTP/1.1";
public static final String SL_MSEARCH = "M-SEARCH * HTTP/1.1";
public static final String SL_OK = "HTTP/1.1 200 OK";
/* Definitions of search targets */
public static final String ST_RootDevice = "ST:rootdevice";
public static final String ST_ContentDirectory = "ST:urn:schemas-upnp- org:service:ContentDirectory:1";
/* Definitions of notification sub type */
public static final String NTS_ALIVE = "NTS:ssdp:alive";
public static final String NTS_BYE = "NTS:ssdp:byebye";
public static final String NTS_UPDATE = "NTS:ssdp:update";
}
public class SSDPSearchMsg {
static final String HOST = "Host:" + SSDP.ADDRESS + ":" + SSDP.PORT;
static final String MAN = "Man:ssdp:discover";
int mMX = 3; /* seconds to delay response */
String mST; /* Search target */
public SSDPSearchMsg(String ST) {
mST = ST;
}
public int getmMX() {
return mMX;
}
public void setmMX(int mMX) {
this.mMX = mMX;
}
public String getmST() {
return mST;
}
public void setmST(String mST) {
this.mST = mST;
}
#Override
public String toString() {
StringBuilder content = new StringBuilder();
content.append(SSDP.SL_MSEARCH).append(NEWLINE);
content.append(HOST).append(NEWLINE);
content.append(MAN).append(NEWLINE);
content.append(mST).append(NEWLINE);
content.append("MX:" + mMX).append(NEWLINE);
content.append(NEWLINE);
return content.toString();
}
}
Nothing seems to be wrong.
Have you add the multicast permission in Mainifest?
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"></uses-permission>
Android doesnt like you doing expensive operations in the main thread and it throws an exception when yo do it. Try executing that code with a new thread you create. Then it should work.