I have one service(BackgoundService), one intent service (MyIntentService) and one process in my android app. UI hangs i.e. freezes completely when all three are running but it becomes so responsive when I stop the Intent Service.
Also I am running the BackgroundService in a worker thread and documentation says that Intent Service runs in a separate worker thread by default.
I don't get why my ui thread is still getting blocked when all other operations ,services are running in separate threads.
Intent service
public class MyIntentService extends IntentService {
public static String ACTION ="com.example.mediaapp.prototypingcanvas.MyIntentService.DONE_Processing";
public MyIntentService(){
super("MyIntentService");
}
DBRepo dbRepo;
WebRepo webRepo;
FileRepo fileRepo;
#Override
protected void onHandleIntent(Intent intent) {
//Activity Types ; 1=uploadSurvey; 2=downloadQre; 3=download survey for review; 4=sample download; 5=projectlistdownload
webRepo = new WebRepo(this);
fileRepo = new FileRepo();
int queueID = intent.getIntExtra("ID", 0);
dbRepo = new DBRepo(getApplicationContext());
dbRepo.updateQueue(queueID);
List<String> filesList;
int activityType = intent.getIntExtra("ActivityType", 0);
// int projectID = intent.getIntExtra("ProjectID",0);
String userName = intent.getStringExtra("UserName");
String ProjectGUID = intent.getStringExtra("ProjectGUID");
String projectName = intent.getStringExtra("ProjectName");
int response = -1;
Log.i("activitytype", activityType + "");
if (activityType == 1) {
filesList = new ArrayList<>();
filesList = fileRepo.list(projectName);
for (String fileName : filesList) {
webRepo.SyncData("http://test.cloud.rebuscode.com/api/api/v2/respondent/SyncData/" + projectName + "/" + fileName + "/true");
}
Log.i("activity type", activityType + "");
response = 1;
} else if (activityType == 2) {
Log.i("activity type", activityType + "");
response = 0;
} else if (activityType == 3) {
Log.i("activity type", activityType + "");
//webRepo.DownloadQuestionnaire("http://test.cloud.rebuscode.com/api/api/v2/respondent/DownloadQuestionnaireForTab/" + projectGuid + "/" + projectName,projectName);
fileRepo.unzip("Splash/and.zip");
} else if (activityType == 4) {
Log.i("activity type", activityType + "");
response = 1;
} else if (activityType == 5) {
Log.i("activity type", activityType + "");
response = 0;
} else {
Log.i("activity type", activityType + "");
}
// processing done here….
//delete row from Queue table and broadcast
dbRepo.deleteQueue(queueID);
Intent broadcastIntent = new Intent(ACTION);
broadcastIntent.putExtra("Response", response);
broadcastIntent.putExtra("ActivityType", activityType);
broadcastIntent.putExtra("UserName", userName);
broadcastIntent.putExtra("ID", queueID);
broadcastIntent.putExtra("ProjectGuid", ProjectGUID);
sendBroadcast(broadcastIntent);
}
}
can anyone suggest why its blocking my ui thread???
Related
I'm transfering an image of 1 mb using the following code.
The image gets transferred successfully if a thread delay is implemented between each packets.
If the thread delay is not set all the packets are sent from BluetoothGattServer but the BluetoothGattCallback does not receive all the packets.
Can anyone guide in sending the packets without the thread delay
Implement thread between each packets
private void sendingContinuePacket(BluetoothGattCharacteristic characteristic,
byte[] CHARACTERS) {
boolean isComplete = false;
runOnUiThread(() -> {
tv_status.setText("Sending Data...!!");
startTime = SystemClock.uptimeMillis();
customHandler.postDelayed(updateTimerThread, 0);
});
// Check the data length is large how many times with Default Data (BLE)
int times = CHARACTERS.length / DEFAULT_BYTES_IN_CONTINUE_PACKET;
totalPackets = times;
Log.i("", "CHARACTERS.length() " + CHARACTERS.length);
byte[] packetNoByte;
byte[] sending_continue_hex = new byte[DEFAULT_BYTES_IN_CONTINUE_PACKET];
for (int time = 0; time <= times; time++) {
final int remainingTime = time;
if (!hasDisconnected) {
this.runOnUiThread(new Runnable() {
#Override
public void run() {
mRelativeLayout.setVisibility(View.VISIBLE);
if (totalPackets != 0) {
showProgress(totalPackets, remainingTime);
}
}
});
} else {
runOnUiThread(() -> {
mProgressBar.setProgress(0);
tv_progress.setText(0 + "%");
tv_timer.setText("00:00:00");
tv_imageSize.setText("");
tv_status.setText("");
Toast.makeText(PeripheralRoleActivity.this, "Something went wrong, Please Try again", Toast.LENGTH_SHORT).show();
customHandler.removeCallbacks(updateTimerThread);
});
return;
}
int a;
int b;
/**
* #param THREAD_SLEEP_TIME_FOR_NOTIFICATION
* this delay is placed to give a small pause while sending the data packe
* */
try {
Thread.sleep(Constants.THREAD_SLEEP_TIME_FOR_NOTIFICATION);
} catch (InterruptedException e) {
e.printStackTrace();
}
sentPacket = sentPacket + 1;
byte[] packetArray = Utils.getUtilsClass().toByteArray(sentPacket);
packetNoByte = Arrays.copyOf(packetArray, packetArray.length);
if (time == times) {
Log.i("", "LAST PACKET ");
int character_length = CHARACTERS.length
- DEFAULT_BYTES_IN_CONTINUE_PACKET * times;
byte[] sending_last_hex = new byte[character_length];
a = (sending_continue_hex.length) * time;
b = a + character_length;
if(b-a ==0){
return;
}
sending_last_hex = Arrays.copyOfRange(CHARACTERS, a, b);
byte[] last_packet =
new byte[packetNoByte.length + character_length];
System.arraycopy(packetNoByte, 0, last_packet,
0, packetNoByte.length);
System.arraycopy(sending_last_hex, 0, last_packet,
packetNoByte.length, sending_last_hex.length);
Log.d("Sending packets", Arrays.toString(last_packet));
// Set value for characteristic
characteristic.setValue(last_packet);
notifyCharacteristicChanged();
isComplete = true;
customHandler.removeCallbacks(updateTimerThread);
currentDateTimeString = DateFormat.getDateTimeInstance().format(new Date());
Log.d("Collection", "End Time: " + currentDateTimeString);
Utils.getUtilsClass().sendNotification(getApplicationContext(), "Data Transfer", "Transfer Complete");
} else {
Log.i("", "CONTINUE PACKET ");
a = ((sending_continue_hex.length) * time);
b = a + DEFAULT_BYTES_IN_CONTINUE_PACKET;
sending_continue_hex = Arrays.copyOfRange(CHARACTERS, a, b);
byte[] sending_continue_packet =
new byte[packetNoByte.length + sending_continue_hex.length];
System.arraycopy(packetNoByte, 0, sending_continue_packet,
0, packetNoByte.length);
System.arraycopy(sending_continue_hex, 0, sending_continue_packet,
packetNoByte.length, sending_continue_hex.length);
Log.d("data transfer a", String.valueOf(a));
Log.d("data transfer b", String.valueOf(b));
Log.d("data trans bytes", String.valueOf(sending_continue_hex.length));
if(output == null){
output = new ByteArrayOutputStream();
}
try {
if {
characteristic.setValue(sending_continue_packet);
Log.d("Sending packets", Arrays.toString(sending_continue_packet));
notifyCharacteristicChanged();
}
} catch (IOException e) {
e.printStackTrace();
}
}
Log.d("Data byte", "times " + time);
if (isComplete) {
characteristic.setValue("Completed");
notifyCharacteristicChanged();
}
runOnUiThread(() -> tv_status.setText("Data sent!!"));
}
}
Updated Code
//the following function is used break the image byte [] into packets and store it in an arraylist
private void breakPackets(byte[] CHARACTERS) {
// Check the data length is large how many times with Default Data (BLE)
int times = CHARACTERS.length / DEFAULT_BYTES_IN_CONTINUE_PACKET;
totalPackets = times;
packetList = new ArrayList<>();
sendingPacket = 0;
Log.i("", "CHARACTERS.length() " + CHARACTERS.length);
byte[] sending_continue_hex = new byte[DEFAULT_BYTES_IN_CONTINUE_PACKET];
for (int time = 0; time <= times; time++) {
int a;
int b;
if (time == times) {
Log.i("", "LAST PACKET ");
int character_length = CHARACTERS.length
- DEFAULT_BYTES_IN_CONTINUE_PACKET * times;
byte[] sending_last_hex = new byte[character_length];
a = (sending_continue_hex.length) * time;
b = a + character_length;
sending_last_hex = Arrays.copyOfRange(CHARACTERS, a, b);
//packetList is an ArrayList<byte[]>
packetList.add(sending_last_hex);
startSendingPackets(sendingPacket);
} else {
a = (sending_continue_hex.length) * time;
b = a + DEFAULT_BYTES_IN_CONTINUE_PACKET;
sending_continue_hex = Arrays.copyOfRange(CHARACTERS, a, b);
packetList.add(sending_continue_hex);
}
Log.d("Data byte", "times " + time);
}
}
//the following function is used to set the byte[] from the arraylist to the characteristics and then notify the characteristics
private void startSendingPackets(int packet) {
isCommand = false;
mSampleCharacteristic.setValue(packetList.get(packet));
notifyCharacteristicChanged();
Log.i("packeting", "Sending ------------> " + packet);
}
/*************************************************/
#Override
public void onNotificationSent(BluetoothDevice device, int status) {
super.onNotificationSent(device, status);
//check if status is success
if (status == BluetoothGatt.GATT_SUCCESS) {
//if status is not successful isExecutable is false and the else loop is executed to resend the same packet that has failed
if (isExecutable) {
// Log.i("packeting", "Sent ------------> " + sendingPacket);
sendingPacket = sendingPacket + 1;
int size = packetList.size();
if (sendingPacket <= size-1) {
startSendingPackets(sendingPacket);
Log.d(MainActivity.TAG, "Notification sent. Status: " + status + " sending packet no --" + sendingPacket);
} else {
sendCommand("Completed");
}
} else {
startSendingPackets(sendingPacket);
isExecutable = true;
Log.d(MainActivity.TAG, "Notification sent. Status: " + status + " sending packet no --" + sendingPacket);
}
}else{
//if status is not successful
isExecutable = false;
Log.d(MainActivity.TAG, "Notification sent. fail Status: " + status );
}
}
As can be read in the documentation at https://developer.android.com/reference/android/bluetooth/BluetoothGattServerCallback.html#onNotificationSent(android.bluetooth.BluetoothDevice,%20int):
When multiple notifications are to be sent, an application must wait
for this callback to be received before sending additional
notifications.
This means after you have called notifyCharacteristicChanged, you cannot call notifyCharacteristicChanged again until the callback onNotificationSent has been received. So you need to remove your for-loop and refactor your code to follow the API rules.
The reason for this is to get flow control. If you just push new packets faster than the BLE link's throughput, the internal buffers get full and packet loss will occur. That's why a delay might seem to work, but it's not a robust solution so that's why you should wait for the onNotificationSent callback since that means the BLE stack is ready to accept new packets.
I have a for loop inside onActivityResult() method that creates a Runnable object and assign in to an AsyncTask. Each Runnable object is responsible of operating on a pdf file, sealing it with a password and then starting an startActivityForResult() method with an Intent to send an email.
Everything works as a charm except that my problem is that the for loop will start all the AsyncTask immediately even though the the activity is paused and the user is on the email client app. I want to make sure that the next AsyncTask doesn't execute until the user gets back to the application after pressing send email button on the email client app.
UPDATE
if (requestCode == 2) {
// Create Insurer annexe, seal document with insurer password and trigger sending email
int lastInsurerPosition = -1;
for (int i = 0; i < Constat.getInstance().getAccidentList().size(); i++) {
if (Constat.getInstance().getAccidentList().get(i).getCar().getInsurerPosition() != -1 &&
!insurersEmails[Constat.getInstance().getAccidentList().get(i).getCar().getInsurerPosition()].equals("null") &&
Constat.getInstance().getAccidentList().get(i).getSendOption() != 1 &&
Constat.getInstance().getAccidentList().get(i).getSendOption() != 2) {
lastInsurerPosition = i;
}
}
if (lastInsurerPosition != -1) {
final int lastInsurerPositionCopy = lastInsurerPosition;
for (int i = 0; i < Constat.getInstance().getAccidentList().size(); i++) {
String insurerEmail = "null";
if (Constat.getInstance().getAccidentList().get(i).getCar().getInsurerPosition() != -1) {
insurerEmail = insurersEmails[Constat.getInstance().getAccidentList().get(i).getCar().getInsurerPosition()];
}
if (Constat.getInstance().getAccidentList().get(i).getSendOption() != 1 &&
Constat.getInstance().getAccidentList().get(i).getSendOption() != 2 &&
!insurerEmail.equals("null")) {
final int finalI = i;
Runnable progressRunnable = new Runnable() {
#Override
public void run() {
try {
String[] toArray = new String[1];
toArray[0] = insurersEmails[Constat.getInstance().getAccidentList().get(finalI).getCar().getInsurerPosition()];
String subject = getResources().getString(R.string.pdf_joint_report);
InputStream is;
String str;
byte[] buffer = null;
int size;
if (Locale.getDefault().getLanguage().equals("en")) {
is = getAssets().open("insurerEmailTemplateENG.html");
} else {
is = getAssets().open("insurerEmailTemplateFR.html");
}
size = is.available();
buffer = new byte[size];
is.read(buffer);
is.close();
String destPath = Constat.getInstance().getPdfPath().replace(".pdf", "_copy" + Constat.getInstance().getAccidentList().get(finalI).getNumAccident() + ".pdf");
String destPath1 = Constat.getInstance().getPdfPath().replace(".pdf", "_copy1.pdf");
if (insurersPdfStructure[Constat.getInstance().getAccidentList().get(finalI).getCar().getInsurerPosition()].equals("1")) {
List<File> filesList = new ArrayList<>();
if (PdfController.getInstance(activityRef.get()).getAnnexePref()) {
filesList.add(new File(Constat.getInstance().getPdfPath()));
filesList.add(new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + PACKAGE_NAME + "/annexe.pdf"));
} else {
filesList.add(new File(Constat.getInstance().getPdfPath()));
}
File outputFile = new File(destPath1);
try {
Utilities.mergePdfDocuments(filesList, outputFile);
} catch (DocumentException | IOException e) {
e.printStackTrace();
}
} else {
try {
Document document = new Document(PageSize.A4);
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(destPath1));
document.open();
PdfContentByte cb = writer.getDirectContent();
PdfReader reader = new PdfReader(new FileInputStream(Constat.getInstance().getPdfPath()));
for (int j = 0; j < reader.getNumberOfPages(); j++) {
PdfImportedPage page = writer.getImportedPage(reader, j + 1);
if (j == 0) {
PdfDictionary parameters = new PdfDictionary();
parameters.put(PdfName.MODDATE, new PdfDate());
PdfFileSpecification fileSpec = PdfFileSpecification.fileEmbedded(
writer, Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + PACKAGE_NAME + "/annexe.xml",
"annexe.xml", null, "application/xml", parameters, 0);
fileSpec.put(new PdfName("annexe"), new PdfName("Data"));
writer.addFileAttachment("annexe.xml", fileSpec);
PdfFileSpecification fileSpec1 = PdfFileSpecification.fileEmbedded(
writer, Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + PACKAGE_NAME + "/xml_def.xsd",
"xml_def.xsd", null, "application/xml", parameters, 0);
fileSpec.put(new PdfName("xml_def"), new PdfName("Data"));
writer.addFileAttachment("xml_def.xsd", fileSpec1);
PdfArray array = new PdfArray();
array.add(fileSpec.getReference());
array.add(fileSpec1.getReference());
writer.getExtraCatalog().put(new PdfName("AF"), array);
}
cb.addTemplate(page, 0, 0);
document.newPage();
}
document.close();
} catch (DocumentException | IOException e) {
e.printStackTrace();
}
}
try {
File file1 = new File(destPath);
file1.getParentFile().mkdirs();
Utilities.sealPdf(destPath1, destPath, insurersPasswords[Constat.getInstance().getAccidentList().get(finalI).getCar().getInsurerPosition()]);
} catch (DocumentException e) {
e.printStackTrace();
}
ArrayList<Uri> uris = new ArrayList<Uri>();
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N)
uris.add(Uri.fromFile(new File(destPath)));
else
uris.add(FileProvider.getUriForFile(context, getApplicationContext().getPackageName() + ".provider", new File(destPath)));
str = new String(buffer);
str = str.replace("{#CAROWNER}", Constat.getInstance().getAccidentList().get(finalI).getCar().getOwner().getFirstName() + " " + Constat.getInstance().getAccidentList().get(finalI).getCar().getOwner().getLastName());
final int i1 = finalI;
final int lastInsurerPosition1 = lastInsurerPositionCopy;
final String[] toArray1 = toArray;
final String str1 = str;
final String subject1 = subject;
final ArrayList<Uri> uris1 = uris;
runOnUiThread(new Runnable() {
#Override
public void run() {
if (i1 != lastInsurerPosition1) {
Utilities.sendEmails(activityRef.get(), toArray1, null, str1, subject1, uris1, 3);
} else {
Utilities.sendEmails(activityRef.get(), toArray1, null, str1, subject1, uris1, 4);
}
while (!activityRef.get().hasWindowFocus()) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
};
LongOperation lo = new LongOperation(PdfActivity.this, progressRunnable, getResources().getString(R.string.generating),
getResources().getString(R.string.generating_email_n_for_insurer, Constat.getInstance().getAccidentList().get(i).getDriver().getFirstName()));
lo.execute();
}
}
} else {
// delete signature image file and redirect user to home screen
for (int j = 0; j < Constat.getInstance().getAccidentList().size(); j++) {
File file = new File(Constat.getInstance().getAccidentList().get(j).getSignatureFilePath());
file.delete();
}
// Reset Pdf instance
PdfController.destroyInstance();
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(getResources().getString(R.string.send_success))
.setMessage(getResources().getString(R.string.emails_sended))
.setCancelable(false)
.setPositiveButton(getResources().getString(R.string.ok_button), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Intent intent = new Intent(context, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
}
});
AlertDialog alert = builder.create();
alert.show();
}
}
Thanks in advance.
I can write an abstract snippet, cuz i don't understand your code, it can be a guide (if it helps) to alter your code to, i will post answer
Declare this class scope
Queue<MyItem> queue = new LinkedList<MyItem>();
//MyItem is a type i think it's what in 'Constat.getInstance().getAccidentList()'
//it should be the type you have to be processed (email and PDF)
your current code (onActivityResult) don't start processing, just add to Queue, and process first item in Queue:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
for(int i = 0; i < Constat.getInstance().getAccidentList().size(); i++){
//add to-be-processed items in the Queue
queue.add(Constat.getInstance().getAccidentList().get(i));
}//for loop
//when loop finish, start processing first item
MyItem item = queue.remove();
processItem(item);
}
each time onResume() is called, check queue size, if empty
that can be all items were processed, or this is the first time the activity is open, so no items to process yet
#Override
protected void onResume()
{
super.onResume();
if(queue.size() != 0){
processItem(queue.remove());
}//we still have items to process
}
your actual code is here, to create PDF, create email , send email.
private void processItem(MyItem item){
//start runnable ... to create PDF ...
//create email body, and start email sending action
}
How do i can read data from received mms.
I receive an mms but I can't take any data from it to save it
public class MmsReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
String type = intent.getType();
Utils.PrintInfo("Action : "+action+", Type : "+type);
Bundle bundle = intent.getExtras();
Utils.PrintDebug("bundle " + bundle);
if (bundle != null) {
for(String k:bundle.keySet()) {
Utils.PrintInfo(k);
}
byte[] buffer = bundle.getByteArray("data");
Utils.PrintDebug("buffer " + buffer);
String incomingNumber = new String(buffer);
int indx = incomingNumber.indexOf("/TYPE");
if (indx > 0 && (indx - 15) > 0) {
int newIndx = indx - 15;
incomingNumber = incomingNumber.substring(newIndx, indx);
indx = incomingNumber.indexOf("+");
if (indx > 0) {
incomingNumber = incomingNumber.substring(indx);
Utils.PrintDebug("Mobile Number: " + incomingNumber);
}
}
int transactionId = bundle.getInt("transactionId");
Utils.PrintDebug("transactionId " + transactionId);
int pduType = bundle.getInt("pduType");
Utils.PrintDebug("pduType " + pduType);
byte[] buffer2 = bundle.getByteArray("header");
String header = new String(buffer2);
Utils.PrintDebug("header " + header);
}
}
}
data from that mms looks like
data : ???1351504361#mms2??????+48668822862/TYPE=PLMN???????????????http://mmsc.play.pl/?id=1351504361B??
how can I get any image from it? - i have send image from other device to that one
I wrote a little android program, there is a main activity with a broadcast listener, and i create another thread. The thread searches for prime numbers, and loading them into a long arraylist, and after every 3 seconds, sends the filled array to the main activity via broadcast. Everythings ok, until i'm trying to get the long array extra from the intent. It causes every time a nullpointerexception.
I tried with a string arraylist, it worked, but i am curious because the intent has an "getlongarrayextra" method.
Here is my code:
public class MainActivity extends Activity {
public static String BROADCAST_THREAD_KEY = "broadcast_key";
public static String EXTRAARRAYID = "primes";
private static long MAXNUM = 2000000;
private PrimeCalculatorThread thread;
TextView textView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.numberstext);
}
private BroadcastReceiver receiver = new BroadcastReceiver() {
public void onReceive(android.content.Context context,
android.content.Intent intent) {
String origitext = textView.getText().toString();
long[] primes = intent.getExtras().getLongArray(EXTRAARRAYID);
Log.d("ASD", "broadcast received" + primes.toString());
StringBuilder builder = new StringBuilder();
if (primes != null) {
for (long prime : primes) {
builder.append(prime + " - ");
}
textView.setText(origitext + "\n" + builder.toString());
}
};
};
#Override
protected void onResume() {
Log.d("ASD", "ONRESUME");
initReceiverAndStartThread();
super.onResume();
}
private void initReceiverAndStartThread() {
IntentFilter filter = new IntentFilter(BROADCAST_THREAD_KEY);
registerReceiver(receiver, filter);
thread = new PrimeCalculatorThread(getBaseContext(), MAXNUM);
thread.start();
Log.d("ASD", "THREAD STARTED");
}
and the second thread:
public class PrimeCalculatorThread extends Thread {
private Context context;
private long maxnum;
List<Long> primes;
boolean isrunning;
public void setIsrunning(boolean isrunning) {
this.isrunning = isrunning;
}
private long counter = 0;
private long DELAYBETWEENBROADCAST = 3000;
public PrimeCalculatorThread(Context c, long maxnum) {
this.context = c;
this.maxnum = maxnum;
primes = new ArrayList<Long>();
}
#Override
public void run() {
long startTime = System.currentTimeMillis();
long estimatedTime;
isrunning = true;
for (long i = 0; i < maxnum; i++) {
Log.d("ASD", Boolean.toString(isrunning));
if (!isrunning)
break;
Log.d("ASD", i + "");
estimatedTime = System.currentTimeMillis() - startTime;
if (isPrime(i)) {
primes.add(i);
Log.d("ASD", i + "is a prime");
} else {
Log.d("ASD", i + "is not a prime");
}
if (estimatedTime > counter * DELAYBETWEENBROADCAST
+ DELAYBETWEENBROADCAST) { // elapsed another period
Log.d("ASD", primes.toString() + " will be sending.");
sendBroadCast();
primes.clear();
counter++;
}
try { //for debug purposes
Thread.sleep(250);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void sendBroadCast() {
Intent intent = new Intent(MainActivity.BROADCAST_THREAD_KEY);
intent.putExtra(MainActivity.EXTRAARRAYID, primes.toArray());
context.sendBroadcast(intent);
Log.d("ASD", "BROADCAST SENT" + primes.toString());
}
boolean isPrime(long n) {
if (n < 2)
return false;
if (n == 2 || n == 3)
return true;
if (n % 2 == 0 || n % 3 == 0)
return false;
long sqrtN = (long) Math.sqrt(n) + 1;
for (long i = 6L; i <= sqrtN; i += 6) {
if (n % (i - 1) == 0 || n % (i + 1) == 0)
return false;
}
return true;
}
}
The problem is that you are managing a list of Long objects and passing it in putExtra, which means you are invoking putExtra(String name, Serializable value). Then you try to get that value using getLongArray(), but you haven't put any long array extra, you see! To solve this, replace
intent.putExtra(MainActivity.EXTRAARRAYID, primes.toArray());
with
long[] primesArray = new long[primes.size()];
for (int i = 0; i < primes.size(); i++) {
primesArray[i] = primes.get(i);
}
intent.putExtra(MainActivity.EXTRAARRAYID, primesArray);
This will invoke the correct putExtra(String name, long[] value) method.
I need to download 100MB of images, so i decided that the best way is to make Service wich download it, and will show results for each file in activity. But this works like theres no service, the Activity fzreees, and unfreezes only after download all files.
Heres the code of Activity:
public class DownloadActivity extends Activity
{
String hist;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.download_activity);
startService(new Intent(this, DownloadService.class));
registerReceiver(broadcastReceiver,
new IntentFilter(DownloadService.BROADCAST_ACTION));
}
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver()
{
#Override
public void onReceive(Context context, Intent _intent)
{
updateUI(_intent);
}
};
private void updateUI(Intent intent)
{
if (intent.getBooleanExtra("exists", false))
hist = hist + "Item " +
intent.getIntExtra("item", -1) + ", image " +
intent.getIntExtra("obraz", -1) + " - DOWNLOADED\n";
else
hist = hist + "Item " +
intent.getIntExtra("item", -1) + ", image " +
intent.getIntExtra("obraz", -1) + " - ALREADY EXISTS\n";
((TextView) findViewById(R.id.dtitle)).setText("Item " +
intent.getIntExtra("item", -1) + ", image " +
intent.getIntExtra("image", -1) + ".");
((TextView) findViewById(R.id.ddetails)).setText(hist);
}
}
Code of Service:
public class DownloadService extends Service
{
public static final String BROADCAST_ACTION = "emis.katalog.grzybow.publishprogress";
Intent intent;
int counter = 0;
String postString;
#Override
public IBinder onBind(Intent arg0)
{
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate()
{
super.onCreate();
intent = new Intent(BROADCAST_ACTION);
}
#Override
public void onStart(Intent intent, int startId)
{
SQLiteDatabase db = new BazaGrzybowHelper(DownloadService.this).getReadableDatabase();
Cursor kursor = db.rawQuery("SELECT * FROM table", null);
InputStream in = null;
OutputStream out = null;
URL ulrn;
int nn = 1;
int pos = 1;
//out:
while(kursor.moveToNext())
{
while(kursor.getString(kursor.getColumnIndex("i_url_" + nn)) != "" ||
kursor.getString(kursor.getColumnIndex("i_url_" + nn)) != null)
{
String filename = "thg_" + pos + "_" + (nn+2) + ".jpg";
if (new File(Environment.getExternalStorageDirectory(),
"emis/katalog.grzybow/zapis_na_stale/"+filename).exists())
publishProgress(pos, nn, true);
else
{
publishProgress(pos, nn, false);
File destDir = new File(Environment.getExternalStorageDirectory(),
"emis/katalog.grzybow/zapis_na_stale");
if (!destDir.exists())
destDir.mkdirs();
destDir = null;
try
{
ulrn = new URL(kursor.getString(kursor.getColumnIndex("i_url_" + nn)));
HttpURLConnection con = (HttpURLConnection)ulrn.openConnection();
in = con.getInputStream();
out = new FileOutputStream(Environment.getExternalStorageDirectory().
getPath() + "/emis/katalog.grzybow/zapis_na_stale/" + filename);
copyFile(in, out);
in.close();
in = null;
out.flush();
out.close();
out = null;
}
catch(Exception e)
{
e.printStackTrace();
}
}
nn++;
if (nn > 10 || kursor.getString(kursor.getColumnIndex("i_url_" + nn)) == "" ||
kursor.getString(kursor.getColumnIndex("i_url_" + nn)) == null)
{
nn = 1;
break;
}
/*if (anuluj)
break out;*/
}
pos++;
}
db.close();
}
private void publishProgress(int item, int image, boolean exists)
{
intent.putExtra("item", item);
intent.putExtra("image", image);
intent.putExtra("exists", exists);
sendBroadcast(intent);
}
private void copyFile(InputStream in, OutputStream out) throws IOException
{
byte[] buffer = new byte[1024];
int read;
while((read = in.read(buffer)) != -1)
{
out.write(buffer, 0, read);
}
}
}
What am I doing wrong?
Perhaps this?
Caution: A service runs in the main thread of its hosting process—the
service does not create its own thread and does not run in a separate
process (unless you specify otherwise). This means that, if your
service is going to do any CPU intensive work or blocking operations
(such as MP3 playback or networking), you should create a new thread
within the service to do that work. By using a separate thread, you
will reduce the risk of Application Not Responding (ANR) errors and
the application's main thread can remain dedicated to user interaction
with your activities.