I am trying to build a small photo app with a burst mode for camera. The main idea is to shoot a picture every 0,3sec and to store the pictures in an Array until the last picture is taken. The number of pictures to shoot should specified.
I can only shoot a picture every 2sec. as shortest interval. Then, when the pictures should be written to storage, the applications chrashes.
Does someone know how to implement this? Here is my code:
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.View.OnClickListener;
public class CamaeaView extends Activity implements SurfaceHolder.Callback, OnClickListener {
static final int FOTO_MODE = 1;
private static final String TAG = "Test";
Camera mCamera;
boolean mPreviewRunning = false;
private Context mContext = this;
ArrayList<Object> listImage = null;
public static ArrayList<Object> List1[];
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
Log.e(TAG, "onCreate");
#SuppressWarnings("unused")
Bundle extras = getIntent().getExtras();
getWindow().setFormat(PixelFormat.TRANSLUCENT);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.main);
mSurfaceView = (SurfaceView) findViewById(R.id.surface_camera);
mSurfaceView.setOnClickListener(this);
mSurfaceHolder = mSurfaceView.getHolder();
mSurfaceHolder.addCallback(this);
mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
}
Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {
public void onPictureTaken(byte[] imageData, Camera c) {
Log.d("Start: ","Imagelist");
Intent mIntent = new Intent();
listImage.add(StoreByteImage(imageData));
SaveImage(listImage);
mCamera.startPreview();
setResult(FOTO_MODE, mIntent);
finish();
}
};
protected void onResume() {
Log.d(TAG, "onResume");
super.onResume();
}
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
protected void onStop() {
Log.e(TAG, "onStop");
super.onStop();
}
public void surfaceCreated(SurfaceHolder holder) {
Log.d(TAG, "surfaceCreated");
mCamera = Camera.open();
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
Log.d(TAG, "surfaceChanged");
// XXX stopPreview() will crash if preview is not running
if (mPreviewRunning) {
mCamera.stopPreview();
}
Camera.Parameters p = mCamera.getParameters();
p.setPreviewSize(w, h);
p.setPictureSize(1024, 768);
p.getSupportedPictureFormats();
p.setPictureFormat(PixelFormat.JPEG);
mCamera.setParameters(p);
try {
mCamera.setPreviewDisplay(holder);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mCamera.startPreview();
mPreviewRunning = true;
}
public void surfaceDestroyed(SurfaceHolder holder) {
Log.e(TAG, "surfaceDestroyed");
mCamera.stopPreview();
mPreviewRunning = false;
mCamera.release();
}
private SurfaceView mSurfaceView;
private SurfaceHolder mSurfaceHolder;
public void onClick(View arg0) {
int i = 0;
while (i < 4) {
mCamera.takePicture(null, mPictureCallback, mPictureCallback);
i = i + 1;
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static Object StoreByteImage(byte[] imageData) {
Object obj = null;
try {
ByteArrayInputStream bis = new ByteArrayInputStream(imageData);
ObjectInputStream objImageData = new ObjectInputStream(bis);
obj = objImageData.readObject();
} catch (IOException ex) {
// TODO: Handle the exception
} catch (ClassNotFoundException ex) {
// TODO: Handle the exception
}
return obj;
}
public static Object createImagesArray(byte[] imageData) {
Object obj = null;
try {
ByteArrayInputStream bis = new ByteArrayInputStream(imageData);
ObjectInputStream objImageData = new ObjectInputStream(bis);
obj = objImageData.readObject();
} catch (IOException ex) {
// TODO: Handle the exception
} catch (ClassNotFoundException ex) {
// TODO: Handle the exception
}
return obj;
}
public static boolean SaveImage(List<Object> listImage) {
FileOutputStream outStream = null;
Log.d("ListSize: ", Integer.toString(listImage.size()));
Iterator<Object> itList = listImage.iterator();
byte[] imageBytes = null;
while (itList.hasNext()) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(listImage);
oos.flush();
oos.close();
bos.close();
imageBytes = bos.toByteArray();
} catch (IOException ex) {
// TODO: Handle the exception
}
try {
// Write to SD Card
outStream = new FileOutputStream(String.format(
"/sdcard/DCIM/%d.jpg", System.currentTimeMillis())); // <9>
outStream.write(imageBytes);
outStream.close();
} catch (FileNotFoundException e) { // <10>
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
}
}
Log.d(TAG, "onPictureTaken - jpeg");
return true;
}
}
Error from the comments:
ERROR/MemoryHeapBase(1382): error opening /dev/pmem_camera: No such file or directory
ERROR/QualcommCameraHardware(1382): failed to construct master heap for pmem pool /dev/pmem_camera
ERROR/QualcommCameraHardware(1382): initRaw X failed with pmem_camera, trying with pmem_adsp
AFAIK, you cannot take another picture until the first one is complete. Eliminate your for loop and Thread.sleep(). Take the next picture in mPictureCallback.
The main idea is to shoot a picture every 0,3sec and to store the pictures in an Array until the last picture is taken.
The "0,3sec" objective is faster than most devices can process an image, and you may not have enough heap space for your array of images. I suspect that you will have to write each image out to disk as it comes in via an AsyncTask, so you can free up the heap space while also not tying up the main application thread.
You can try capturing subsequent preview frames in preallocated byte arrays.
See the following methods:
http://developer.android.com/reference/android/hardware/Camera.html#addCallbackBuffer(byte[])
http://developer.android.com/reference/android/hardware/Camera.html#setPreviewCallbackWithBuffer(android.hardware.Camera.PreviewCallback)
...or http://developer.android.com/reference/android/hardware/Camera.html#setOneShotPreviewCallback(android.hardware.Camera.PreviewCallback) for better control over timing.
Related
I'm trying to build an app which will periodically call the Camera to take a picture and save it.
My problem is that unless I put the 'takePictuce' call in the 'onCreate' the response to 'takePicture' (onPictureTaken) is never called.
I've broken down the app as simply as possible to illustrate.
if a class to handle the camera is partially defined as:
public class CameraHandler {
private Camera mCamera;
public CameraHandler(){
mCamera = Camera.open();
mCamera.setPreviewTexture(new SurfaceTexture(10));
mCamera.startPreview();
mCamera.takePicture(null, null, mPicture);
}
Camera.PictureCallback mPicture = new Camera.PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile();
if (pictureFile == null) {
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
} catch (IOException e) { }
}
};
Then when I put the following code into MainActivity.java, 'onPictureTaken' IS called when CameraHandler is instantiated.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
CameraHandler cameraHandler = new CameraHandler();
}
However, putting the call to instantiate CameraHandler in a click event in the MainActivity.java will NOT call 'onPictureTaken' in response to the takePicture call.
(This snippet is located in MainACtivity.java)
public void onClickListener(View view){
CameraHandler cameraHandler = new CameraHandler();
}
So why is this occurring, and how can I get the call to take a picture in the class where it belongs and not in the 'main' of the program?
All help welcome
Finally figured out how to set the phone to take timed pics without any screen display.
There were 2 main issues I struggled with. First, I wanted to take the pics without displaying to screen. Along those lines, I found an example where they used :
mCamera.setPreviewTexture(new SurfaceTexture(10));
and nothing showed on the screen when using this preview method. It appears that some sort of preview is required. Another method was to set the preview to 1 pixel. This method had examples online which appeared to work as well, but I did not try it.
The second and bigger problem had to do with 'onPictureTaken' method. This method processes your picture after the 'takePicture' call.
It seemed that no matter what looping method I used, or where in the code the call to 'takePicture' was located, all of the 'onPictureTaken' methods were queued up and called one after another once the parent of the 'takePicture' caller ended.
Although the picture data processed by onPictureTaken were in a proper time sequence, I could see that having several hundred pics stored and waiting to process could cause problems, and a method needed to be found where on pic was processed and stored before the next pic was taken.
Along those lines, I stumbled upon the AlarmManager and coupled that with the BroadcastReceiver and Future classes to solve the problem.
What I've done is set the alarmManger to go off at a set time or time frequency. The BroadcaseReceiver captures this call & in turn calls a method which creates
a thread where a 'Future' object makes the call to take a picture.
'Future' object is nice, because it will wait for the physical camera to take the picture (takePicture) and then process it (onPictureTaken). This all occurs in one thread, then terminates. So no queuing of pics to process and each picture sequence is handled separately.
Code is contained below. Note that some of the default 'Overrides' have been left out to save space. Also, the visible screen was basically a button which captured the click event...very basic.
MainActivity.java:
package myTest.com.test;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.SystemClock;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class MainActivity extends Activity {
CameraHandler cameraHandler;
public BroadcastReceiver br;
public PendingIntent pi;
public AlarmManager am;
final static private long LOOPTIME = 20000;
private static final ExecutorService threadpool = Executors.newFixedThreadPool(3);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setup();
}
private void setup() {
try{
cameraHandler = new CameraHandler();
br = new BroadcastReceiver() {
#Override
public void onReceive(Context c, Intent i) {
//Toast.makeText(c, "Taking a pic!", Toast.LENGTH_LONG).show();
TryAThread();
}
};
registerReceiver(br, new IntentFilter("com.timedActivity.activity") );
pi = PendingIntent.getBroadcast(this, 0, new Intent("com.timedActivity.activity"), 0);
am = (AlarmManager)(this.getSystemService( Context.ALARM_SERVICE ));
}
catch (Exception e){ }
}
private void TryAThread() {
try{
CameraCaller cameraCaller = new CameraCaller(cameraHandler);
Future future = threadpool.submit(cameraCaller);
while (!future.isDone()) {
try {
Thread.sleep(5000);
} catch (Exception ex) { }
}
}
catch (Exception e){ }
}
#Override
protected void onDestroy() {
am.cancel(pi);
unregisterReceiver(br);
super.onDestroy();
}
public void onClickListener(View view){
try{
am.setRepeating(am.ELAPSED_REALTIME,SystemClock.elapsedRealtime(), LOOPTIME, pi);
}
catch (Exception e){ }
}
}
CameraCaller.java:.
package myTest.com.test;
import java.util.concurrent.Callable;
public class CameraCaller implements Callable {
private CameraHandler cameraHandler;
public CameraCaller(CameraHandler ch){
cameraHandler = ch;
}
#Override
public Object call() throws Exception {
cameraHandler.takeAPic();
return true;
}
}
CameraHandler.java:.
package myTest.com.test;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.os.Environment;
import android.util.Log;
import junit.runner.Version;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class CameraHandler implements Camera.PictureCallback{
private Camera mCamera;
public CameraHandler(){
}
public Boolean takeAPic(){
try{
if (mCamera == null){
mCamera = Camera.open();
mCamera.enableShutterSound(false);
try {
mCamera.setPreviewTexture(new SurfaceTexture(10));
}
catch (IOException e1) {Log.e(Version.id(), e1.getMessage());
}
}
mCamera.startPreview();
mCamera.takePicture(null, null, this);
}
catch (Exception ex){ }
return true;
}
#Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile();
if (pictureFile == null) {
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
} catch (IOException e) { }
try {
Thread.sleep(2000);
}catch (Exception ex){}
}
public static File getOutputMediaFile() {
File file = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File mediaStorageDir = new File(file, "MyCameraApp");
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d("MyCameraApp", "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg");
return mediaFile;
}
}
As i am working on OBD Reader Demo .Through my app i am trying to connect obd reader device and my app is installed in Nexus 7.OBD Reader device is connecting to other apps which is available on google play but if i am connecting with my app it is getting error java.io.IOException: bt socket closed, read return: -1 after connection establish .Any suggestions...
=========================================================
**MainActivity:-**
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Set;
import java.util.UUID;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.virgosys.demo.commands.SpeedObdCommand;
import com.virgosys.demo.commands.engine.EngineRPMObdCommand;
import com.virgosys.demo.commands.fuel.FindFuelTypeObdCommand;
public class MainActivity extends Bluetooth {
#SuppressWarnings("unused")
private Button On, Off, Visible, list;
private BluetoothAdapter BA;
private Set<BluetoothDevice> pairedDevices;
#SuppressWarnings("unused")
private ListView lv;
private BluetoothDevice device;
// private UUID uuid;
// private BluetoothSocketWrapper bluetoothSocket;
private BluetoothSocket socket;
private String deviceAddress;
String RPM, Speed, FuelType;
private TextView uuidTextView, deviceTextView, showRpm, showSpeed,
showFuelType, tv_connection_e, tv_connection_f;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
showRpm = ((TextView) findViewById(R.id.show_rpm));
showSpeed = ((TextView) findViewById(R.id.txt_speed));
showFuelType = ((TextView) findViewById(R.id.txt_fueltype));
uuidTextView = ((TextView) findViewById(R.id.txt_uuid));
deviceTextView = ((TextView) findViewById(R.id.txt_device));
// tv_connection_e = ((TextView) findViewById(R.id.txt_device));
// tv_connection_f = ((TextView) findViewById(R.id.show_error));
On = (Button) findViewById(R.id.button1);
Off = (Button) findViewById(R.id.button2);
Visible = (Button) findViewById(R.id.button3);
list = (Button) findViewById(R.id.button4);
lv = (ListView) findViewById(R.id.listView1);
BA = BluetoothAdapter.getDefaultAdapter();
try {
Process process = Runtime.getRuntime().exec("logcat -d");
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
StringBuilder log = new StringBuilder();
String line = "";
while ((line = bufferedReader.readLine()) != null) {
log.append(line);
}
TextView tv_connection_e = (TextView) findViewById(R.id.show_error);
tv_connection_e.setText(log.toString());
} catch (IOException e) {
}
}
public void on(View view) {
if (!BA.isEnabled()) {
Intent turnOn = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(turnOn, 0);
Toast.makeText(getApplicationContext(), "Turned on",
Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(), "Already on",
Toast.LENGTH_LONG).show();
}
}
#SuppressWarnings("unchecked")
public void list(View view) {
ArrayList deviceStrs = new ArrayList();
final ArrayList devices = new ArrayList();
BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
pairedDevices = btAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
for (BluetoothDevice device : pairedDevices) {
deviceStrs.add(device.getName() + "\n" + device.getAddress());
devices.add(device.getAddress());
}
}
// show list
final AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
ArrayAdapter adapter = new ArrayAdapter(this,
android.R.layout.select_dialog_singlechoice,
deviceStrs.toArray(new String[deviceStrs.size()]));
alertDialog.setSingleChoiceItems(adapter, -1,
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
int position = ((AlertDialog) dialog).getListView()
.getCheckedItemPosition();
deviceAddress = (String) devices.get(position);
System.out.println("Device Address-->" + deviceAddress);
/*
* Intent i = new Intent(MainActivity.this,
* SecondActivity.class); i.putExtra("uuid",
* "00001101-0000-1000-8000-00805F9B34FB");
* i.putExtra("deviceAddress", deviceAddress);
* i.putExtra("RPM", RPM); i.putExtra("Speed", Speed);
* startActivity(i);
*/
try {
dothings();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// save deviceAddress
}
});
alertDialog.setTitle("Choose Bluetooth device");
alertDialog.show();
}
#SuppressLint("NewApi")
protected void dothings() throws InterruptedException {
System.out.println("Inside Do things");
System.out.println("Device address in Do things -->" + deviceAddress);
device = BA.getRemoteDevice(deviceAddress);
// UUID SERIAL_UUID = device.getUuids()[0].getUuid();
// uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
System.out.println("Device Name-->" + device.getName());
System.out.println("Device Address-->" + device.getAddress());
System.out.println("Device Bond State-->" + device.getBondState());
System.out.println("Device Type-->" + device.getType());
System.out.println("Device UUIDS-->" + device.getUuids());
ConnectThread t = new ConnectThread(device);
t.start();
showRpm.setText(RPM);
showSpeed.setText(Speed);
showFuelType.setText(FuelType);
uuidTextView.setText("00001101-0000-1000-8000-00805F9B34FB");
deviceTextView.setText(deviceAddress);
}
public void off(View view) {
BA.disable();
Toast.makeText(getApplicationContext(), "Turned off", Toast.LENGTH_LONG)
.show();
}
public void visible(View view) {
Intent getVisible = new Intent(
BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
startActivityForResult(getVisible, 0);
}
#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;
}
private class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
private final UUID WELL_KNOWN_UUID = UUID
.fromString("00001101-0000-1000-8000-00805f9b34fb");
private Object e;
public ConnectThread(BluetoothDevice device) {
// Use a temporary object that is later assigned to mmSocket,because
// mmSocket is final
BluetoothSocket tmp = null;
// Get a BluetoothSocket to connect with the given BluetoothDevice
try {
tmp = device.createRfcommSocketToServiceRecord(WELL_KNOWN_UUID);
// This is the trick
Method m = device.getClass().getMethod("createRfcommSocket",
new Class[] { int.class });
tmp = (BluetoothSocket) m.invoke(device, 1);
} catch (Exception e) {
e.printStackTrace();
}
mmSocket = tmp;
}
public void run() {
System.out.println("Trying to connect...");
// Cancel discovery because it will slow down the connection
BA.cancelDiscovery();
try {
// Connect the device through the socket. This will block
// until it succeeds or throws an exception
mmSocket.connect();
System.out.println("Connection established");
// tv_connection_e.setText(e.print.stacktrace);
ConnectedThread tc = new ConnectedThread(mmSocket);
tc.start();
} catch (IOException connectException) {
// Unable to connect; close the socket and get out
System.out.println("Fail to connect!");
try {
mmSocket.close();
} catch (IOException closeException) {
System.out.println("Fail to close connection");
}
return;
}
}
/** Will cancel an in-progress connection, and close the socket */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
}
}
}
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket) {
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
}
System.out.println("Inside the thread");
mmInStream = tmpIn;
mmOutStream = tmpOut;
try {
EngineRPMObdCommand engineRpmCommand = new EngineRPMObdCommand();
SpeedObdCommand speedCommand = new SpeedObdCommand();
FindFuelTypeObdCommand fueltypeCommand = new FindFuelTypeObdCommand();
System.out.println("Inside the try block");
while (!Thread.currentThread().isInterrupted()) {
System.out.println("Inside while");
// TODO handle commands result
Log.d("Poonam",
"RPM: " + engineRpmCommand.getFormattedResult());
Log.d("Poonam",
"Speed: " + speedCommand.getFormattedResult());
Log.d("Poonam",
"FuelType: " + fueltypeCommand.getFormattedResult());
RPM = engineRpmCommand.getFormattedResult();
Speed = speedCommand.getFormattedResult();
FuelType = fueltypeCommand.getFormattedResult();
try {
engineRpmCommand.run(mmInStream, mmOutStream);
speedCommand.run(mmInStream, mmOutStream);
fueltypeCommand.run(mmInStream, mmOutStream);
System.out.println("Commands Processed");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("outside try catch");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("inside catch before while");
}
// Get the input and output streams, using temp objects because
// member streams are final
}
public void run() {
byte[] buffer = new byte[1024]; // buffer store for the stream
int bytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs
while (true) {
}
}
/* Call this from the main activity to send data to the remote device */
public void write(byte[] bytes) {
try {
mmOutStream.write(bytes);
} catch (IOException e) {
}
}
/* Call this from the main activity to shutdown the connection */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
}
}
}
}
**Bluetooth.java**
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.util.Log;
public class Bluetooth extends Activity{
private BluetoothSocketWrapper bluetoothSocket;
private BluetoothDevice device;
private boolean secure;
private BluetoothAdapter adapter;
private List<UUID> uuidCandidates;
private int candidate;
/**
* #param device the device
* #param secure if connection should be done via a secure socket
* #param adapter the Android BT adapter
* #param uuidCandidates a list of UUIDs. if null or empty, the Serial PP id is used
* #return
*/
public void BluetoothConnector(BluetoothDevice device, boolean secure, BluetoothAdapter adapter,
List<UUID> uuidCandidates) {
this.device = device;
this.secure = secure;
this.adapter = adapter;
this.uuidCandidates = uuidCandidates;
if (this.uuidCandidates == null || this.uuidCandidates.isEmpty()) {
this.uuidCandidates = new ArrayList<UUID>();
this.uuidCandidates.add(UUID.fromString("00001101-0000-1000-8000-00805f9b34fb"));
}
}
public BluetoothSocketWrapper connect() throws IOException {
boolean success = false;
while (selectSocket()) {
adapter.cancelDiscovery();
try {
bluetoothSocket.connect();
success = true;
break;
} catch (IOException e) {
//try the fallback
try {
bluetoothSocket = new FallbackBluetoothSocket(bluetoothSocket.getUnderlyingSocket());
Thread.sleep(500);
bluetoothSocket.connect();
success = true;
break;
} catch (FallbackException e1) {
Log.w("BT", "Could not initialize FallbackBluetoothSocket classes.", e);
} catch (InterruptedException e1) {
Log.w("BT", e1.getMessage(), e1);
} catch (IOException e1) {
Log.w("BT", "Fallback failed. Cancelling.", e1);
}
}
}
if (!success) {
throw new IOException("Could not connect to device: "+ device.getAddress());
}
return bluetoothSocket;
}
private boolean selectSocket() throws IOException {
if (candidate >= uuidCandidates.size()) {
return false;
}
BluetoothSocket tmp = null;
UUID uuid = uuidCandidates.get(candidate++);
Log.i("BT", "Attempting to connect to Protocol: "+ uuid);
if (secure) {
Method m = null;
try {
m = device.getClass().getMethod("createRfcommSocket", new Class[] {int.class});
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
tmp = (BluetoothSocket) m.invoke(device, 1);
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
tmp = device.createInsecureRfcommSocketToServiceRecord(uuid);
}
bluetoothSocket = new NativeBluetoothSocket(tmp);
return true;
}
public static interface BluetoothSocketWrapper {
InputStream getInputStream() throws IOException;
OutputStream getOutputStream() throws IOException;
String getRemoteDeviceName();
void connect() throws IOException;
String getRemoteDeviceAddress();
void close() throws IOException;
BluetoothSocket getUnderlyingSocket();
}
public static class NativeBluetoothSocket implements BluetoothSocketWrapper {
private BluetoothSocket socket;
public NativeBluetoothSocket(BluetoothSocket tmp) {
this.socket = tmp;
}
#Override
public InputStream getInputStream() throws IOException {
return socket.getInputStream();
}
#Override
public OutputStream getOutputStream() throws IOException {
return socket.getOutputStream();
}
#Override
public String getRemoteDeviceName() {
return socket.getRemoteDevice().getName();
}
#Override
public void connect() throws IOException {
socket.connect();
}
#Override
public String getRemoteDeviceAddress() {
return socket.getRemoteDevice().getAddress();
}
#Override
public void close() throws IOException {
socket.close();
}
#Override
public BluetoothSocket getUnderlyingSocket() {
return socket;
}
}
public class FallbackBluetoothSocket extends NativeBluetoothSocket {
private BluetoothSocket fallbackSocket;
public FallbackBluetoothSocket(BluetoothSocket tmp) throws FallbackException {
super(tmp);
try
{
Class<?> clazz = tmp.getRemoteDevice().getClass();
Class<?>[] paramTypes = new Class<?>[] {Integer.TYPE};
Method m = clazz.getMethod("createRfcommSocket", paramTypes);
Object[] params = new Object[] {Integer.valueOf(1)};
fallbackSocket = (BluetoothSocket) m.invoke(tmp.getRemoteDevice(), params);
}
catch (Exception e)
{
throw new FallbackException(e);
}
}
#Override
public InputStream getInputStream() throws IOException {
return fallbackSocket.getInputStream();
}
#Override
public OutputStream getOutputStream() throws IOException {
return fallbackSocket.getOutputStream();
}
#Override
public void connect() throws IOException {
fallbackSocket.connect();
}
#Override
public void close() throws IOException {
fallbackSocket.close();
}
}
public static class FallbackException extends Exception {
/**
*
*/
private static final long serialVersionUID = 1L;
public FallbackException(Exception e) {
super(e);
}
}
}
(MainActivity.java:367)
try {
engineRpmCommand.run(mmInStream, mmOutStream);
speedCommand.run(mmInStream, mmOutStream);
fueltypeCommand.run(mmInStream, mmOutStream);
System.out.println("Commands Processed");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
367--> e.printStackTrace();
}
System.out.println("outside try catch");
}
(ObdCommand.java:164)
protected void readRawData(InputStream in) throws IOException {
byte b = 0;
StringBuilder res = new StringBuilder();
// read until '>' arrives
164--> while ((char) (b = (byte) in.read()) != '>')
res.append((char) b);
Have you checked if your string builder / buffer contains anything at the time the exception is thrown?
I've had this trouble with Bluetooth on a Nexus 7 2012 and the only thing I can suggest is that you Thread.sleep() while waiting for data and use .available() from the stream to make sure you don't read more than what is available.
You could sleep loop while .available() is zero and not equal to the amount as the last loop, and then assume you have all the data when it stabilizes. Alternatively you can simply catch the exception and assume you have received all the data at that point.
I think its a bug in read() method. From #Keilaron's answer.. I tried this and this works:
while (inputStream.available() == 0);
val available = inputStream.available()
val bytes = ByteArray(available)
inputStream.read(bytes, 0, available)
val text = String(bytes)
I am new to android app and I am trying Camera using SurfaceTexture. The call back for OnFrameAvailable() is not being called... Please suggest me a solution. The code is below.
What is missing in this? I am not sure if I have made the correct call to setOnFrameListener().
package com.example.cameratest;
import com.example.test.R;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.graphics.SurfaceTexture;
import android.graphics.SurfaceTexture.OnFrameAvailableListener;
import android.hardware.Camera;
import android.media.MediaCodec;
import android.media.MediaCodecInfo;
import android.media.MediaFormat;
import android.media.MediaMuxer;
import android.opengl.*;
import android.util.Log;
import android.view.Surface;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.concurrent.locks.ReentrantLock;
public class MainActivity extends Activity implements OnFrameAvailableListener {
private static final String TAG = "CameraToMpegTest";
private static final boolean VERBOSE = true; // lots of logging
// where to put the output file (note: /sdcard requires WRITE_EXTERNAL_STORAGE permission)
private static final long DURATION_SEC = 8;
// camera state
private Camera mCamera;
private static SurfaceTexture mSurfaceTexture;
private int[] mGlTextures = null;
private Object mFrameSyncObject = new Object();
private boolean mFrameAvailable = false;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void startCamera(View v) {
try {
this.initCamera(0);
this.StartCamera();
} catch (Throwable throwable) {
throwable.printStackTrace();
}
}
private void StartCamera() {
try {
mCamera.startPreview();
long startWhen = System.nanoTime();
long desiredEnd = startWhen + DURATION_SEC * 1000000000L;
int frameCount = 0;
while (System.nanoTime() < desiredEnd) {
// Feed any pending encoder output into the muxer.
awaitNewImage();
}
} finally {
// release everything we grabbed
releaseCamera();
}
}
/**
* Stops camera preview, and releases the camera to the system.
*/
private void releaseCamera() {
if (VERBOSE) Log.d(TAG, "releasing camera");
if (mCamera != null) {
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
}
private void initCamera(int cameraId) {
mCamera = Camera.open(cameraId);
if (mCamera == null) {
Log.d(TAG, "No front-facing camera found; opening default");
mCamera = Camera.open(); // opens first back-facing camera
}
if (mCamera == null) {
throw new RuntimeException("Unable to open camera");
}
Camera.Parameters parms = mCamera.getParameters();
parms.setPreviewSize(640, 480);
mGlTextures = new int[1];
GLES20.glGenTextures(1, mGlTextures, 0);
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mGlTextures[0]);
GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER,
GLES20.GL_NEAREST);
GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER,
GLES20.GL_LINEAR);
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_S,
GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_T,
GLES20.GL_CLAMP_TO_EDGE);
mSurfaceTexture = new SurfaceTexture(mGlTextures[0]);
try {
mCamera.setPreviewTexture(mSurfaceTexture);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mSurfaceTexture.setOnFrameAvailableListener(MainActivity.this);
}
public void awaitNewImage() {
final int TIMEOUT_MS = 4500;
synchronized (mFrameSyncObject) {
while (!mFrameAvailable) {
try {
// Wait for onFrameAvailable() to signal us. Use a timeout to avoid
// stalling the test if it doesn't arrive.
if (VERBOSE) Log.i(TAG, "Waiting for Frame in Thread");
mFrameSyncObject.wait(TIMEOUT_MS);
if (!mFrameAvailable) {
// TODO: if "spurious wakeup", continue while loop
throw new RuntimeException("Camera frame wait timed out");
}
} catch (InterruptedException ie) {
// shouldn't happen
throw new RuntimeException(ie);
}
}
mFrameAvailable = false;
}
}
#Override
public void onFrameAvailable(SurfaceTexture st) {
if (VERBOSE) Log.d(TAG, "new frame available");
synchronized (mFrameSyncObject) {
if (mFrameAvailable) {
throw new RuntimeException("mFrameAvailable already set, frame could be dropped");
}
mFrameAvailable = true;
mFrameSyncObject.notifyAll();
}
}
}
I think you have to call SurfaceTeture.updateTextImage() after your OnFrameAvailable() Callback to tell the camera "I've used your last frame, give me another one".
(Sorry but my English cannot provide a better explanation)
#Override
public void onFrameAvailable(SurfaceTexture surfaceTexture) {
...
surfaceTexture.updateTexImage();
}
had the same problem, seems like I forgot to call for the updateTexImage()
use method setOnFrameAvailableListener(#Nullable final OnFrameAvailableListener listener, #Nullable Handler handler) replace setOnFrameAvailableListener(#Nullable OnFrameAvailableListener listener).
in your case, you can modify the code as:
frameUpdateThread = new HandlerThread("frameUpdateThread");
frameUpdateThread.start();
mSurfaceTexture.setOnFrameAvailableListener(MainActivity.this, Handler(frameUpdateThread.getLooper()));
In my understanding onFrameAvailable should be used with thread. With that i am not facing the issue and also make sure updatetextImage is called after receiving the frames
I'm currently working on writing an App on Android to interface with an Arduino Board. I am able to send serial data to my Arduino just fine, however my app crashes at start up the moment I begin trying to receive data.
I currently have it set so a text field takes data from a user, and sends to the Arduino, Arduino does a function.
For my receive, I am making a new thread at start up to constantly listen for data from the Arduino. whenever the code in this thread is executed, it crashes.
I am using this library as my basis: https://github.com/mik3y/usb-serial-for-android
Below is the all the code pertinent, omitted code for other functionality this app is providing, that are unrealted:
import java.io.IOException;
import java.io.InputStream;
import java.text.DecimalFormat;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import com.hoho.android.usbserial.driver.UsbSerialDriver;
import android.hardware.usb.UsbManager;
import android.content.Intent;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.content.Context;
import android.util.Log;
import com.hoho.android.usbserial.driver.UsbSerialProber;
public class MainActivity extends Activity implements SensorEventListener, LocationListener{
private EditText sendTextField;
TextView uartRX;
public Handler Handler;
UsbManager manager;
/** Called to create application activity*/
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
uartRX = (TextView)findViewById(R.id.rxUART);
sendTextField = (EditText) findViewById(R.id.sendTextField);
Handler = new Handler() {
#Override public void handleMessage(Message msg) {
String text = (String)msg.obj;
uartRX.append(text);
}
};
Thread t = new Thread(new Runnable() {
public void run()
{
Message msg = new Message();
msg.obj = "Start Serial Listen\n";
Handler.sendMessage(msg);
rxUART();
}
public void rxUART()
{
manager = (UsbManager) getSystemService(Context.USB_SERVICE);
UsbSerialDriver rxDriver = UsbSerialProber.acquire(manager);
if (rxDriver != null) {
try {
rxDriver.open();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
int byteSize = 0;
String data = "";
while(true)
{
byte[] arr = null;
try {
rxDriver.setBaudRate(115200);
rxDriver.read(arr, byteSize);
data = new String(arr);
Message msg = new Message();
msg.obj = data;
Handler.sendMessage(msg);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
t.start();
}
public void sendUART(String data)
{
manager = (UsbManager) getSystemService(Context.USB_SERVICE);
// Find the first available driver.
UsbSerialDriver driver = UsbSerialProber.acquire(manager);
if (driver != null) {
try {
driver.open();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
driver.setBaudRate(115200);
byte buffer[] = new byte[16];
int numBytesRead = driver.read(buffer, 1000);
Log.d(TAG, "Read " + numBytesRead + " bytes.");
byte temp[] = data.getBytes();
driver.write(temp, 16);
} catch (IOException e) {
// Deal with error.
} finally {
try {
driver.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public void onClickSendBtn(View v)
{
String data = "";
data = sendTextField.getText().toString();
sendUART(data);
sendTextField.setText(" ");
}
#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;
}
}
Can anyone help me figure out why the app crashes on the code created in the thread?
Note: the code also crashes when not in a thread. Code was originally a function called by sendUART() to check for a response. no while(true) either.
Logcat:
11-02 09:49:22.988: E/AndroidRuntime(22652): FATAL EXCEPTION: Thread-964
11-02 09:49:22.988: E/AndroidRuntime(22652): java.lang.NullPointerException
11-02 09:49:22.988: E/AndroidRuntime(22652): at com.example.sensortest.MainActivity$2.rxUART(MainActivity.java:143)
11-02 09:49:22.988: E/AndroidRuntime(22652): at com.example.sensortest.MainActivity$2.run(MainActivity.java:119)
11-02 09:49:22.988: E/AndroidRuntime(22652): at java.lang.Thread.run(Thread.java:856)
The line numbers referenced are:
Thread t = new Thread(new Runnable() {
public void run()
{
Message msg = new Message();
msg.obj = "Start Serial Listen\n";
Handler.sendMessage(msg);
rxUART();
}
public void rxUART()
{
manager = (UsbManager) getSystemService(Context.USB_SERVICE);
UsbSerialDriver rxDriver = UsbSerialProber.acquire(manager);
if (rxDriver != null) {
try {
rxDriver.open();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
int byteSize = 0;
String data = "";
while(true)
{
byte[] arr = null;
try {
rxDriver.setBaudRate(115200);
rxDriver.read(arr, byteSize);
data = new String(arr);
Message msg = new Message();
msg.obj = data;
Handler.sendMessage(msg);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
t.start();
You don't handle the case rxDriver == null in rxUart() correctly.
The if() statement skips the open() call only, but the while() loop gets executed with rxDriver being NULL resulting in NPE. You have the same problem in `sendUART(), btw.
Getting this exception while executing on emulator.
I think this is related to some memory issue.
Because its working fine when am trying it on my phone.
Anyone help me to find the real reason for this problem?
Galleryview.java
package example.hitwallhd;
import example.hitwallhd.ImageDownloader;
import example.hitwallhd.ImageDownloader.ImageLoaderListener;
import example.hitwallhd.R;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.URISyntaxException;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ImageView.ScaleType;
public class Galleryview extends Activity {
private ProgressBar pb;
private Button save,bnxt,bprv;
private ImageView img;
private static Bitmap bmp;
private TextView percent;
private FileOutputStream fos;
private ImageDownloader mDownloader;
TextView t1,t2;
String num,cate,addrs,urladdrs,pviews,pdown,sele;
int savecount=0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_galleryview);
save.setEnabled(false);
initViews();
Bundle extras = getIntent().getExtras();
num = extras.getString("num");
cate = extras.getString("category");
sele = extras.getString("sele");
addrs= extras.getString("picno");
t1 =(TextView) findViewById(R.id.textView2);
t2 =(TextView) findViewById(R.id.textView3);
//t1.setText(pviews);
//t2.setText(pdown);
urladdrs="http://someaddrs.com/wallpapers/"+cate+"/"+addrs;
/*--- instantiate our downloader passing it required components ---*/
mDownloader = new ImageDownloader(urladdrs, pb, save, img, percent, Galleryview.this, bmp, new ImageLoaderListener() {
#Override
public void onImageDownloaded(Bitmap bmp) {
Galleryview.bmp = bmp;
/*--- here we assign the value of bmp field in our Loader class
* to the bmp field of the current class ---*/
}
});
/*--- we need to call execute() since nothing will happen otherwise ---*/
mDownloader.execute();
save.setEnabled(true);
}
private void initViews() {
save = (Button) findViewById(R.id.save);
//bnxt=(Button) findViewById(R.id.bnext);
//bprv=(Button) findViewById(R.id.bprev);
/*--- we are using 'this' because our class implements the OnClickListener ---*/
img = (ImageView) findViewById(R.id.imageView1);
img.setScaleType(ScaleType.CENTER_CROP);
pb = (ProgressBar) findViewById(R.id.pbDownload);
pb.setVisibility(View.INVISIBLE);
percent = (TextView) findViewById(R.id.textView1);
percent.setVisibility(View.INVISIBLE);
}
public void onclick_next(View v)
{
bprv.setEnabled(true);
GetData obj = new GetData();
int nxt=Integer.parseInt(num)+1;
num=String.valueOf(nxt);
String urls="http://someaddrs.com/wallpapers/newlist.php?cate="+cate+"&no="+num+"&prev=0";
obj.execute(urls);
}
public void onclick_prev(View v)
{
bnxt.setEnabled(true);
GetData obj = new GetData();
int nxt=Integer.parseInt(num)-1;
num=String.valueOf(nxt);
String urls="http://someaddrs.com/wallpapers/newlist.php?cate="+cate+"&no="+num+"&prev=1";
obj.execute(urls);
}
public void onclick_save(View v)
{
saveImageToSD();
String cnum;
if(urladdrs.equals("nexterror"))
{
int nxt=Integer.parseInt(num)-1;
cnum=String.valueOf(nxt);
}
else if(urladdrs.equals("preverror"))
{
int nxt=Integer.parseInt(num)+1;
cnum=String.valueOf(nxt);
}
else
cnum=num;
savecount=1;
GetData obj = new GetData();
String urls="http://someaddrs.com/wallpapers/downloadcount.php?no="+cnum;
obj.execute(urls);
}
private void saveImageToSD() {
/*--- this method will save your downloaded image to SD card ---*/
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
/*--- you can select your preferred CompressFormat and quality.
* I'm going to use JPEG and 100% quality ---*/
bmp.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
/*--- create a new file on SD card ---*/
File file = new File(Environment.getExternalStorageDirectory()
+ File.separator + num+"Image.jpg");
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
/*--- create a new FileOutputStream and write bytes to file ---*/
try {
fos = new FileOutputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
fos.write(bytes.toByteArray());
fos.close();
Toast.makeText(this, "Image saved", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
}
Intent pview = new Intent(Galleryview.this,HitWall.class);
startActivity(pview);
}
public void looperfn()
{
t1 =(TextView) findViewById(R.id.textView2);
t2 =(TextView) findViewById(R.id.textView3);
t1.setText(pviews);
t2.setText(pdown);
if(urladdrs.equals("nexterror"))
{
int nxt=Integer.parseInt(num)-1;
num=String.valueOf(nxt);
bnxt.setEnabled(false);
}
else if(urladdrs.equals("preverror"))
{
int nxt=Integer.parseInt(num)+1;
num=String.valueOf(nxt);
bprv.setEnabled(false);
}
else
{
//t1.setText(urladdrs);
urladdrs="http://someaddrs.com/wallpapers/"+cate+"/"+urladdrs;
mDownloader = new ImageDownloader(urladdrs, pb, save, img, percent, Galleryview.this, bmp, new ImageLoaderListener() {
#Override
public void onImageDownloaded(Bitmap bmp) {
Galleryview.bmp = bmp;
/*--- here we assign the value of bmp field in our Loader class
* to the bmp field of the current class ---*/
}
});
/*--- we need to call execute() since nothing will happen otherwise ---*/
mDownloader.execute();
}
}
public class GetData extends AsyncTask<String, Void, String>{
#Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
BufferedReader reader =null;
String data =null;
try{
HttpClient client = new DefaultHttpClient();
URI uri=new URI(params[0]);
HttpGet get =new HttpGet(uri);
HttpResponse response= client.execute(get);
InputStream stream=response.getEntity().getContent();
reader = new BufferedReader(new InputStreamReader(stream));
StringBuffer buffer =new StringBuffer("");
String line="";
while((line=reader.readLine())!=null){
buffer.append(line);
}
reader.close();
data = buffer.toString();
if(data.equals("preverror")||data.equals("nexterror"))
{
return data;
}
else
{
pviews=data.substring(data.indexOf("|")+1,data.indexOf(":"));
pviews=" Views : "+pviews;
pdown=data.substring(data.indexOf(":")+1, data.length());
pdown=" Downloads : "+pdown;
data=data.substring(0, data.indexOf("|"));
return data;
}
//data=data.substring(0, data.indexOf("|"));
//t1.setText(data);
}
catch(URISyntaxException e){
e.printStackTrace();
}
catch(ClientProtocolException f){
f.printStackTrace();
}
catch(IOException g){
g.printStackTrace();
}
finally{
if(reader!=null){
try{
reader.close();
}
catch(Exception e){
}
}
}
return null;
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
urladdrs=result;
if(savecount==0)
{
looperfn();
}
else
savecount=0;
}
}
}
This type of issue is arrived due to memory leakage.
the main problem is that there is Java.lang.NullPointerException and this type of exception arrives when there is low virtual memory.
As there is low virtual memory in emulator so it is getting the error and the phone has the sufficient virtual memory to display and load the image in the memory.
You have an exception in Galleryview.java at line 57. Please provide the peace of code around line 57 or the whole Galleryview.java.