android emulator memory options stop my app from running - java

I seem to be having major problems with my eclipse emulator and don't know if it's the ram size or my code. In my opinion, my code should run, as it does so in my java netbeans project.
Everytime I run my application and push the connect button, I want to get the string that the server sends back and then do something with it. I have a "Process Connection" method that reads in the string, but when I return it and actually use what is being returned, my emulator crashes
My code is as follows:
package za.nmmu.wrap302.networks.example02;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.util.ArrayList;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnKeyListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;
public class MainActivity extends Activity {
private ListView lstMessages;
private EditText txtMessage;
private ArrayList<String> messages;
private ArrayAdapter<String> adapter;
String message = "";
private ServerConnection connection;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// get references to View objects
txtMessage = (EditText) findViewById(R.id.txtMessage);
lstMessages = (ListView) findViewById(R.id.lstMessages);
// set up adapter
messages = new ArrayList<String>();
adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, messages);
lstMessages.setAdapter(adapter);
// attach event listener
txtMessage.setOnKeyListener(new OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_ENTER)
&& (event.getAction() == KeyEvent.ACTION_DOWN)) {
try {
onTxtMessageEnterPressed();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return true;
}
return false;
}
});
}
public void onBtnConnectClicked(View view) {
clearMessages();
connection = new ServerConnection();
connection.start();
}
public void onTxtMessageEnterPressed() throws IOException {
if (connection != null) {
String message = txtMessage.getText().toString();
txtMessage.getText().clear();
connection.sendData(message);
}
}
public void addMessage(String message) {
adapter.add(message);
}
public void clearMessages() {
adapter.clear();
}
// the thread that will be communicating with the server
public class ServerConnection extends Thread {
// the I/O streams that will be receiving/sending data from/to the
// server
private ObjectOutputStream output;
private ObjectInputStream input;
private Socket client;
#Override
public void run() {
try {
// Step 1: Create a Socket to make connection
connectToServer();
// Step 2: Get the input and output streams
getStreams();
// Step 3: Process connection
processConnection();
// Step 4: Close connection
//closeConnection();
} catch (IOException e) {
Log.e("CONNECTION", e.getMessage());
}
}
public void addMessage(final String message) {
runOnUiThread(new Runnable() {
#Override
public void run() {
MainActivity.this.addMessage(message);
}
});
}
private void connectToServer() throws IOException {
addMessage("Attempting connection\n");
client = new Socket("10.0.0.7", 5001);
addMessage("Connected to: " + client.getInetAddress().getHostName());
}
private void getStreams() throws IOException {
output = new ObjectOutputStream(client.getOutputStream());
output.flush();
input = new ObjectInputStream(client.getInputStream());
addMessage("Got I/O streams");
}
//I would like to call the message below and return it to anywhere else in the code
private String processConnection() throws IOException
{
do {
try {
message = (String) input.readObject();
addMessage(message);
return message;
}
catch (ClassNotFoundException classNotFoundException)
{
addMessage("ERROR: Unknown object type received");
}
return message;
} while (!message.equals("SERVER>>> TERMINATE"));
}
private void sendData(String message) {
try {
output.writeObject(message);
output.flush();
addMessage("CLIENT>>>" + message);
} catch (IOException ioException) {
addMessage("ERROR: Error writing object");
}
}
private void closeConnection() throws IOException {
addMessage("Closing connection");
output.close();
input.close();
client.close();
}
}
}
My application seems to just crash whenever I call the processConnection method from anywhere.
My server picks up that I've sent the message, but my client doesn't read.
http://i.stack.imgur.com/cNu7m.png
My logcat shows:
06-13 08:18:00.460: D/dalvikvm(1145): GC_FOR_ALLOC freed 45K, 4% free 3076K/3204K, paused 293ms, total 296ms
06-13 08:18:00.460: I/dalvikvm-heap(1145): Grow heap (frag case) to 3.687MB for 635812-byte allocation
06-13 08:18:00.530: D/dalvikvm(1145): GC_FOR_ALLOC freed 1K, 4% free 3695K/3828K, paused 55ms, total 55ms
06-13 08:18:02.220: I/Choreographer(1145): Skipped 172 frames! The application may be doing too much work on its main thread.
06-13 08:18:02.240: D/gralloc_goldfish(1145): Emulator without GPU emulation detected.
06-13 08:18:03.100: I/Choreographer(1145): Skipped 198 frames! The application may be doing too much work on its main thread.
06-13 08:18:27.660: E/InputEventSender(1145): Exception dispatching finished signal.
06-13 08:18:27.660: E/MessageQueue-JNI(1145): Exception in MessageQueue callback: handleReceiveCallback
Does the ram in the emulator affect this? What am I doing wrong?

