3

I have been fighting for like 6 hours with this now. I have followed Dropbox's "tutorials" (if they can be called that, because they are awfully poor), played with the DBRoulette example, and done tons of stuff to get my app working.

My app can Authenticate with no problems. But I can't upload anything despite doing exactly what the tutorial is doing:

This is the little snippet of code I have (this is to save a created note on the phone itself and then upload to Dropbox):

        saveBtn.setOnClickListener(new OnClickListener()
    {
        @Override
        public void onClick(View view)
        {
            try
            {
                //Create the directory if it doesn't exist. If it does exist the next two line won't do anything.
                File dropNotesDir = new File(Environment.getExternalStorageDirectory() + "/documents/AppData/Dropnotes/");
                dropNotesDir.mkdirs();
                //-----------------------------------------------------------------------------------------------
                String wholeNoteString = noteBody.getText().toString();
                //Now we create the title of the txt file. It will be the first line of the whole note. The name will get truncated to 32 characters
                //if it's too long.
                String noteTitle;
                if(wholeNoteString.indexOf("\n") >= 0) //New line character found.
                {
                    noteTitle = wholeNoteString.substring(0, wholeNoteString.indexOf("\n"));
                    if(noteTitle.length() >= 32)
                    {
                        noteTitle = wholeNoteString.substring(0, 32);
                    }
                }
                else
                {
                    if(wholeNoteString.length() >= 32)
                    {
                        noteTitle = wholeNoteString.substring(0, 32);
                    }else
                    {
                        noteTitle = wholeNoteString;
                    }
                }
                if(extras.getString("file-mode").equals("modify"))
                {
                    //We will need to delete the existing file if it does exist to save the new one.
                    File existing = new File(Environment.getExternalStorageDirectory() + "/documents/AppData/Dropnotes/" + extras.getString("noteTitle"));
                    existing.delete();
                }
                File newNote = new File(Environment.getExternalStorageDirectory() + "/documents/AppData/Dropnotes/" + noteTitle + ".txt");
                PrintWriter newNoteWriter = new PrintWriter(new FileOutputStream(newNote));
                newNoteWriter.print(noteBody.getText().toString());
                newNoteWriter.close();

                //TRYING TO UPLOAD TO DROPBOX HERE
                File fileToUpload = new File(Environment.getExternalStorageDirectory() + "/documents/AppData/Dropnotes/" + noteTitle + ".txt");
                FileInputStream file2Uis = new FileInputStream(fileToUpload);
                Entry newEntry = mDBApi.putFile("/" + noteTitle + ".txt", file2Uis, fileToUpload.length(), null, null);
                //END OF TRYING TO UPLOAD TO DROPBOX HERE

                Toast.makeText(view.getContext(), "Saved successfully", Toast.LENGTH_SHORT).show();
                finish();
            } catch (FileNotFoundException e)
            {
                Toast.makeText(view.getContext(), "File not found: " + e.getMessage(), Toast.LENGTH_SHORT).show();
                e.printStackTrace();
            } catch(Exception e)
            {
                Toast.makeText(view.getContext(), "Some bizarre exception occured: " + e.getClass().toString(), Toast.LENGTH_SHORT).show();
                e.printStackTrace();
            }
        }

    });

It's giving me a NetworkOnMainThreadException and I don't know why. I'm trying to follow the section titled "Uploading a File" here. What baffles me about their snippet is that they are not even trying to catch the exception I'm getting thrown at...

Any help? I really need to get this working for next Friday.

Andy Ibanez
  • 12,104
  • 9
  • 65
  • 100
  • you getting `NetworkOnMainThreadException` because you're doing network stuff on main thread ... use AsyncTask – Selvin Jun 05 '12 at 06:54
  • 1
    **[Why Ice Cream Sandwich Crashes Your App](http://www.androiddesignpatterns.com/2012/06/app-force-close-honeycomb-ics.html)**. Check it out... it explains why this might occur. – Alex Lockwood Aug 02 '12 at 15:17

2 Answers2

7

Prior to Honeycomb SDK, it was allowed to perform network operation on the main thread. However, with Honeycomb, it is no longer allowed and a NetworkOnMainThreadException is thrown if a network operation is attempted in main/UI thread.

You need to perform network operations in a different thread. You can take a look at AsyncTask to achieve the same.

Rajesh
  • 15,724
  • 7
  • 46
  • 95
  • Thanks. I will try your solution tomorrow. I'm beaten right now but it looks like it's the right way to do it. – Andy Ibanez Jun 05 '12 at 07:00
  • 1
    Sorry for taking too long. I had to look for a tutorial to do this but I did it. Thank you so much for your help. – Andy Ibanez Jun 10 '12 at 03:20
-4

My guess is, the error caused by StrictMode.ThreadPolicy. you can't access network in the same UI thread.

try adding these lines to your code in oncreate

StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); 
StrictMode.setThreadPolicy(policy);
Rakshi
  • 6,796
  • 3
  • 25
  • 46
  • this policy is there for some reasons ... this solution is bad, m'kay – Selvin Jun 05 '12 at 06:55
  • Just out of curiosity, why was this answer voted down? Is it not the right way to do it? In other words, a really bad alternative? – Andy Ibanez Jun 05 '12 at 06:59
  • Hah, Selvin's comment didn't load till now. I see now. Thanks Selvin! – Andy Ibanez Jun 05 '12 at 07:00
  • 4
    @Sergio from Rajesh answer you can go http://developer.android.com/guide/practices/design/responsiveness.html ... and then you will know that if Main thread do not respond for 5 sec you'll get ANR ... so you can get ANR easly when there is no network available (or signal is weak) that's why you sould not use network operation on main thread (even if it's allowed on API < 11) ... so dissabling this policy is like shooting at own foot – Selvin Jun 05 '12 at 07:17