Как использовать Intent.ACTION_APP_ERROR в качестве средства для платформы "обратной связи" в Android?

Я хотел бы повторно использовать Intent.ACTION_BUG_REPORT в своем приложении в качестве простого способа получения отзывов пользователей.

Карты Google используют его в качестве опции "Обратная связь". Но мне не удалось запустить событие.

Я использую следующее в onOptionsItemSelected(MenuItem item):

    Intent intent = new Intent(Intent.ACTION_BUG_REPORT);
    startActivity(intent);

И по моему AndroidManifest.xml Я объявил следующее под моим Activity:

    <intent-filter>
       <action android:name="android.intent.action.BUG_REPORT" />
       <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>

Тем не менее, кажется, что ничего не происходит, кроме экрана "мигать", когда я выбираю вариант. Приложение или намерение не падает, ничего не регистрируется. Пробовал как в эмуляторе, так и на устройстве ICS 4.0.4.

Я явно что-то упустил, но что?

редактировать

Intent.ACTION_APP_ERROR (постоянная android.intent.action.BUG_REPORT) был добавлен в API level 14, http://developer.android.com/reference/android/content/Intent.html

4 ответа

Решение

Это было решено с помощью ссылки в @TomTasche комментарии выше. Используйте встроенный механизм обратной связи на Android.

В моем AndroidManifest.xml Я добавил следующее к <Activity> откуда я хочу позвонить агенту обратной связи.

<intent-filter>
   <action android:name="android.intent.action.APP_ERROR" />
   <category android:name="android.intent.category.DEFAULT" />
</intent-filter>

И я сделал простой метод под названием sendFeedback() (код из поста TomTasche)

@SuppressWarnings("unused")
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
private void sendFeedback() {
    try {
        int i = 3 / 0;
    } catch (Exception e) {
    ApplicationErrorReport report = new ApplicationErrorReport();
    report.packageName = report.processName = getApplication().getPackageName();
    report.time = System.currentTimeMillis();
    report.type = ApplicationErrorReport.TYPE_CRASH;
    report.systemApp = false;

    ApplicationErrorReport.CrashInfo crash = new ApplicationErrorReport.CrashInfo();
    crash.exceptionClassName = e.getClass().getSimpleName();
    crash.exceptionMessage = e.getMessage();

    StringWriter writer = new StringWriter();
    PrintWriter printer = new PrintWriter(writer);
    e.printStackTrace(printer);

    crash.stackTrace = writer.toString();

    StackTraceElement stack = e.getStackTrace()[0];
    crash.throwClassName = stack.getClassName();
    crash.throwFileName = stack.getFileName();
    crash.throwLineNumber = stack.getLineNumber();
    crash.throwMethodName = stack.getMethodName();

    report.crashInfo = crash;

    Intent intent = new Intent(Intent.ACTION_APP_ERROR);
    intent.putExtra(Intent.EXTRA_BUG_REPORT, report);
    startActivity(intent);
    }
}

И из моего SettingsActivity Я называю это так:

      findPreference(sFeedbackKey).setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
          public final boolean onPreferenceClick(Preference paramAnonymousPreference) {
              sendFeedback();
              finish();
              return true;
          }
      });         

Проверена работа с Android 2.3.7 и 4.2.2.

Когда sendFeedback() При вызове метода открывается диалоговое окно "Выполнить действие с помощью", где пользователь может выбрать один из трех действий / значков.

Завершить действие с помощью

Вызывающее приложение, которое возвращается в приложение, а также Google Play и агент обратной связи. Выбор либо Google Play Storeили же Send feedback откроет встроенный агент обратной связи Android как задумано.

Отправить отзыв

Я не исследовал дальше, можно ли пропустить шаг "Выполнить действие с помощью", возможно, с правильными параметрами, переданными в Intent, Пока что это именно то, что я хотел сейчас.