You need to use Async task to spawn off uploading to a different thread. Android works on a single thread model and using the same thread to make HTTPRequest can result in FATAL exception. Create an Async task and spawn off the upload to it.
AsyncTaskRunner runner = new AsyncTaskRunner();
runner.execute(<pass the required parameters here for file upload>);
private class AsyncTaskRunner extends AsyncTask<String, String, String> {
#Override
protected String doInBackground(String... params) {
//Call the function to upload the file here
}
This is what the logcat is telling you by Main thread is doing too many tasks.

Related

UDP Server android application wont upload to phone

I have built a upd server listen code to upload on my phone and listen to data packets. This code will compile but for some reason it wont load to my phone. I don't see any errors anywhere. Why could this be ? this is my whole Mainactivity code :
package roman10.tutorial.udpcommserver;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.net.InetSocketAddress;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
public class UdpServer extends Activity {
/** Called when the activity is first created. */
private TextView textView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
textView = (TextView) findViewById(R.id.text1);
runUdpServer();
}
private static final int UDP_SERVER_PORT = 4000;
private static final int MAX_UDP_DATAGRAM_LEN = 1500;
private static final String ipAdd = new String("172.30.42.80");
private void runUdpServer() {
String lText;
// byte[] lMsg = new byte[MAX_UDP_DATAGRAM_LEN];
// DatagramPacket dp = new DatagramPacket(lMsg, lMsg.length);
// DatagramSocket ds = null;
byte buffer[] = new byte[MAX_UDP_DATAGRAM_LEN];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
try {
// ds = new DatagramSocket(UDP_SERVER_PORT);
// //disable timeout for testing
// //ds.setSoTimeout(100000);
// ds.receive(dp);
//lText = new String(lMsg, 0, dp.getLength());
// Log.i("UDP packet received", lText);
// textView.setText(lText);
DatagramSocket s = new DatagramSocket();
InetSocketAddress address = new InetSocketAddress(ipAdd, UDP_SERVER_PORT);
s.bind(address);
lText = new String(buffer,0,packet.getLength());
Log.i("UDP packet received", lText);
textView.setText(lText);
System.out.println("Waiting...");
s.receive(packet);
if (s != null) {
s.close();
}
// s.close();
System.out.println("Received!");
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
System.out.print("we are done ");
}
}
}
1)
You are not returning from your onCreate (until you have received something). The activity can't continue to start (certainly not call onStart, onResume etc.
2)
Then you are doing I/O on the main thread, network I/O even, not recommended and usually detected as not allowed on android and force closed. You will get a NetworkOnMainThreadException
Fortunately both those issues can be solved by creating a separate thread and executing runUdpServer() there.
Short example, instead of:
runUdpServer();
do:
Thread thread = new Thread() {
public void run() {
runUdpServer();
}
};
thread.start();

Trigger AsyncTask from listener - AndroidStudio 1.2.2 - java.lang.NoClassDefFound

