startActivity в подклассе приложения - PullRequest
6 голосов
/ 13 октября 2011

У меня есть небольшое приложение для Android, в котором я указываю свое приложение напрямую и выполняю некоторые настройки для всего приложения в ApplicationSubclass 'onCreate, но я получаю следующую ошибку (обратите внимание, я знаю о FLAG_ACTIVITY_NEW_TASK):

Caused by: android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity  context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
    at android.app.ContextImpl.startActivity(ContextImpl.java:644)
    at android.content.ContextWrapper.startActivity(ContextWrapper.java:258)
    at somePart.ofA.nameSpace.ApplicationSubclass.sendNotificationEmail(ApplicationSubclass.java:186)

Я вызываю этот sendNotificationEmail, когда генерируются некоторые исключения, и я их перехватываю, чтобы пользователь приложения мог отправить небольшое электронное письмо с информацией об исключении, чтобы мне было легче исправить все, что может возникнуть, или направлять их на исправление их проблемы.

Вот некоторые из соответствующих кодов:

manifest.xml:

<application android:label="@string/app_name" android:icon="@drawable/icon" android:name=".ApplicationSubclass">
// ... some stuff, including all of my app's activities
</application>

ApplicationSubclass определяется как:

public class ApplicationSubclass extends Application {
   // Multiple methods, including an override of onCreate

  public void sendNotificationEmail(String emailBody) {
      Intent emailIntent = new Intent(Intent.ACTION_SEND);
      emailIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
      emailIntent.setType("text/html");
      emailIntent.putExtra(Intent.EXTRA_EMAIL, notificationRecipients);
      emailIntent.putExtra(Intent.EXTRA_SUBJECT, "MyAppName Error");
      emailIntent.putExtra(Intent.EXTRA_TEXT, emailBody);
      try {
          startActivity(Intent.createChooser(emailIntent, "An error has occurred! Send an error report?"));
      } catch (ActivityNotFoundException e) {
          // If there is nothing that can send a text/html MIME type
          e.printStackTrace();
      }
   }
}

Я хотел бы знать, почему это происходит. Я прочитал некоторую документацию, я искал ответы на вопросы о StackOverflow и Интернете в целом. Мне кажется, что я должен быть в порядке, так как я устанавливаю FLAG_ACTIVITY_NEW_TASK, однако это явно не так!

Просто я даже не могу пытаться сделать это из контекста Приложения? Должен ли я быть в Activity в моем приложении, когда я пытаюсь это сделать? Было бы немного досадно, если бы пришлось перепроектировать эту проблему, и возможность отправлять электронные письма об исключениях была бы весьма полезной!

РЕДАКТИРОВАТЬ : Рич задал хороший вопрос, и поэтому, черт возьми, я бы хотел заняться этим в первую очередь? Ответ прост: в приложении загружаются данные, которые могут не работать, и я бы хотел, чтобы пользователь мог отправлять некоторые из этих данных об ошибках, когда это происходит.

Причина, по которой это происходит в Приложении, а не в активности, заключается в том, что существуют переменные состояния приложения, которые я не хочу терять при каждом вращении устройства. Когда я узнал о том, что onPause и onCreate вызываются при вращении (для активаций), я переделал этот код в приложение (что прекрасно работает!). Я на самом деле пробовал решение отправить их onConfigurationChanged и переопределить этот метод в моей деятельности, но это грязно и по какой-то причине, несмотря на то, что в моем манифесте было указано android:configChanges="keyboardHidden|orientation", это не помогло мне. Я уверен, что я мог бы использовать эту опцию, но я бы предпочел оставить все как есть (оно чище) и получить возможность кому-то писать по электронной почте!

Ответы [ 2 ]

17 голосов
/ 13 октября 2011

Ах!Я понял, что я сделал, это довольно просто!Я неправильно настроил FLAG_ACTIVITY_NEW_TASK!Глупо, я пропустил, что Intent.createChooser (..., ...) вернет новое намерение, поэтому вы должны установить флаг для chooser Intent, а не для ACTION_SEND Intent.

Не все так запутанно, когда ты думаешь об этом, и я не могу поверить, что я упустил это из виду!

Так что, если кто-нибудь когда-нибудь сделает то, что я сделал, вот, пожалуйста:

public void sendNotificationEmail(String emailBody) {
        Intent emailIntent = new Intent(Intent.ACTION_SEND);
        emailIntent.setType("text/html");
        emailIntent.putExtra(Intent.EXTRA_EMAIL, notificationRecipients);
        emailIntent.putExtra(Intent.EXTRA_SUBJECT, "MyAppName Error");
        emailIntent.putExtra(Intent.EXTRA_TEXT, emailBody);
        Intent emailChooser = Intent.createChooser(emailIntent, "An error has occurred! Send an error report?");
        emailChooser.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        try {
            startActivity(emailChooser);
        } catch (ActivityNotFoundException e) {
            // If there is nothing that can send a text/html MIME type
            e.printStackTrace();
        }
    }
6 голосов
/ 13 октября 2011

Я запустил действие (чтобы повторно зарегистрировать пользователя при потере сеанса) из моего класса, который подкласс из Приложения, как следует:

public boolean relogin(Activity act) {      
    Intent intent = new Intent(act,ActivityLogin.class);    
    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);     
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
    startActivity(intent);              
    act.finish();// here i finish my current activity
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...