如何使用Intent.ACTION“应用程序”错误作为;“反馈”;Android中的框架?
我想在我的应用程序中重用Intent.ACTION\u BUG\u报告,作为获取用户反馈的简单方法 谷歌地图使用它作为他们的“反馈”选项。但我没有成功地启动这项活动 我在一个如何使用Intent.ACTION“应用程序”错误作为;“反馈”;Android中的框架?,android,android-intent,Android,Android Intent,我想在我的应用程序中重用Intent.ACTION\u BUG\u报告,作为获取用户反馈的简单方法 谷歌地图使用它作为他们的“反馈”选项。但我没有成功地启动这项活动 我在一个onoptionItemSelected(MenuItem项)中使用了以下内容: 在我的AndroidManifest.xml中,我在我的活动下声明了以下内容: <intent-filter> <action android:name="android.intent.action.BU
onoptionItemSelected(MenuItem项)
中使用了以下内容:
在我的AndroidManifest.xml
中,我在我的活动
下声明了以下内容:
<intent-filter>
<action android:name="android.intent.action.BUG_REPORT" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
从API第14级开始,您可以尝试使用操作应用程序错误
意图,但该应用程序需要在Google Play store上可用才能正常工作
Intent intent = new Intent(Intent.ACTION_APP_ERROR);
startActivity(intent);
//must be available on play store
这是在上面@TomTasche评论中链接的帮助下解决的
在我的AndroidManifest.xml
中,我在
中添加了以下内容,我想从中调用反馈代理
<intent-filter>
<action android:name="android.intent.action.APP_ERROR" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
通过我的设置活动
我称之为:
findPreference(sFeedbackKey).setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
public final boolean onPreferenceClick(Preference paramAnonymousPreference) {
sendFeedback();
finish();
return true;
}
});
已验证使用Android2.3.7和4.2.2。
调用sendfeived()
方法时,会打开一个“使用完成操作”对话框,用户可以在其中从三个操作/图标中进行选择
返回应用程序的呼叫应用程序,以及Google Play和反馈代理。选择Google Play Store
或Send feedback
将按预期打开内置的Android反馈代理
我没有进一步研究是否可以跳过“使用完成操作”-步骤,如果将正确的参数传递给Intent
,则很可能是可以的。到目前为止,这正是我想要的。请不要混淆两种不同的意图Intent.ACTION\u BUG\u REPORT
和Intent.ACTION\u APP\u ERROR
。第一个是为旧的错误报告和反馈而设计的,它受API v1的支持。第二个用于发送高级错误报告(支持ApplicationErrorReport
对象,您可以在其中存储大量有用的信息),并添加到API v14中
为了发送反馈,我正在我的新版本应用程序中测试下面的代码(它还创建了活动的屏幕截图)。这将启动com.google.android.gms.feedback.FeedbackActivity
,它是谷歌游戏服务的一部分。但问题是我在哪里能找到反馈
受保护的无效发送反馈(活动){
activity.bindService(新意图(Intent.ACTION\u BUG\u报告)、新反馈服务连接(activity.getWindow()),BIND\u AUTO\u CREATE);
}
受保护的静态类FeedbackServiceConnection实现ServiceConnection{
专用静态int最大宽度=600;
专用静态int最大高度=600;
受保护的最终窗口mWindow;
公共反馈服务连接(窗口){
this.mWindow=窗口;
}
服务连接上的公共无效(组件名称,IBinder服务){
试一试{
地块=地块。获取();
位图位图=getScreenshot();
if(位图!=null){
位图。writeToParcel(parcel,0);
}
service.transact(IBinder.FIRST\u CALL\u TRANSACTION,包裹,空,0);
包裹回收();
}捕获(远程异常){
Log.e(“ServiceConn”,e.getMessage(),e);
}
}
ServiceDisconnected上的公共无效(组件名称){}
私有位图getScreenshot(){
试一试{
View rootView=mWindow.getDecorView().getRootView();
setDrawingCacheEnabled(true);
位图Bitmap=rootView.getDrawingCache();
if(位图!=null)
{
double height=bitmap.getHeight();
double width=bitmap.getWidth();
双比值=数学最小值(最大宽度/宽度,最大高度/高度);
返回Bitmap.createScaledBitmap(位图,(int)Math.round(宽度*比率),(int)Math.round(高度*比率),true);
}
}捕获(例外e){
Log.e(“截图者”,“获取当前截图时出错:”,e);
}
返回null;
}
}
请注意,碰撞报告解决方案(如此处所示)在Android的ICS之前版本上不可用
“kaderud”()解决方案的一个简短版本:
@TargetApi(Build.VERSION\u code.ICE\u CREAM\u三明治)
私有void sendFeedback()
{
最终意图=新意图(意图.行动\应用\错误);
最终ApplicationErrorReport=新的ApplicationErrorReport();
report.packageName=report.processName=getApplication().getPackageName();
report.time=System.currentTimeMillis();
report.type=ApplicationErrorReport.type\u无;
intent.putExtra(intent.EXTRA_BUG_报告,报告);
最终PackageManager pm=getPackageManager();
最终列表resolveInfos=pm.querytentActivities(intent,0);
if(resolveInfos!=null&&!resolveInfos.isEmpty())
{
对于(最终解决方案信息解决方案信息:解决方案信息)
{
最后一个字符串packageName=resolveInfo.activityInfo.packageName;
//喜欢使用google play应用程序发送反馈:
if(“com.android.vending”.equals(packageName))
{
//intent.setPackage(packageName);
setClassName(packageName、resolveInfo.activityInfo.name);
打破
}
}
星触觉(意向);
}
其他的
{
//处理无法发送反馈的情况
}
}
这应该是从Google Play store下载的应用程序崩溃时使用的同一“代码”。根据@bogdan的回答,我能够想出实际向Android开发者控制台发送崩溃报告的代码(bogdan提供的代码不起作用)。你可以在这里找到代码:另请看一个更开放的问题,它有一个更全面的答案为什么
@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);
}
}
findPreference(sFeedbackKey).setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
public final boolean onPreferenceClick(Preference paramAnonymousPreference) {
sendFeedback();
finish();
return true;
}
});
@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
}
}