I have this interface on my Android project:
package com.kkoci.shairlook;
/**
* Created by kristian on 07/07/2015.
*/
public interface OnTaskFinishListener{
void onFinish();
}
I'm using this, to call a onPostExecute on my AsyncTask class:
package com.kkoci.shairlook;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.Toast;
import com.appspot.shairlook1.userEndpoint.UserEndpoint;
import com.appspot.shairlook1.userEndpoint.model.User;
import com.google.api.client.extensions.android.http.AndroidHttp;
import com.google.api.client.extensions.android.json.AndroidJsonFactory;
import com.google.api.client.googleapis.services.AbstractGoogleClientRequest;
import com.google.api.client.googleapis.services.GoogleClientRequestInitializer;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
/**
* Created by kristian on 04/07/2015.
*/
public class EndpointsAsyncTaskInsert extends AsyncTask<String, Void, User> implements GoogleClientRequestInitializer {
private static UserEndpoint myApiService = null;
private Context context;
private OnTaskFinishListener listener;
EndpointsAsyncTaskInsert(Context context) {
this.context = context;
}
public EndpointsAsyncTaskInsert(OnTaskFinishListener listener){
this.listener = listener;
}
#Override
public void initialize(AbstractGoogleClientRequest<?> abstractGoogleClientRequest) throws IOException {
// put it here no in MyClass
abstractGoogleClientRequest.setDisableGZipContent(true);
}
#Override
protected User doInBackground(String... params) {
User response = null;
if (myApiService == null) { // Only do this once
UserEndpoint.Builder builder = new UserEndpoint.Builder(AndroidHttp.newCompatibleTransport(),
new AndroidJsonFactory(), null)
// options for running against local devappserver
// - 10.0.2.2 is localhost's IP address in Android emulator
// - turn off compression when running against local devappserver
.setRootUrl("https://shairlook1.appspot.com/_ah/api/")
.setGoogleClientRequestInitializer(this);
// end options for devappserver
myApiService = builder.build();
}
try {
User users = new User();
users.setEmail(params[0]);
users.setPassword(params[1]);
users.setName(params[2]);
response = myApiService.insertUser(users).execute();
} catch (Exception e) {
Log.d("Could not Add User", e.getMessage(), e);
}
return response;
}
protected void onPostExecute(User user){
listener.onFinish();
}
}
But this is giving me java.lang.NoCalssDefFound error, I'm initializing it in my Activity like this:
public class LoginMember extends Activity implements OnTaskFinishListener {
public void onFinish(){
Intent intent = new Intent(LoginMember.this, WelcomeScreen.class);
startActivity(intent);
}
Then execute:
btnLogin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(txtEmail.getWindowToken(), 0);
imm.hideSoftInputFromWindow(txtPassword.getWindowToken(), 0);
String password = txtPassword.getText().toString();
String email = txtEmail.getText().toString();
if ((txtEmail.length() == 0) || (txtPassword.length() == 0)) {
Toast.makeText(LoginMember.this, "You need to provide values for Email and Password", Toast.LENGTH_SHORT).show();
return;
}
//Go ahead and perform the transaction
String[] params = {email, password};
new EndpointsAsyncTaskInsert(currentActivity.getApplicationContext()).execute(params);
}
});
So, the problem arises when executing EndpointAsyncTaskInsert method listener.OnFinish();
This is the complete logcat:
7752-7752/com.kkoci.shairlook E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.NullPointerException
at com.kkoci.shairlook.EndpointsAsyncTaskInsert.onPostExecute(EndpointsAsyncTaskInsert.java:74)
at com.kkoci.shairlook.EndpointsAsyncTaskInsert.onPostExecute(EndpointsAsyncTaskInsert.java:24)
at android.os.AsyncTask.finish(AsyncTask.java:631)
at android.os.AsyncTask.access$600(AsyncTask.java:177)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:175)
at android.app.ActivityThread.main(ActivityThread.java:5279)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
at dalvik.system.NativeStart.main(Native Method)
I've seen this question here, seems to be the same kind of problem, but I'm not really sure about that solution.
Any ideas, please?
Thanks in advance!
The logs say the error is java.lang.NullPointerException... and it's because you're creating a EndpointsAsyncTaskInsert using the Context constructor, thus listener inside of it null... and you dereference it without checking for null in onPostExecute

AsyncTask and socket not working in android java

