2015-06-09 2 views
1

Я пытаюсь разработать приложение, которое извлекает электронные письма с сервера POP3, который не является Google, и у меня много проблем.
Я использую библиотеку JavaMail и следую руководству TutorialsPoint. Их пример для pop3 отлично работает на Eclipse/desktop, но когда я перемещаю код на Android, он никогда не работает, и я расстроен.
В LogCat я получаю все кучи ошибок первого из которых гласит, чтоКак я могу получать электронные письма на Android?

W/System.err: android.os.NetworkOnMainThreadException, даже если я использую AsyncTask (вероятно, не правильно).

Есть ли способ, которым я могу исправить работу AsyncTask правильно?

Кроме того, есть ли способ, которым я могу сделать что-то подобное, не используя профессиональное приложение, такое как K-9 Mail?

код, если кто-то заинтересован:

public class FetchPop extends AsyncTask{ 

    public static void fetch(String pop3Host, String storeType, String user, 
          String password) { 
     try { 
      // create properties field 
      Properties properties = new Properties(); 
      properties.put("mail.store.protocol", "pop3"); 
      properties.put("mail.pop3.host", pop3Host); 
      properties.put("mail.pop3.port", "995"); 
      properties.put("mail.pop3.starttls.enable", "true"); 
      Session emailSession = Session.getDefaultInstance(properties); 
      // emailSession.setDebug(true); 

      // create the POP3 store object and connect with the pop server 
      Store store = emailSession.getStore("pop3s"); 

      store.connect(pop3Host, user, password); 

      // create the folder object and open it 
      Folder emailFolder = store.getFolder("INBOX"); 
      emailFolder.open(Folder.READ_ONLY); 

      BufferedReader reader = new BufferedReader(new InputStreamReader(
        System.in)); 

      // retrieve the messages from the folder in an array and print it 
      Message[] messages = emailFolder.getMessages(); 
      Log.d("No. messages:", messages.length + ""); //just the number at first 


/*for (int i = 0; i < messages.length; i++) { 
       Message message = messages[i]; 
       writePart(message); 
       String line = reader.readLine(); 
       if ("YES".equals(line)) { 
        message.writeTo(System.out); 
       } else if ("QUIT".equals(line)) { 
        break; 
       } 
      }*/ 
      // close the store and folder objects 
      emailFolder.close(false); 
      store.close(); 

     } catch (NoSuchProviderException e) { 
      e.printStackTrace(); 
     } catch (MessagingException e) { 
      e.printStackTrace(); 
     } /*catch (IOException e) { 
      e.printStackTrace(); 
     }*/ catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 


     @Override 
     protected Object doInBackground(Object[] params) { 
      String host = "pop.gmail.com";// I tried google's pop 
      String mailStoreType = "pop3"; 
      String username = 
        "myusername";// change accordingly 
      String password = "notmyrealpass";// change accordingly 

      //Call method fetch 
      fetch(host, mailStoreType, username, password); 
      Log.d("mytag","done!"); 
      return null; 
     } 

    public void GO() { 
     doInBackground(null); 
    } 





    /* 
    * This method checks for content-type 
    * based on which, it processes and 
    * fetches the content of the message 
    */ 
    public static void writePart(Part p) throws Exception { 
     if (p instanceof Message) 
      //Call methos writeEnvelope 
      writeEnvelope((Message) p); 

     /* System.out.println("----------------------------"); 
     System.out.println("CONTENT-TYPE: " + p.getContentType());*/ 

     //check if the content is plain text 
     if (p.isMimeType("text/plain")) { 
      System.out.println("This is plain text"); 
      System.out.println("---------------------------"); 
      System.out.println((String) p.getContent()); 
     } 
     //check if the content has attachment 
     else if (p.isMimeType("multipart/*")) { 
      System.out.println("This is a Multipart"); 
      System.out.println("---------------------------"); 
      Multipart mp = (Multipart) p.getContent(); 
      int count = mp.getCount(); 
      for (int i = 0; i < count; i++) 
       writePart(mp.getBodyPart(i)); 
     } 
     //check if the content is a nested message 
     else if (p.isMimeType("message/rfc822")) { 
      System.out.println("This is a Nested Message"); 
      System.out.println("---------------------------"); 
      writePart((Part) p.getContent()); 
     } 
     //check if the content is an inline image 
     else if (p.isMimeType("image/jpeg")) { 
      System.out.println("--------> image/jpeg"); 
      Object o = p.getContent(); 

      InputStream x = (InputStream) o; 
      // Construct the required byte array 
      int i; 
      byte[] bArray = new byte[0]; 
      System.out.println("x.length = " + x.available()); 
      while ((i = (int) ((InputStream) x).available()) > 0) { 
       int result = (int) (((InputStream) x).read(bArray)); 
       if (result == -1) 
        i=0; 
       bArray = new byte[x.available()]; 

       break; 
      } 
      FileOutputStream f2 = new FileOutputStream("/tmp/image.jpg"); 
      f2.write(bArray); 
     } 
     else if (p.getContentType().contains("image/")) { 
      System.out.println("content type" + p.getContentType()); 
      File f = new File("image" + new Date().getTime() + ".jpg"); 
      DataOutputStream output = new DataOutputStream(
        new BufferedOutputStream(new FileOutputStream(f))); 
      com.sun.mail.util.BASE64DecoderStream test = 
        (com.sun.mail.util.BASE64DecoderStream) p 
          .getContent(); 
      byte[] buffer = new byte[1024]; 
      int bytesRead; 
      while ((bytesRead = test.read(buffer)) != -1) { 
       output.write(buffer, 0, bytesRead); 
      } 
     } 
     else { 
      Object o = p.getContent(); 
      if (o instanceof String) { 
       System.out.println("This is a string"); 
       System.out.println("---------------------------"); 
       System.out.println((String) o); 
      } 
      else if (o instanceof InputStream) { 
       System.out.println("This is just an input stream"); 
       System.out.println("---------------------------"); 
       InputStream is = (InputStream) o; 
       is = (InputStream) o; 
       int c; 
       while ((c = is.read()) != -1) 
        System.out.write(c); 
      } 
      else { 
       System.out.println("This is an unknown type"); 
       System.out.println("---------------------------"); 
       System.out.println(o.toString()); 
      } 
     } 

    } 
    /* 
    * This method would print FROM,TO and SUBJECT of the message 
    */ 
    public static void writeEnvelope(Message m) throws Exception { 
     System.out.println("This is the message envelope"); 
     System.out.println("---------------------------"); 
     Address[] a; 

     // FROM 
     if ((a = m.getFrom()) != null) { 
      for (int j = 0; j < a.length; j++) 
       System.out.println("FROM: " + a[j].toString()); 
     } 

     // TO 
     if ((a = m.getRecipients(Message.RecipientType.TO)) != null) { 
      for (int j = 0; j < a.length; j++) 
       System.out.println("TO: " + a[j].toString()); 
     } 

     // SUBJECT 
     if (m.getSubject() != null) 
      System.out.println("SUBJECT: " + m.getSubject()); 

    } 

} 

ответ

0

Похоже, что вы не используете AsyncTask правильно, особенно видя, что у вас есть GO() метод, который напрямую вызывает doInBackground(). Удалите метод GO(), в этом нет необходимости.

Правильный способом выполнить AsyncTask является использование execute() метода, который вызывает doInBackground() и запускает его на рабочий поток, который будет устранить NetworkOnMainThreadException ошибки времени выполнения, которые вы получаете в настоящее время.

Итак, помимо использования библиотеки, специфичной для Android, исправьте AsyncTask так, чтобы она фактически запускала метод doInBackground() в рабочем потоке вместо основного потока пользовательского интерфейса.

В целом лучше использовать дженерики и varargs, а не только doInBackground() взять параметр Object[] в качестве параметра. Было бы полезно иметь возможность передавать имя пользователя и пароль каждый раз, когда вы запускаете AsyncTask, поэтому сделайте так, чтобы он принял параметр vargs.

public class FetchPop extends AsyncTask<String, Void, Void> { 

