Как использовать 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#ACTION_APP_ERROR

Ответ 1

Это было решено с помощью ссылки в комментарии @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(), открывается "Полное действие с использованием" -диалога, где пользователь может выбрать один из трех действий/значков.

Complete action using

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

Send feedback

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

Ответ 2

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

Для отправки отзывов, я тестирую следующий код в своей новой версии APP (он также создает скриншот активности). Это начинается с 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;
    }
}

Ответ 3

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

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

  @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
      }
    }

Ответ 4

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

Intent intent = new Intent(Intent.ACTION_APP_ERROR);
startActivity(intent);
//must be available on play store