I'm making a simple app client-server in java, i want my phone to receive and send messages to my pc, i'm on same LAN and my pc's ip is 192.168.1.8, my serverSocket is running on port 7777.
for some reason my client android cant connect i think it is because i created a socket in a thread, i have read that i should use AsyncTask or Handle, i tried with that too but i get an exception too.
Class server:
public class MyServer implements Runnable{
private ServerSocket server;
private ObjectInputStream in;
private ObjectOutputStream out;
private Socket clientedConnected;
public ExampleServerZNuC(){
try {
server= new ServerSocket(7777);
System.out.println("server opened on port 7777");
} catch (IOException ex) {
Logger.getLogger(MyServer.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void sendMessage(String message){
try {
out.writeObject(message);
out.flush();
} catch (IOException ex) {
Logger.getLogger(MyServer.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void sendNotifiy(){
try {
out.writeObject("Send Notify");
out.flush();
} catch (IOException ex) {
Logger.getLogger(MyServer.class.getName()).log(Level.SEVERE, null, ex);
}
}
public String getMessage(){
return "";
}
public void run(){
System.out.println("method run started");
System.out.println("Waiting for a client to connect");
try {
Socket clientedConnected;
clientedConnected = server.accept();
System.out.println("A client connected : "+clientedConnected.getInetAddress().getHostAddress());
in= new ObjectInputStream(clientedConnected.getInputStream());
out = new ObjectOutputStream(clientedConnected.getOutputStream());
} catch (IOException ex) {
Logger.getLogger(MyServer.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("End of method Run");
} }
this is the output i get when i create run the server:
server opened on port 7777
method run started
Waiting for a client to connect
client android:
class to connect to my server( atm i just want it to receive the message):
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OptionalDataException;
import java.net.Socket;
import java.net.UnknownHostException;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
public class MyConnect implements Runnable{
private Socket myconnect=null ;
private TextView txtMessage;
private ObjectInputStream in;
private ObjectOutputStream out;
public MyConnect( ){
try {
// this is my pc's IP, my phone is connected to same LAN
Log.d("inizializating socket","");
myconnect= new Socket("192.168.1.8",7777);
in = new ObjectInputStream(myconnect.getInputStream());
out = new ObjectOutputStream(myconnect.getOutputStream());
} catch (UnknownHostException e) {
Log.d("My Error connecting",e.getMessage());
} catch (IOException e) {
Log.d("My Error connecting",e.getMessage());
}
}
#Override
public void run() {
try {
String message = (String)in.readObject();
Log.d("messaged recived",message);
} catch (OptionalDataException e) {
Log.d("My Error connecting",e.getMessage());
} catch (ClassNotFoundException e) {
Log.d("Error My ClassNotFoundException",e.getMessage());
} catch (IOException e) {
Log.d("Error My IOEXCEPTION",e.getMessage());
}
}
}
this is the error that i get when i click on a button that should create the socket:
on create i use connect= new MyConnect();
and on onclick event i use:
#Override
public void onClick(View v) {
switch(v.getId()){
case R.id.btnExample:
new Thread(connect).start();
break;
}
}
error message :
05-29 19:02:05.905: E/AndroidRuntime(6520): FATAL EXCEPTION: main
05-29 19:02:05.905: E/AndroidRuntime(6520): android.os.NetworkOnMainThreadException
05-29 19:02:05.905: E/AndroidRuntime(6520): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1118)
05-29 19:02:05.905: E/AndroidRuntime(6520): at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:84)
05-29 19:02:05.905: E/AndroidRuntime(6520): at libcore.io.IoBridge.connectErrno(IoBridge.java:127)
05-29 19:02:05.905: E/AndroidRuntime(6520): at libcore.io.IoBridge.connect(IoBridge.java:112)
05-29 19:02:05.905: E/AndroidRuntime(6520): at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
05-29 19:02:05.905: E/AndroidRuntime(6520): at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
05-29 19:02:05.905: E/AndroidRuntime(6520): at java.net.Socket.startupSocket(Socket.java:566)
05-29 19:02:05.905: E/AndroidRuntime(6520): at java.net.Socket.tryAllAddresses(Socket.java:127)
EDIT:
class MySyncTask extends AsyncTask<Integer, Integer, String>{
String advice;
#Override
protected String doInBackground(Integer... params) {
try {
s = new Socket("192.168.1.8",7777);
Log.d("socket connected","");
ObjectInputStream streamReader = new ObjectInputStream(s.getInputStream());
advice = (String)streamReader.readObject();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "";
}
protected void onPostExecute(String result) {
txtMessage.setText("you got a message: " + advice);
}
protected void onPreExecute() {
Log.d("my started","start");
}
}
and i used
MySyncTask asyncTask=new MySyncTask ();
asyncTask.execute();
on onCreate() method but for some reason it is not connecting to my server
LogCat with AsyncTask:
05-29 19:46:21.900: D/my started(26169): start
05-29 19:46:22.020: D/libEGL(26169): loaded /system/lib/egl/l ibEGL_mali.so
05-29 19:46:22.030: D/libEGL(26169): loaded /system/lib/egl/libGLESv1_CM_mali.so
05-29 19:46:22.040: D/libEGL(26169): loaded /system/lib/egl/libGLESv2_mali.so
05-29 19:46:22.080: D/OpenGLRenderer(26169): Enabling debug mode 0
EDIT PROBLEM SOLVED
after searching on internet why socket was not connecting i found someone who had a similar problem and i found the answer here Android Socket not being instantiated
i had to initializate the socket first and then use connect
This is happening because you are trying to perform a networking operation on the main thread. This is bad design, you do not want to lock up the user interface while you run a process that can take long time to execute.
Put your network method in an AsyncTask or Service.
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
// Escape early if cancel() is called
if (isCancelled()) break;
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}
Like Eduardo points out,
NetworkOnMainThreadException
The exception that is thrown when an application attempts to perform a
networking operation on its main thread.
Use Asynctask for your connection
Be sure to have
<uses-permission android:name="android.permission.INTERNET" />
into your AndroidManifest.xml
Have you set the proper permissions in the manifest? If yes, is the phone on the same network as your PC (if they are on same wifi network is good)? Try running through debugger and putting a break point.
Here is a nice tutorial that explains client/server communication in android.
http://examples.javacodegeeks.com/android/core/socket-core/android-socket-example/
Good luck
-Raghu

Application stopped unexpectedly: Fatal Exception

could anyone help my with my app code. I tryied to make an application that could send data (number or letter) to arduino through bluetooth. This is how my JAVA code look:
package com.example.btprojektas;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Set;
import java.util.UUID;
public class MainActivity extends Activity{
private static final String TAG = "btprojektas";
Button btnON, btnOFF;
BluetoothAdapter bluetoothAdapter = null;
BluetoothDevice device = null;
OutputStream outputStream = null;
BluetoothSocket socket = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
btnON = (Button) findViewById(R.id.btnON);
btnOFF = (Button) findViewById(R.id.btnOFF);
if(!bluetoothAdapter.isEnabled()){
Intent enableBluetooth = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBluetooth, 0);
}
loadPairedDevice();
connectBT();
btnON.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
sendData("0");
Toast.makeText(getBaseContext(), "Turn on LED", Toast.LENGTH_SHORT).show();
}
});
btnOFF.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
sendData("1");
Toast.makeText(getBaseContext(), "Turn off LED", Toast.LENGTH_SHORT).show();
}
});
}
private void connectBT() {
if (device != null) {
UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb"); //Standard SerialPortService ID
try {
socket = device.createRfcommSocketToServiceRecord(uuid);
socket.connect();
outputStream = socket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void disconnect() {
try {
if (outputStream != null) outputStream.close();
if (socket != null) socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private void loadPairedDevice() {
Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
Log.d(TAG, "Device found");
for (BluetoothDevice device : pairedDevices)
if (device.getName().equals("HC-06")) {
this.device = device;
break;
}
}
}
#Override
protected void onPause() {
super.onPause();
disconnect();
}
#Override
protected void onResume() {
super.onResume();
loadPairedDevice();
connectBT();
}
private void sendData(String message) {
byte[] buffer = message.getBytes();
Log.d(TAG,"Send data:"+ message);
try{
outputStream.write (buffer);
} catch (IOException e) {}
}
}
in XML I have two buttons. When the program starts I push one of those buttons and the "Applications ... stopped unexpectedly" appears with fatal exeption fault code:
01-08 15:55:15.439 15354-15354/com.example.btprojektas E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.NullPointerException
at com.example.btprojektas.MainActivity.sendData(MainActivity.java:122)
at com.example.btprojektas.MainActivity.access$000(MainActivity.java:22)
at com.example.btprojektas.MainActivity$1.onClick(MainActivity.java:55)
at android.view.View.performClick(View.java:2485)
at android.view.View$PerformClick.run(View.java:9080)
at android.os.Handler.handleCallback(Handler.java:587)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3687)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
at dalvik.system.NativeStart.main(Native Method)
P.S. Sorry for this question I know that it is quite common but I am new at programming especially JAVA.
It's either the socket or the outputStream. In ConnectBT, you don't check if socket is not null. You directly call socket.connect() assuming socket is valid. The same applies to outputStream. You use it before making sure it's not null.
Also you call
startActivityForResult(enableBluetooth, 0);
but you don't check for the result which is whether bluetooth got enabled or not. This makes your device also suspicious.
Calling
loadPairedDevice();
connectBT();
makes sense only when bluetooth is enabled. Enabling bluetooth can take couple of seconds, but you call them right away.
A couple of tips:
you're calling loadPairedDevice() and connectBT() twice: in onCreate() and in onResume() - do it only once
before using outputStream, check if it's not null (as advised by others)
in sendData(), catch AND print your exception:
try {
if (outputStream != null) {
outputStream.write(buffer);
}
else {
Log.d("TAG", "sendData() - outputStream is null!");
}
}
catch (IOException e) {
e.printStackTrace();
}
in loadPairedDevice(), if you don't find the device "HC-06", your variable device will be null...
enabling bluetooth takes few seconds, so register and listen to ACTION_STATE_CHANGED broadcast Intent. It will contain extra field EXTRA_STATE; look for STATE_ON, and then call your loadPairedDevices() and connectBT() there:
create receiver (inside your MainActivity class):
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
//this is the action you are observing
if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
switch(state) {
//and the state we were looking for
//which means that bluetooth has switched on
//so now you can call your functions
//and set the flag to true, which then use in your
//onClick listeners
case BluetoothAdapter.STATE_ON:
loadPairedDevice();
connectBT();
isBluetoothOn = true;
break;
}
}
}
}
in onCreate(), create IntentFilter and register receiver with it
IntentFilter btFilter = new IntentFilter();
btFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
registerReceiver(mReceiver, btFilter);
remember to unregister receiver in onPause():
unregisterReceiver(mReceiver);
disable your buttons and enable them in the above listener, when you know BT is switched on; alternatively, keep a flag and use it in your click listeners, eg.:
boolean isBluetoothOn = false;
then later in listener when you get STATE_ON
isBluetooth = true;
And in your button click listener:
//for btnON
public void onClick(View v) {
if (isBluetoothOn) {
sendData("0");
Toast.makeText(getBaseContext(), "Turn on LED", Toast.LENGTH_SHORT).show();
}
}
Do the same for btnOFF.

