Execute multiple Asynctask - java

I would like to implement a image processing Asynctask in Android. There is a condition - if the previous asyntask is processing locally, the current task should process on the server.
I tried 4 images, and set the Thread.sleep(1000) in side the local process section, expected the first one process locally and others on server. However, they are all processed locally. Am I wrong?
private class ProcessImageTask extends AsyncTask<ImageItem, Void, ImageItem>{
#Override
protected ImageItem doInBackground(ImageItem... params) {
if(localProcessing==false){
//**************processing locally*****************
localProcessing = true;
try {
Bitmap bm = BitmapFactory.decodeFile(params[0].getBitmap());
Bitmap croppedBitmap = getBitmap(getApplicationContext(), INPUT_SIZE, bm);
final List<Classifier.Recognition> results = classifier.recognizeImage(croppedBitmap);
String resultStr = results.toString();
String trimResult = resultStr.substring(resultStr.indexOf("[")+1,resultStr.indexOf("]")).trim();
String localId = params[0].getId();
trimResult = trimResult.substring(0,trimResult.indexOf(")")) + " likely)";
Bitmap thumbnail = getBitmap(getApplicationContext(), 50, bm);
ImageItem tmp = new ImageItem(localId, imgToString(thumbnail), trimResult);
Thread.currentThread();
Thread.sleep(1000);
localProcessing = false;
return tmp;
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
//****************processing on server*************************
try {
String ip = "192.168.1.3";
int port = 8195;
Bitmap bm = BitmapFactory.decodeFile(params[0].getBitmap());
Bitmap croppedBitmap = getBitmap(getApplicationContext(), INPUT_SIZE, bm);
String encodedImage = "/ID-BEGIN/" + ID + "/ID-END" + imgToString(croppedBitmap);
try {
//**********Send request to server*********
Socket socket = new Socket(ip,port);
DataInputStream dis = new DataInputStream(socket.getInputStream());
DataOutputStream dout = new DataOutputStream(socket.getOutputStream());
byte [] messageToServer = encodedImage.getBytes();
dout.writeInt(messageToServer.length);
dout.write(messageToServer);
//Receive response from server
int length = dis.readInt();
if(length>0) {
byte [] message = new byte[length];
dis.readFully(message, 0, message.length);
String response = new String(message);
//Handler updateHandler.post(new updateUIThread(response));
Bitmap thumbnail = getBitmap(getApplicationContext(), 50, bm);
ImageItem tmp = new ImageItem(params[0].getId(),imgToString(thumbnail), extractServerMessage(response)+"##");
return tmp;
}
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
#Override
protected void onPostExecute(ImageItem imageItem) {
super.onPostExecute(imageItem);
}
}
and I executes in a for loop
ImageItem it = pit.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, tmp).get();
Should I need to set the core pool size? Thanks a lot.

Your call to AsyncTask.get() waits for the task to finish before returning, so you're not actually running these in parallel, despite using the THREAD_POOL_EXECUTOR. You shouldn't call get here, but instead rely on onPostExecute to communicate results back to your program.

Related

Uploading files to Parse database

I want to add a feature to my app in which the users can upload files (PDF files) from their mobile to the database, then download this file back to the app and display it.
I have no idea how to start doing this and what is the right code to use.
I tried using this code,
ParseObject pObject = new ParseObject("ExampleObject");
pObject.put("myNumber", number);
pObject.put("myString", name);
pObject.saveInBackground(); // asynchronous, no callback
- EDIT -
I tried this code but the app crashes when I click the button:
public class Test extends Activity {
Button btn;
File PDFFile;
ParseObject po;
String userPDFFile;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test);
po = new ParseObject("pdfFilesUser");
btn = (Button) findViewById(R.id.button);
PDFFile = new File("res/raw/test.pdf");
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
uploadPDFToParse(PDFFile, po, userPDFFile);
}
});
}
private ParseObject uploadPDFToParse(File PDFFile, ParseObject po, String columnName){
if(PDFFile != null){
Log.d("EB", "PDFFile is not NULL: " + PDFFile.toString());
ByteArrayOutputStream out = new ByteArrayOutputStream();
BufferedInputStream in = null;
try {
in = new BufferedInputStream(new FileInputStream(PDFFile));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
int read;
byte[] buff = new byte[1024];
try {
while ((read = in.read(buff)) > 0)
{
out.write(buff, 0, read);
}
} catch (IOException e) {
e.printStackTrace();
}
try {
out.flush();
} catch (IOException e) {
e.printStackTrace();
}
byte[] pdfBytes = out.toByteArray();
// Create the ParseFile
ParseFile file = new ParseFile(PDFFile.getName() , pdfBytes);
po.put(columnName, file);
// Upload the file into Parse Cloud
file.saveInBackground();
po.saveInBackground();
}
return po;
}
}
You can upload a file manually via REST API. Take a look at this docs here
Can try this code:
private ParseObject uploadPDFToParse(File PDFFile, ParseObject po, String columnName){
if(PDFFile != null){
Log.d("EB", "PDFFile is not NULL: " + PDFFile.toString());
ByteArrayOutputStream out = new ByteArrayOutputStream();
BufferedInputStream in = null;
try {
in = new BufferedInputStream(new FileInputStream(PDFFile));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
int read;
byte[] buff = new byte[1024];
try {
while ((read = in.read(buff)) > 0)
{
out.write(buff, 0, read);
}
} catch (IOException e) {
e.printStackTrace();
}
try {
out.flush();
} catch (IOException e) {
e.printStackTrace();
}
byte[] pdfBytes = out.toByteArray();
// Create the ParseFile
ParseFile file = new ParseFile(PDFFile.getName() , pdfBytes);
po.put(columnName, file);
// Upload the file into Parse Cloud
file.saveInBackground();
po.saveInBackground();
}
return po;
}
For more details check this
I would strongly suggest you quickly get up to speed with the Parse Java development wiki.
To answer your question. You want to be using:
byte[] data = "Working at Parse is great!".getBytes();
ParseFile file = new ParseFile("resume.txt", data);
file.saveInBackground();
First declare your file etc then save it using that. But once again, first read the guidelines to better understand the framework you working with.
https://parseplatform.github.io/docs/android/guide/

How to read sensor data in android bluetooth not single byte

I've read data from sensor in android app via bluetooth using following code
try {
int byteCount = inputStream.available();
if (byteCount > 0) {
count++;
byte[] rawBytes = new byte[byteCount];
inputStream.read(rawBytes);
final String string = new String(rawBytes, "UTF-8");
handler.post(new Runnable() {
public void run() {
textView.append(string);
textView.append("\n");
}
});
}
} catch (IOException ex) {
stopThread = true;
}
This code read 10 as 1 and 0, So I want to read whole string . What will be required code for it?

Java: Can't convert string to array

I can't convert a string to an array!
String text = "";
String[] textsplit = {};
//Stuff
The app set the content of an online txt file in a string:
The online txt file contain: hello,my,name,is,simone
[...] //Downloading code
text = bo.toString(); //Set the content of the online file to the string
Now the string text is like this:
text = "hello,my,name,is,simone"
Now i have to convert the string to an array that must be like this:
textsplit = {"hello","my","name","is","simone"}
so the code that i use is:
textsplit = text.split(",");
But when i try to use the array the app crash! :(
For example:
textview.setText(textsplit[0]); //The text of the textview is empity
textview.setText(textsplit[1]); //The app crash
textview.setText(textsplit[2]); //The app crash
etc...
where am I wrong? thanks!
EDIT: This is the code:
new Thread() {
#Override
public void run() {
String path ="http://www.luconisimone.altervista.org/ciao.txt";
URL u = null;
try {
u = new URL(path);
HttpURLConnection c = (HttpURLConnection) u.openConnection();
c.setRequestMethod("GET");
c.connect();
InputStream in = c.getInputStream();
final ByteArrayOutputStream bo = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
in.read(buffer); // Read from Buffer.
bo.write(buffer); // Write Into Buffer.
runOnUiThread(new Runnable() {
#Override
public void run() {
text = bo.toString();
testo.setText("(" + text + ")");
try {
bo.close();
} catch (IOException e) {
e.printStackTrace();
}
}
});
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
// Here all variables became empity
textsplit = text.split(",");
datisplittati.setText(textsplit[0]);
Try :
String text = "hello,my,name,is,simone";
String[] textArr = text.split(Pattern.quote(","));
You can get string using AsyncTask
private class GetStringFromUrl extends AsyncTask<String, Void, String> {
ProgressDialog dialog ;
#Override
protected void onPreExecute() {
super.onPreExecute();
// show progress dialog when downloading
dialog = ProgressDialog.show(MainActivity.this, null, "Downloading...");
}
#Override
protected String doInBackground(String... params) {
// #BadSkillz codes with same changes
try {
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(params[0]);
HttpResponse response = httpClient.execute(httpGet);
HttpEntity entity = response.getEntity();
BufferedHttpEntity buf = new BufferedHttpEntity(entity);
InputStream is = buf.getContent();
BufferedReader r = new BufferedReader(new InputStreamReader(is));
StringBuilder total = new StringBuilder();
String line;
while ((line = r.readLine()) != null) {
total.append(line + "\n");
}
String result = total.toString();
Log.i("Get URL", "Downloaded string: " + result);
return result;
} catch (Exception e) {
Log.e("Get Url", "Error in downloading: " + e.toString());
}
return null;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
// TODO change text view id for yourself
TextView textView = (TextView) findViewById(R.id.textView1);
// show result in textView
if (result == null) {
textView.setText("Error in downloading. Please try again.");
} else {
textView.setText(result);
}
// close progresses dialog
dialog.dismiss();
}
}
and use blow line every time that you want:
new GetStringFromUrl().execute("http://www.luconisimone.altervista.org/ciao.txt");
You're using new thread to get data from an url. So in runtime, data will be asynchronous.
So when you access text variable (split it), it's still not get full value (example reason: network delay).
Try to move the function split after text = bo.toString(); , I think it will work well.

Decrypt AES256 encrypted file and save it in the phone

I'm downloading a file that is stored on a remote server, I try to decrypt it using JNCryptor, and all goes well except that the file I have downloaded and store in the phone external storage is corrupted and I cannot open it. Can anyone tell me where im going wrong?
Im trying to get the InputStream from the file, decrypt it, and save the file on external storage.
Thanks
Here is my code:
private void downloadFile() {
final String FILE_URL = "https://www.google.com";
final String PASS = "password";
new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... voids) {
Log.d(TAG, "starting");
JNCryptor cryptor = new AES256JNCryptor();
int count;
try {
URL url = new URL(FILE_URL);
URLConnection conection = url.openConnection();
conection.connect();
// this will be useful so that you can show a tipical 0-100%
// progress bar
int lenghtOfFile = conection.getContentLength();
// download the file
InputStream input = new BufferedInputStream(url.openStream(),
8192);
//decrypt istream
byte[] b = null;
byte[] data = null;
try {
b = new byte[input.available()];
input.read(b);
} catch (IOException e) {
Log.i("decrypt error", e.toString());
}
AES256JNCryptorOutputStream cryptorStream = null;
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
try {
cryptorStream = new AES256JNCryptorOutputStream(byteStream,
PASS.toCharArray());
} catch (CryptorException e) {
e.printStackTrace();
}
try {
cryptorStream.write(b);
cryptorStream.flush();
cryptorStream.close();
} catch (IOException e1) {
e1.printStackTrace();
}
byte[] encrypted = byteStream.toByteArray();
try {
data = cryptor.decryptData(encrypted, PASS.toCharArray());
Log.d(TAG, "decrypted");
} catch (InvalidHMACException e) {
e.printStackTrace();
} catch (CryptorException e) {
e.printStackTrace();
}
if (data != null) {
Log.d(TAG, "data is ok");
}
//end decryption
// Output stream
//test
FileOutputStream fos = new FileOutputStream(Environment
.getExternalStorageDirectory().toString()
+ "/temp.zip");
fos.write(data);
fos.close();
Log.d(TAG, "file saved ");
input.close();
Log.d(TAG, "done");
} catch (Exception e) {
Log.d(TAG, "Error: " + e.getMessage());
}
return null;
}
}.execute();
}
P.S. Im not getting any error or warning in logCat.

Download a large file in background only on WiFi

So what I'm trying to achieve is creating a service that downloads a large (~200 MB) file to the app's internal directory. It should resume (not restart) when it got canceled and automatically resume after a system reboot. It should sometimes (as written in a propeties file) only download using WiFi connection.
To do so I created an IntentService (is that a suitable solution?) that gets started by an Frgament's UI or by a BroadcastReceiver (after boot-up):
#Override
public void onHandleIntent(final Intent intent) {
c.registerReceiver(receiver, new IntentFilter(
ConnectivityManager.CONNECTIVITY_ACTION));
c.registerReceiver(receiver, new IntentFilter(
WifiManager.NETWORK_STATE_CHANGED_ACTION));
receiver.onReceive(null, null); // To start the download the first time
}
The last line calls a BroadcastReceiver that handles the download process. This is the way I tried to make sure that there is only one ongoing download at a time:
BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
boolean allowed = isConnectionAllowed();
if (allowed && !thread.isAlive()) {
thread.start();
} else if (allowed && thread.isAlive()) {
thread.notify(); // Can this cause any problems in this case?
} else if (!allowed && thread.isAlive()) {
try {
thread.wait();
} catch (InterruptedException e) {
if (StartActivity.DEV_MODE)
Log.i(StartActivity.LOG_TAG, Log.getStackTraceString(e));
}
}
}
};
And the download itselv runs in a seperate Thread.
private Thread thread = new Thread() {
#SuppressWarnings("resource")
#Override
public void run() {
HttpURLConnection connection = null;
BufferedInputStream input = null;
RandomAccessFile output = null;
try {
long already_downloaded = 0;
URL url = new URL(getSource());
File outputFileCache = new File(getDestination());
connection = (HttpURLConnection) url.openConnection();
if (outputFileCache.exists()) {
connection.setAllowUserInteraction(true);
connection.setRequestProperty("Range", "bytes="
+ outputFileCache.length() + "-");
}
connection.setConnectTimeout(14000);
connection.setReadTimeout(20000);
connection.connect();
if (connection.getResponseCode() / 100 != 2)
throw new Exception("Invalid response code!");
else {
String connectionField = connection
.getHeaderField("content-range");
if (connectionField != null) {
String[] connectionRanges = connectionField.substring(
"bytes=".length()).split("-");
already_downloaded = Long.valueOf(connectionRanges[0]);
}
if (connectionField == null && outputFileCache.exists())
outputFileCache.delete();
long fileLength = connection.getContentLength()
+ already_downloaded;
input = new BufferedInputStream(connection.getInputStream());
output = new RandomAccessFile(outputFileCache, "rw");
output.seek(already_downloaded);
byte data[] = new byte[1024];
int count = 0;
int progress = 0;
int progress_last_value = 0;
while ((count = input.read(data, 0, 1024)) != -1
&& progress != 100) {
already_downloaded += count;
output.write(data, 0, count);
progress = (int) ((already_downloaded * 100) / fileLength);
if (progress != progress_last_value) {
// Update notification
}
}
}
} catch (MalformedURLException e) {
if (StartActivity.DEV_MODE)
Log.i(StartActivity.LOG_TAG, Log.getStackTraceString(e));
} catch (IOException e) {
if (StartActivity.DEV_MODE)
Log.i(StartActivity.LOG_TAG, Log.getStackTraceString(e));
} catch (Exception e) {
if (StartActivity.DEV_MODE)
Log.i(StartActivity.LOG_TAG, Log.getStackTraceString(e));
} finally {
try {
if (output != null)
output.close();
if (input != null)
input.close();
if (connection != null)
connection.disconnect();
} catch (IOException e) {
if (StartActivity.DEV_MODE)
Log.i(StartActivity.LOG_TAG, Log.getStackTraceString(e));
}
}
// notify the Fragment using a `LocalBroadcast`.
}
};
And to make sure that the WiFi connection ist kept alive, I use the WifiLock class.
Note: I shortened the code in a few cases but I already managed to write that code.
So I'm not sure whether this is a good solution for my problem:
Should I use an IntentService or a normal Service for that?
Is that solution using a Thread a good one and will it work?
Won't the HttpURLConnection expire?
Can I access the Thread that way? (referres to wait() and notify())
I know this is a lot of code but it was the closest I could get. I hope someone knows a solution for that becuase I couldn't find anything usful on that topic ("only download while WiFi in ON") using Google and StackOverflow.
Thanks in advance,
Felix
(Comment if you need the whole Class)

Categories