I am using android autobahn websocket for establish connection between android and python tornado socket server .
Below is the autobahn websocket code which am using in android .
public void start() {
final String wsuri = ip;
try {
mConnection.connect(wsuri, new WebSocketHandler() {
#Override
public void onOpen() {
Log.d(TAG, "Connected to " + wsuri);
}
#Override
public void onTextMessage(String payload) {
Log.d(TAG, "Got echo: " + payload);
try{
InputStream stream = new ByteArrayInputStream(Base64.decode((payload).getBytes(), Base64.DEFAULT));
Bitmap bitmap = BitmapFactory.decodeStream(stream);
image.setImageBitmap(bitmap);
} catch (Exception e) {
Log.d("got exception:", e.toString());
}
}
#Override
public void onClose(int code, String reason) {
Log.d(TAG, "Connection lost.");
Toast.makeText(Project12.this, "Server is Closed", Toast.LENGTH_SHORT).show();
}
});
} catch (WebSocketException e) {
Log.d(TAG, e.toString());
Toast.makeText(Project12.this, "Given IP Adress is not available", Toast.LENGTH_SHORT).show();
return;
}
}
All messages are receiving in public void onTextMessage(Object payload) method.
Problem is that when am sending images less than 128 kb from python socket server, am able to receive it .But when am sending images having size more than 128 kb it shows error which mention below.
WebSocketException (de.tavendo.autobahn.WebSocketException: frame payload too large)
So how can i increase frame payload size.
you need to use WebSocketOptions like this:
WebSocketOptions options = new WebSocketOptions();
options.setMaxMessagePayloadSize(1000000); //max size of message
options.setMaxFramePayloadSize(1000000); //max size of frame
mConnection.connect(wsuri, new WebSocketHandler() {},options);
Related
I'm having a weird problem. I already lost a lot of time trying to understand
and solve this but nothing works.
I have an app that communicates with another device across bluetooth connection
to receive some sensor data. In that point, everything works fine, I can connect
to the device, receive and treat the messages.
But yesterday, I decided to create some kind of log file to directly save in the
internal memory the data received from the device without any kind of transformation from my app.
To receive the data from the device, I have a background thread:
public class CommunicationThread extends Thread {
private static final UUID UUID_DEVICE = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
private static final String TAG = CommunicationThread.class.getSimpleName();
private CommunicationListener mListener;
private boolean mRunning;
private BluetoothSocket mBluetoothSocket;
private InputStream mInputStream;
private OutputStream mOutputStream;
public interface CommunicationListener {
void onMessageReceived(String msg);
}
public CommunicationThread(
#NonNull BluetoothDevice device,
#Nullable CommunicationListener listener) throws IOException {
BluetoothSocket socket = device.createRfcommSocketToServiceRecord(UUID_DEVICE);
socket.connect();
this.mBluetoothSocket = socket;
this.mInputStream = socket.getInputStream();
this.mOutputStream = socket.getOutputStream();
this.mListener = listener;
}
#Override
public void run() {
mRunning = true;
byte[] bytes = new byte[1024];
int length;
while (mRunning) {
try {
Log.d(TAG, "Waiting for message");
// read the message (block until receive)
length = mInputStream.read(bytes);
String msg = new String(bytes, 0, length);
Log.d(TAG, "Message: " + msg);
// Message received, inform the listener
if (mListener != null)
mListener.onMessageReceived(msg);
} catch (Exception e) {
Log.e(TAG, "Error reading the message", e);
}
}
}
public void sendCommand(String msg) {
try {
mOutputStream.write((msg).getBytes());
} catch (Exception e) {
Log.e(TAG, "Error to send message", e);
}
}
public void stopCommunication() {
mRunning = false;
mListener = null;
try {
if (mBluetoothSocket != null) {
mBluetoothSocket.close();
}
if (mInputStream != null) {
mInputStream.close();
}
if (mOutputStream != null) {
mOutputStream.close();
}
} catch (IOException e) {
Log.e(TAG, "Error to stop communication", e);
}
}
}
This thread works pretty fine and when a message is received, it informs the listener,
my Controller class. The first thing that I try to do when a message comes, is save it:
public class Controller implements CommunicationThread.CommunicationListener
...
#Override
public void onMessageReceived(final String msg) {
Log.d(TAG, "onMessageReceived(msg): " + msg);
mLogCreator.saveThis(msg);
....
}
}
Here is the LogCreator class:
public class LogCreator {
private static final String TAG = LogCreator.class.getSimpleName();
public static final String LOG_FILE_NAME = "log.txt";
private final Context mContext;
private volatile String mTempFullLog;
public LogCreator(Context context) {
mContext = context.getApplicationContext();
File dir = new File(mContext.getFilesDir(), "log_folder");
if (!dir.exists()) {
dir.mkdirs();
File file = new File(dir, LOG_FILE_NAME);
writeString(file, "");
Log.d(TAG, "empty file created");
}
}
public void saveThis(final String data) {
mTempFullLog += "\n" + data;
Log.d(TAG, "New log: " + data);
}
public void start() {
File dir = new File(mContext.getFilesDir(), "log_folder");
File file = new File(dir, LOG_FILE_NAME);
mTempFullLog = readString(file);
Log.d(TAG, "File: " + file);
Log.d(TAG, "Temp full log: " + mTempFullLog);
}
public void stop() {
File dir = new File(mContext.getFilesDir(), "log_folder");
File file = new File(dir, LOG_FILE_NAME);
writeString(file, mTempFullLog);
Log.d(TAG, "log saved: " + mTempFullLog);
}
}
The LogCreator class is already initialized and it works properly, because
if I try to read the file later, everything is there.
The real problem is the following: there is a lot of calls to Log.d during
this execution flow, and this makes very easy to me to understand the all process.
But, the logs are only printed in the logcat until this Log.d call, in the
CommunicationThread class:
Log.d(TAG, "Waiting for message);
After the message received, all code executes normally, but no logs are printed in
the logcat and I really dont know why.
Logs not printed:
CommunicationThread:
Log.d(TAG, "Message: " + msg);
Controller:
Log.d(TAG, "onMessageReceived(msg): " + msg);
LogCreator:
Log.d(TAG, "New log: " + data);
Like I said, I know that everything is working fine with the code because the log
file is created in internal memory even without the logcat prints. It cost me
some hours to realize that the problem is only with the log and not really in
my code.
For testing purpose, if I add this code in the saveThis method of LogCreator,
it executes normally:
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
Toast.makeText(mContext, data, Toast.LENGTH_SHORT).show();
}
});
This makes me think that everything could be a thread problem, because the start
and stop methods of LogCreator are both called from the main thread not the CommunicationThread and both methods have their logs printed. Because of this, in the onMessageReceived method
of the Controller class, I tried this:
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
mLogCreator.saveThis(msg);
}
});
But, unfortunately, the logs don't get printed in the logcat. The toast is still
executed and the data are still saved to the file.
If anyone has any idea of what might be causing this, I really want to know, thanks.
I finally find the solution myself. The reason why the following not work is not clear for me, and IMO it should be treated like a bug.
I compile the app in debug mode and discover that the string received from the device has a "\r" in the end.
Example: "15.50\r"
So, for some strange reason, if I try to do this:
Log.d(TAG, "New log: " + data);
Nothing prints and we don't receive no warnings at all.
But, if I do this instead:
Log.d(TAG, "New log: " + data.replace("\r", ""));
Where data is: "15.50\r"
Everything works and the logcat prints the message.
I am trying to develop an android application that can exchange data on peer to peer connection with other devices without server. So please suggest how can I do this. Thank you in advance.
This is a complete code for chat by SocketProgramming without server.
In my Application, first you are a client and you search for a server. When you do not find any server, you become a server and wait for a client.
public class MainActivity extends ActionBarActivity {
private Handler handler = new Handler();
private TextView text;
private EditText input;
private Button send;
private Socket socket;
private DataOutputStream outputStream;
private BufferedReader inputStream;
private String DeviceName = "Device";
private boolean searchNetwork() {
log("Connecting");
String range = "192.168.56.";
for (int i = 1; i <= 255; i++) {
String ip = range + i;
try {
socket = new Socket();
socket.connect(new InetSocketAddress(ip, 9000), 50);
outputStream = new DataOutputStream(socket.getOutputStream());
inputStream = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
DeviceName += "1";
Log.i("Server", DeviceName);
log("Connected");
return true;
} catch (Exception e) {
}
}
return false;
}
private void runNewChatServer() {
ServerSocket serverSocket;
try {
serverSocket = new ServerSocket(9000);
log("Waiting for client...");
socket = serverSocket.accept();
DeviceName += "2";
log("a new client Connected");
} catch (IOException e) {
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text = (TextView) findViewById(R.id.text);
input = (EditText) findViewById(R.id.input);
send = (Button) findViewById(R.id.send);
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try {
if (!searchNetwork()) {
runNewChatServer();
}
outputStream = new DataOutputStream(
socket.getOutputStream());
inputStream = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
while (true) {
String Message = inputStream.readLine();
if (Message != null) {
log(Message);
}
}
} catch (IOException e) {
log("Error: IO Exception");
e.printStackTrace();
}
}
});
send.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
if (outputStream == null) {
return;
}
try {
String Message = input.getText().toString() + "\n";
outputStream.write(Message.getBytes());
log2(input.getText().toString());
} catch (IOException e) {
e.printStackTrace();
}
input.setText("");
}
});
thread.start();
}
private void log(final String message) {
handler.post(new Runnable() {
String DeviceName2="";
#Override
public void run() {
if (DeviceName.equals("Device1")) {
DeviceName2 = "Device2";
}else if(DeviceName.equals("Device2")) {
DeviceName2 = "Device1";
}else{
DeviceName2 = "UnknowDevice";
}
text.setText(text.getText() + "\n" + DeviceName2 + " :"
+ message);
}
});
}
private void log2(final String message) {
handler.post(new Runnable() {
#Override
public void run() {
text.setText(text.getText() + "\n" + "you" + " :"
+ message);
}
});
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.exit(0);
return true;
}
return super.onKeyDown(keyCode, event);
}
}
Your design has a big problem : ...
If there is no central server some android devices should act as client and others as server but this will not work in some situations:
When the mobile telephony provider assigns private and non-public IP
When the device is connected to a Wi-Fi network but no NAT rule is defined on the router.
In both cases the problem is that the listening port of the device that must act as server is unreachable.
Java provides ServerSocket and Socket to communicate b/w devices. One of the device you can make as server and other device you can make as client and communicate b/w 'em without introducing server hosted on some machine.
The Other and better option is Using Wi-Fi Peer-to-Peer. WifiP2pManager help you to achieve your purpose.Here is an example.
If you're looking for such P2P over a local network, there are two parts to it:
Discovering peers
Communicating with peers
Among Android APIs, you can either use Network Service Discovery APIs for this or Wifi P2P Service Discovery APIs.
There's a wrapper library which which uses these internally and has comparatively better documentation - Salut, which can also be used.
I also created a library for P2P - Near, which uses sockets directly. The problem I was facing with Android APIs was that discovery wasn't happening with certainty every time and the underlying issue was unknown.
If you're looking for P2P across the internet, socket IO is a prevalent solution. Even Near should be able to facilitate the transfers if you provide the IP addresses and they're not behind NAT firewalls.
What could be the problem with Apache MINA if it won't call messageSent() method after writing to active session? My code works perfectly in simple Java client but doesn't work in Android application.
TCPClient's code:
if (session != null && session.isConnected()) {
throw new IllegalStateException("Already connected. Disconnect first.");
}
connector = new NioSocketConnector();
connector.getSessionConfig().setUseReadOperation(true);
try {
SslFilter sslFilter = new SslFilter(ClientSslContextFactory.getInstance());
sslFilter.setUseClientMode(true);
connector.getFilterChain().addFirst("sslFilter", sslFilter);
handler = new TCPHandler();
connector.setHandler(handler);
connector.getSessionConfig().setReadBufferSize(4096);
// try to connect to server
Log.d(TAG, "Connecting...");
ConnectFuture future = connector.connect(new InetSocketAddress(Const.hostIP, Const.sessionPort));
future.addListener(new IoFutureListener<IoFuture>() {
public void operationComplete(IoFuture future) {
ConnectFuture connFuture = (ConnectFuture) future;
if(connFuture.isConnected()){
Log.d(TAG, "Assigning session...");
session = future.getSession();
} else {
Log.e(TAG, "Not connected...exiting");
}
}
});
future.awaitUninterruptibly();
} catch (RuntimeIoException e) {
Log.e(TAG, "Failed to connect.");
e.printStackTrace();
} catch (IllegalArgumentException e) {
Log.e(TAG, "Failed to connect. Illegal Argument! Terminating program!");
e.printStackTrace();
} catch (GeneralSecurityException e) {
Log.e(TAG, "Failed to set SSL filter!");
e.printStackTrace();
}
TCPHandler's sending code:
#Override
public void sessionOpened(IoSession session) throws Exception {
super.sessionOpened(session);
Log.d(TAG, "Session opened...");
byte[] ba = ("stringasdfasdf\n").getBytes();
IoBuffer buffer = IoBuffer.allocate(ba.length);
buffer.put(ba);
buffer.flip();
session.write(buffer);
Log.d(TAG, "TCP writing executed.");
}
I have the same issue and notice that it is important:
#Override
public void sessionCreated(IoSession session) throws Exception {
Log.d(TAG, "sessionCreated");
session.setAttribute(SslFilter.USE_NOTIFICATION);
}
Once session.setAttribute(SslFilter.USE_NOTIFICATION) is added. It works.
connector.connect can not run in the main thread in Android. Are you sure the session is open?
I'm trying to use the native Android SIP stack to make direct SIP calls within a LAN. It appears that within the native stack, you are required to register a local profile in order to make SIP calls.
Here is the code I (try to) use to register a profile. I do not have a SIP server on this network, so I just use localhost for a domain.
if (mSipManager == null) {
mSipManager = SipManager.newInstance(mContext);
try {
SipProfile.Builder builder = new SipProfile.Builder("foo", "localhost");
builder.setPassword("bar");
mSipProfile = builder.build();
mSipManager.register(mSipProfile, 30000, new SipRegistrationListener() {
public void onRegistering(String localProfileUri) {
Log.v(TAG, "Registering with profile with SIP Server. URI: " + localProfileUri);
}
public void onRegistrationDone(String localProfileUri, long expiryTime) {
Log.v(TAG, "Registered with profile with SIP Server. URI: " + localProfileUri);
}
public void onRegistrationFailed(String localProfileUri, int errorCode,
String errorMessage) {
Log.e(TAG, "Registration failed. Code: " + Integer.toString(errorCode));
Log.e(TAG, errorMessage);
}
});
} catch (ParseException e) {
Log.e(TAG, "Unable to set up local SipProfile.", e);
} catch (SipException e) {
Log.e(TAG, "Unable to open local SipProfile.", e);
}
}
Elsewhere, here is my code for making a call:
try {
Log.v(TAG, "VOIP Supported: " + SipManager.isVoipSupported(mActivity));
Log.v(TAG, "SIP API Supported: " + SipManager.isApiSupported(mActivity));
SipProfile.Builder builder = new SipProfile.Builder(mSipUri);
SipProfile remote = builder.build();
SipAudioCall.Listener listener = new SipAudioCall.Listener() {
#Override
public void onCalling(SipAudioCall call) {
Log.d(TAG, "SIP Call initiating...");
}
#Override
public void onCallEstablished(SipAudioCall call) {
Log.d(TAG, "SIP Call established.");
call.startAudio();
call.setSpeakerMode(true);
call.toggleMute();
}
#Override
public void onCallEnded(SipAudioCall call) {
Log.d(TAG, "SIP Call ended.");
}
#Override
public void onError(SipAudioCall call, int errorCode, String errorMessage) {
Log.e(TAG, "SIP Call Error. Code: " + Integer.toString(errorCode));
Log.e(TAG, errorMessage);
}
};
mSipCall = mSipManager.makeAudioCall(mSipProfile, remote, listener, 10);
} catch (ParseException e) {
Log.e(TAG, "Unable to set up remote SipProfile.", e);
} catch (SipException e) {
Log.e(TAG, "SipAudioCall error.", e);
}
This all results in the following logcat output:
11-20 11:46:33.150 1412-1412/package.name E/XmlTest﹕ 1- Unable to open local SipProfile.
android.net.sip.SipException: SipService.createSession() returns null
at android.net.sip.SipManager.register(SipManager.java:481)
I'm unable to find further details as to why createSession is returning null; is it because I've not provided a valid server for the profile to register with? If so, is there a way to use the native SIP stack without registering with a server?
It turns out the problem is that Android's SIP stack appears to require the local SIP Profile you provide to the SIPManager (in the first codeblock above, represented by builder and mSipProfile) to have a valid IP address supplied to it.
Where I originally specified "localhost", you must actually provide the IP address of whatever interface you are making the SIP call over; if you are using a VPN, you must provide the IP of the VPN interface.
I am developing one app in which i have to print one receipt, receipt has one logo(static) image view, how can i print this to bluetooth printer? and also i have taken signature by using GestureOverlayView, now i have to print that gesture as well along with logo and some data regarding the receipt.
and i need to print one arabic string as well. which is shown in the TEXT VIEW.
for showing signature i am using image view in my layout. Please check the image,
i am attaching the image which i have to print, please give me some idea about printing it.
i can change the format in printing, means i dont have to print data in rectangles, but image alignment is the main issue, how will i get to know about alignment?
Try using this one....
public class BluetoothPrinterActivity extends Activity {
BluetoothAdapter mBTAdapter;
BluetoothSocket mBTSocket = null;
Dialog dialogProgress;
String BILL, TRANS_ID;
String PRINTER_MAC_ID = "00:1F:B7:02:8F:44";
final String ERROR_MESSAGE = "There has been an error in printing the bill.";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
BILL = "\nSale Slip No: 12345678" + " " + "04-08-2011\n";
BILL = BILL + "----------------------------------------";
BILL = BILL + "\n\n";
BILL = BILL + "Total Qty:" + " " + "2.0\n";
BILL = BILL + "Total Value:" + " " + "17625.0\n";
BILL = BILL + "-----------------------------------------";
mBTAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBTAdapter == null) {
Toast.makeText(this, "Device has no bluetooth capability",Toast.LENGTH_LONG).show();
finish();
} else {
if (!mBTAdapter.isEnabled()) {
Intent i = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(i, 0);
}
// Register the BroadcastReceiver
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, filter); // Don't forget to unregister during onDestroy
dialogProgress = new Dialog(BluetoothPrinterActivity.this);
dialogProgress.setTitle("Finding printer...");
dialogProgress.setOnDismissListener(new DialogInterface.OnDismissListener() {
public void onDismiss(DialogInterface dialog) {
dialog.dismiss();
setResult(RESULT_CANCELED);
finish();
}
});
dialogProgress.show();
}
if (mBTAdapter.isDiscovering())
mBTAdapter.cancelDiscovery();
else
mBTAdapter.startDiscovery();
System.out.println("BT Searching status :" + mBTAdapter.isDiscovering());
} catch (Exception e) {
Log.e("Class ", "My Exe ", e);
}
}
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
try {
String action = intent.getAction();
// When discovery finds a device
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
System.out.println("***" + device.getName() + " : "+ device.getAddress());
if (device.getAddress().equalsIgnoreCase(PRINTER_MAC_ID)) {
mBTAdapter.cancelDiscovery();
dialogProgress.dismiss();
Toast.makeText(BluetoothPrinterActivity.this,device.getName() + " Printing data",Toast.LENGTH_LONG).show();
printBillToDevice(PRINTER_MAC_ID);
Toast.makeText(BluetoothPrinterActivity.this,device.getName() + " found", Toast.LENGTH_LONG).show();
}
}
} catch (Exception e) {
Log.e("Class ", "My Exe ", e);
}
}
};
#Override
protected void onDestroy() {
super.onDestroy();
try {
if (dialogProgress != null)
dialogProgress.dismiss();
if (mBTAdapter != null)
mBTAdapter.cancelDiscovery();
this.unregisterReceiver(mReceiver);
} catch (Exception e) {
Log.e("Class ", "My Exe ", e);
}
}
#Override
public void onBackPressed() {
try {
if (mBTAdapter != null)
mBTAdapter.cancelDiscovery();
this.unregisterReceiver(mReceiver);
} catch (Exception e) {
Log.e("Class ", "My Exe ", e);
}
setResult(RESULT_CANCELED);
finish();
}
public void printBillToDevice(final String address) {
new Thread(new Runnable() {
public void run() {
runOnUiThread(new Runnable() {
public void run() {
dialogProgress.setTitle("Connecting...");
dialogProgress.show();
}
});
mBTAdapter.cancelDiscovery();
try {
System.out.println("**************************#****connecting");
BluetoothDevice mdevice = mBTAdapter.getRemoteDevice(address);
Method m = mdevice.getClass().getMethod("createRfcommSocket", new Class[] { int.class });
mBTSocket = (BluetoothSocket) m.invoke(mdevice, 1);
mBTSocket.connect();
OutputStream os = mBTSocket.getOutputStream();
os.flush();
os.write(BILL.getBytes());
System.out.println(BILL);
setResult(RESULT_OK);
finish();
} catch (Exception e) {
Log.e("Class ", "My Exe ", e);
e.printStackTrace();
setResult(RESULT_CANCELED);
finish();
}
runOnUiThread(new Runnable() {
public void run() {
try {
dialogProgress.dismiss();
} catch (Exception e) {
Log.e("Class ", "My Exe ", e);
}
}
});
}
}).start();
}
}
from this link Bluetooth Printer issue in android
I try my best to give the answer before that you can get the solution from already asked questions
you have 3 options for printing from android app
1>SDKs/Libraries: (like starmicronics, it's limited to few devices)
2>Google Play Apps: (directly calling the intent to thirparty apps)
3>Google cloud print: (recommended. It's easy to use and integrate into an app)
By this we connect any printers like Classic printers, Cloud Print printers.
for using Google print as user perspective user should activate google print service to gmail account, Google cloud print used in many places!
Setting up the google print service:
Blog
https://stackoverflow.com/questions/11323805/how-to-setup-network-printer-to-google-cloud-print/14911180#14911180
Google cloud print set up1
Google cloud print set up2
Printing via gchrome
Google cloud printers
Integrating Cloud printers to App:
In Android there no option for Airprint like other platforms, but Google made awesome cloud printing option for that such that any printer can use the print option from mobile devices.
Sample codes:
funcode
Google cloud print code