1

Sorry, I don't know exactly what should be the title of the question. Can anyone tell me how is this possible?? enter image description here

The green line hasn't been executed yet.

Edit: Here tmp and size are positive integers for sure.

Edit: Source Code:

public class MyDownloadService extends IntentService {
String urlD, name, sole, urlOfImage = "";
Context conte;
static int q = -1;
int progress = 0, nin, tmp = 0;
File file;
public static final String NOTIFICATION = "com.example.downloader2.ShowDownloadsActivity";
public static final String NOTIFICATION2 = "com.example.downloader2.ShowDownloadsActivity2";
AppGlobal apg;

public MyDownloadService(String name) {
    super("Downloading");
}

public MyDownloadService() {
    super("Downloading");
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    q = q + 1;
    return super.onStartCommand(intent, flags, startId);
}

@Override
public void onCreate() {
    super.onCreate();
    conte = this;
}

@Override
protected void onHandleIntent(Intent intent) {
    apg = (AppGlobal) getApplication();
    urlD = intent.getExtras().getString("url");
    name = intent.getExtras().getString("name");
    nin = intent.getExtras().getInt("nin");
    urlOfImage = intent.getExtras().getString("urlOfImage");
    int ret = intent.getExtras().getInt("retry");
    if (ret == 1) {
        Toast.makeText(conte,
                "Please wait... Your download will start soon",
                Toast.LENGTH_SHORT).show();
    }
    sole = name;
    try {
        int size = 0;
        final int TIMEOUT_CONNECTION = 15000;// 15sec
        final int TIMEOUT_SOCKET = 30000;// 30sec
        String imageURL = urlD;
        URL url = new URL(imageURL);
        long startTime = System.currentTimeMillis();
        Log.e("Note: ", "image download beginning: " + imageURL);
        // Open a connection to that URL.
        URLConnection ucon = url.openConnection();

        // this timeout affects how long it takes for the app to realize
        // there's a connection problem
        ucon.setReadTimeout(TIMEOUT_CONNECTION);
        ucon.setConnectTimeout(TIMEOUT_SOCKET);

        // Define InputStreams to read from the URLConnection.
        // uses 3KB download buffer
        InputStream is = ucon.getInputStream();
        size = ucon.getContentLength();
        BufferedInputStream inStream = new BufferedInputStream(is, 1024 * 5);
        File wallpaperDirectory = new File(
                Environment.getExternalStorageDirectory() + "/myFold");
        wallpaperDirectory.mkdirs();
        // sole = sole.replace("?", "_");
        // sole = sole.replace("|", "_");
        // sole = sole.replace("/", "_");
        // sole = sole.replace(":", "_");
        // sole = sole.replace("$", "_");
        file = new File(wallpaperDirectory + File.separator + sole);
        if (file.exists()) {
            file.delete();
        }

        file.createNewFile();
        apg.setInDownload(true);
        FileOutputStream outStream = new FileOutputStream(file);
        byte[] buff = new byte[5 * 1024];

        // Read bytes (and store them) until there is nothing more to
        // read(-1)
        int len;
        tmp = 0;
        while ((len = inStream.read(buff)) != -1) {
            if (apg.getCont()) {
                apg.setCont(false);
                stopSelf();
                Intent inten = new Intent();
                inten.putExtra("urlToDownload", urlD);
                inten.putExtra("timeout", 7);
                inten.putExtra("name", sole);
                inten.putExtra("progress", progress);
                inten.putExtra("nin", nin);
                inten.putExtra("url", urlD);
                inten.setAction("com.example.downloader2.BR");
                sendBroadcast(inten);
                Intent in2 = new Intent(NOTIFICATION);
                in2.putExtra("progress", progress);
                in2.putExtra("running", 0);
                in2.putExtra("name", sole);
                q--;
                sendBroadcast(in2);
                progress = 0;
                if (file.exists()) {
                    file.delete();
                }
                outStream.close();
                return;
            }
            tmp = tmp + len;
            progress = (tmp * 100) / size;
            if(progress<0)
                progress=-1*progress;
            outStream.write(buff, 0, len);
            publishP();
        }
        tmp = size;
        progress = 101;
        publishP();
        // clean up

        outStream.flush();
        outStream.close();
        inStream.close();
        Log.e("Note: ",
                "Download completed in "
                        + ((System.currentTimeMillis() - startTime) / 1000)
                        + " secs.");
    } catch (Exception e) {
        if (file.exists()) {
            file.delete();
        }
        apg.setInDownload(false);
        Intent inten = new Intent();
        inten.putExtra("urlToDownload", urlD);
        if (e.toString()
                .equals("java.io.IOException: open failed: EACCES (Permission denied)")) {
            inten.putExtra("timeout", 5);
        } else {
            inten.putExtra("timeout", 1);
        }
        inten.putExtra("name", sole);
        inten.putExtra("progress", progress);
        inten.putExtra("nin", nin);
        inten.putExtra("url", urlD);
        inten.setAction("com.example.downloader2.BR");
        sendBroadcast(inten);
        Intent in2 = new Intent(NOTIFICATION);
        in2.putExtra("progress", progress);
        in2.putExtra("running", 0);
        in2.putExtra("name", sole);
        q--;
        sendBroadcast(in2);
        progress = 0;
        Log.e("Error: ", "Error is:" + e.toString());
    }
}

protected void publishP() {
    try {
        Intent intent = new Intent();
        intent.putExtra("timeout", 0);
        intent.putExtra("progress", progress);
        intent.putExtra("nin", nin);
        intent.putExtra("name", sole);
        intent.setAction("com.example.downloader2.BR");
        sendBroadcast(intent);
        Intent in2 = new Intent(NOTIFICATION);
        if (progress > 100)
            q--;
        in2.putExtra("progress", progress);
        in2.putExtra("running", 1);
        in2.putExtra("name", sole);
        in2.putExtra("queue", q);
        sendBroadcast(in2);
    } catch (Exception e) {
        Log.e("Shit", e.toString());
    }
}

@Override
public boolean stopService(Intent name) {
    return super.stopService(name);
}
}