    @Override 
    protected Void doInBackground(String... params) { 
     String host = "pop.gmail.com";// I tried google's pop 
     String mailStoreType = "pop3"; 

     String username = params[0]; //passed in through the execute() method  
     String password = params[1]; //passed in through the execute() method 

     //Call method fetch 
     fetch(host, mailStoreType, username, password); 
     Log.d("mytag", "done!"); 
     return null; 
    } 
} 

Затем, чтобы правильно выполнить AsyncTask, используйте метод execute(), и передать имя пользователя и пароль:

//First get the username and password from the user through the UI 
String user = "myusername"; // change accordingly 
String pass = "notmyrealpass"; // change accordingly 
new FetchPop().execute(user, pass); 

Кроме того, обратите внимание, что любые связанные с UI код нужно будет поместить в onPostExecute() , так как все задачи пользовательского интерфейса должны выполняться в основном потоке пользовательского интерфейса в Android.

Для получения более подробной информации о AsyncTasks, есть много хорошей информации в this question and the answers posted

+0

Это сработало! Я знаю, что лучше передавать такие переменные. Это было всего лишь скопировать пасту из TutorialsPoint, чтобы я начал. Я буду разлагать этот класс в нескольких методах для моего проекта, теперь, когда знаю, что он работает. Спасибо огромное! – ogrishmania

+0

@ogrishmania Отлично, рад, что он работает на вас сейчас! –

0

Попробуйте с этой библиотеки https://code.google.com/p/javamail-android/.

Не знаю точное состояние Lib, но у них есть хороший пример в этом блоге (http://www.jondev.net/articles/Sending_Emails_without_User_Intervention_%28no_Intents%29_in_Android), и они говорят,

«это специальная версия API JavaMail, который был написан специально для Android ".

+0

Я определенно попробовать его. Благодаря! – ogrishmania

Смежные вопросы