Bluetooth Sends Sensor Data Only once

So for my research, I have to send accelometer data to an arduino mega as a constant stream. I have the module connected to the arduino via serial. However, when I ran the code, it only runs once. I tried to place the Bluetooth connect part of the code inside my on accuracy change part of my code, but it keeps freezing the device. Here's my code:
package com.example.arduino_bluetooth2;
//=================================================================================================
//Imports
//=================================================================================================
import java.io.IOException;
import java.io.OutputStream;
import java.util.Set;
import java.util.UUID;
import android.os.Bundle;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.view.Menu;
import android.widget.TextView;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
public class MainActivity extends Activity implements SensorEventListener {
// Setup necessary sensor objects
private Sensor acc;
private SensorManager sm;
private TextView t1;
private double value;
// Bluetooth Object
private BluetoothAdapter bAdapter;
private BluetoothDevice device;
private BluetoothSocket mmServerSocket;
private OutputStream btoutput;
private static final UUID SPP_UUID = UUID
.fromString("00001101-0000-1000-8000-00805F9B34FB");
private static final int DISCOVERY_REQUEST = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
accelerometer_initialization();
bluetooth_initialization();
}
// Setsup the accelerometer object
private void accelerometer_initialization() {
sm = (SensorManager) getSystemService(SENSOR_SERVICE);
acc = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
sm.registerListener(this, acc, SensorManager.SENSOR_DELAY_NORMAL);
}
// Setup bluetooth object
private void bluetooth_initialization() {
bAdapter = BluetoothAdapter.getDefaultAdapter();
startActivityForResult(new Intent(
BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE),
DISCOVERY_REQUEST);
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, filter);
bAdapter.startDiscovery();
}
#Override
public void onSensorChanged(SensorEvent event) {
value = event.values[0];
}
#Override
public void onAccuracyChanged(Sensor arg0, int arg1) {
}
final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
if (BluetoothDevice.ACTION_FOUND.equals(intent.getAction())) {
device = intent
.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (new String(device.getName()).equals("BT UART")) {
bAdapter.cancelDiscovery();
try {
BluetoothSocket test = null;
test = device
.createInsecureRfcommSocketToServiceRecord(SPP_UUID);
mmServerSocket = test;
mmServerSocket.connect();
String message = Double.toString(value);
byte[] send = message.getBytes();
btoutput = mmServerSocket.getOutputStream();
btoutput.write(send);
btoutput.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
};
};
}
I am not sure you should creating and connecting the bluetooth socket in the broadcast receiver. I do the bluetooth connection management in the onResume() of the activity.
Also I use a thread to manage getting data from the serial data connection between the arduino and the device, it is spawned off and runs continuously in the background. There is a write method to send data out that i call from the activity
/* Call this from the main activity to send data to the remote device */
public void write(String message) {
System.out.println("...Data to send: " + message + "...");
byte[] msgBuffer = message.getBytes();
try {
mmOutStream.write(msgBuffer);
} catch (IOException e) {
System.out.println("...Error data send: " + e.getMessage() + "...");
}
}
then the run() method of the tread takes care of getting data back
See my answer in this thread for an example
Error with receiving xml strings via bluetooth in Android
Good luck!
Check out this page from arduino: http://arduino.cc/en/Reference/Loop
The problem is that it only goes once because it is not in a loop that continues forever until the device is shut off or told otherwise.

Categories

Resources