Edit: These 3 snapshots were taken by me at same debugger state:

enter image description here

enter image description here

enter image description here

berserk
  • 2,690
  • 3
  • 32
  • 63
  • 1
    What do you want actually ? – GrIsHu Nov 13 '13 at 06:53
  • I am using this code to check whether the progress is positive or not. If negative, it must become positive. But if it is already positive, I must not go inside if statement. – berserk Nov 13 '13 at 06:55
  • Paste the source code please. It's not clear from snapshot. How are you so sure it's positive? Log statements or debugger? – Shobhit Puri Nov 13 '13 at 06:56
  • Your tmp and size are positive, so progress should not be negative. You do not have to check progress. – handrenliang Nov 13 '13 at 07:02
  • @handrenliang Then how can it jump to if statement? – berserk Nov 13 '13 at 07:03
  • Does your program always enter the while loop? You 'Len' value is uninitialized. So if it does not enter while loop it may have some random value.. What happens if you use Len = 0; ? – Shobhit Puri Nov 13 '13 at 07:04
  • @Shobit Yes it does. It is positive for some time, but suddenly gets negative. I will post 3 more screens which will show a strange thing. I took them at same debug state. – berserk Nov 13 '13 at 07:07
  • @user2944070 are you sure your tmp and size are positive? if they do, progress should not be negative – handrenliang Nov 13 '13 at 07:11
  • @handrenliang Yes, see the edit in the question. – berserk Nov 13 '13 at 07:13
  • @user2944070 if you enter the green line, please back to check tmp and size. – handrenliang Nov 13 '13 at 07:16

3 Answers3

2

Why don't you simply use

progress = abs((tmp * 100) / size);

so that your progress is always positive and get rid of the if statement ?

HpTerm
  • 8,151
  • 12
  • 51
  • 67
2

This is called overflow. When a number is too large and it then can't be represented properly and goes negative. Search the term "overflow" for details.

You could try (float)tmp / size * 100, the rationale is to ensure the number never exceed 100 during the calculation.

Please note that float casting is necessary because integer division would always give you an integer. In your case, you would always get 0 if you don't do the casting.

Bear
  • 5,138
  • 5
  • 50
  • 80
  • Sounds like a nice answer. Let me try :) – berserk Nov 13 '13 at 07:17
  • and tmp and size should be long – handrenliang Nov 13 '13 at 07:19
  • @Bear It seems working sirr, thanks. But I want to know one more thing. How the thing in the first picture I posted possible?? – berserk Nov 13 '13 at 07:27
  • I am not sure, I think your breakpoint actually print the value of progress after running the line (after the negation)? – Bear Nov 13 '13 at 07:33
  • Or with the async tasks running in background you are not sure you are reading a value is really the one at the debugger line. – HpTerm Nov 13 '13 at 07:38
  • For me yes (but need confirmation of others on that point), or at least you must put some specific information in eclipse or you project to debug correctly. Check http://stackoverflow.com/questions/4770587/how-do-i-use-the-eclipse-debugger-in-an-asynctask-when-developing-for-android or http://stackoverflow.com/questions/7051157/how-can-i-debug-doinbackground-code-of-an-asynctask – HpTerm Nov 13 '13 at 08:25
  • @HpTerm There is only one service running at a time. So, I don't think it is possible. What do you say? – berserk Nov 13 '13 at 08:27
  • In your screen capture I see 2 'AsyncTasks' running that's why I thought that. – HpTerm Nov 13 '13 at 08:56
  • But as long as it as nothing to do with your 'progress' my comments are useless and I'll remove them. – HpTerm Nov 13 '13 at 08:57
2

int can hold a max value of 2147483647, you can check it from doc here. When you multiply your temp with 100, it overflows and gives out wrong value. Just multiply 100 after you divide by size.

Lawrence Choy
  • 6,088
  • 1
  • 20
  • 30