Пожалуйста, не смешивайте два разных намерения Intent.ACTION_BUG_REPORT а также Intent.ACTION_APP_ERROR, Первый предназначен для старых отчетов об ошибках и обратной связи и поддерживается API v1. Второй - для отправки расширенных отчетов об ошибках (поддерживает ApplicationErrorReport объект, где можно хранить много полезной информации) и был добавлен в API v14.

Для отправки отзыва я тестирую приведенный ниже код в моей новой версии приложения (он также создает скриншот активности). Это начинается com.google.android.gms.feedback.FeedbackActivity, который является частью сервисов Google Play. Но вопрос, где тогда я найду отзывы?!

protected void sendFeedback(Activity activity) {
    activity.bindService(new Intent(Intent.ACTION_BUG_REPORT), new FeedbackServiceConnection(activity.getWindow()), BIND_AUTO_CREATE);
}

protected static class FeedbackServiceConnection implements ServiceConnection {
    private static int MAX_WIDTH = 600;
    private static int MAX_HEIGHT = 600;

    protected final Window mWindow;

    public FeedbackServiceConnection(Window window) {
        this.mWindow = window;
    }

    public void onServiceConnected(ComponentName name, IBinder service) {
        try {
            Parcel parcel = Parcel.obtain();
            Bitmap bitmap = getScreenshot();
            if (bitmap != null) {
                bitmap.writeToParcel(parcel, 0);
            }
            service.transact(IBinder.FIRST_CALL_TRANSACTION, parcel, null, 0);
            parcel.recycle();
        } catch (RemoteException e) {
            Log.e("ServiceConn", e.getMessage(), e);
        }
    }

    public void onServiceDisconnected(ComponentName name) { }

    private Bitmap getScreenshot() {
        try {
            View rootView = mWindow.getDecorView().getRootView();
            rootView.setDrawingCacheEnabled(true);
            Bitmap bitmap = rootView.getDrawingCache();
            if (bitmap != null)
            {
                double height = bitmap.getHeight();
                double width = bitmap.getWidth();
                double ratio = Math.min(MAX_WIDTH / width, MAX_HEIGHT / height);
                return Bitmap.createScaledBitmap(bitmap, (int)Math.round(width * ratio), (int)Math.round(height * ratio), true);
            }
        } catch (Exception e) {
            Log.e("Screenshoter", "Error getting current screenshot: ", e);
        }
        return null;
    }
}

Обратите внимание, что решение о сбое (как здесь) недоступно в версиях Android, выпущенных до ICS.

Короче, более простая версия решения "кадеруд" ( здесь):

  @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
  private void sendFeedback()
    {
    final Intent intent=new Intent(Intent.ACTION_APP_ERROR);
    final ApplicationErrorReport report=new ApplicationErrorReport();
    report.packageName=report.processName=getApplication().getPackageName();
    report.time=System.currentTimeMillis();
    report.type=ApplicationErrorReport.TYPE_NONE;
    intent.putExtra(Intent.EXTRA_BUG_REPORT,report);
    final PackageManager pm=getPackageManager();
    final List<ResolveInfo> resolveInfos=pm.queryIntentActivities(intent,0);
    if(resolveInfos!=null&&!resolveInfos.isEmpty())
      {
      for(final ResolveInfo resolveInfo : resolveInfos)
        {
        final String packageName=resolveInfo.activityInfo.packageName;
        // prefer google play app for sending the feedback:
        if("com.android.vending".equals(packageName))
          {
          // intent.setPackage(packageName);
          intent.setClassName(packageName,resolveInfo.activityInfo.name);
          break;
          }
        }
      startActivity(intent);
      }
    else
      {
      // handle the case of not being able to send feedback
      }
    }

Начиная с уровня API 14, вы можете попробовать использовать ACTION_APP_ERROR намерение, но приложение должно быть доступно в магазине Google Play, чтобы это работало.

Intent intent = new Intent(Intent.ACTION_APP_ERROR);
startActivity(intent);
//must be available on play store
Другие вопросы по тегам