Android中Zxing横屏扫码时onActivityResult未触发问题求助
onActivityResult不触发的解决方案 我之前也碰到过一模一样的问题——竖屏扫码完全正常,切到横屏扫码后明明看起来扫成功了,但onActivityResult死活不回调,断点都打不到。结合你给出的代码和依赖版本,大概率是屏幕方向切换导致的Activity/Fragment重建,或者是旧版Zxing的横屏回调bug。下面给你几个亲测有效的解决方案:
1. 先升级Zxing依赖版本(最优先尝试)
你用的3.0.2版本太老了,后续版本修复了不少横屏相关的回调问题,而且compile已经被Gradle弃用,换成implementation:
implementation 'com.journeyapps:zxing-android-embedded:4.3.0' implementation 'com.google.zxing:core:3.4.1'
升级后直接测试横屏扫码,很多时候这个问题会直接消失。
2. 锁定扫码Activity的屏幕方向
如果升级后还是有问题,大概率是扫码过程中屏幕方向切换导致原Activity重建,回调上下文丢失。可以强制扫码界面固定方向:
方式一:启动扫码时锁定方向
// 用Fragment的方式启动扫码,同时锁定方向 IntentIntegrator integrator = IntentIntegrator.forSupportFragment(this); // 如果需要横屏扫码,就锁定横屏;如果无所谓,锁定竖屏更稳妥 integrator.setOrientationLocked(true); // 锁定竖屏,避免切换方向 // 或者如果你需要强制横屏: // integrator.setOrientationLocked(false); // 先允许自由旋转,再在Manifest里配置 integrator.initiateScan();
方式二:在Manifest里固定扫码Activity的方向
直接给Zxing的CaptureActivity加配置,避免它随系统方向切换:
<activity android:name="com.journeyapps.barcodescanner.CaptureActivity" android:screenOrientation="sensorLandscape" <!-- 固定横屏 --> <!-- 或者固定竖屏:android:screenOrientation="portrait" --> android:windowSoftInputMode="stateAlwaysHidden"/>
3. 避免主Activity因方向切换重建
如果你的主Activity允许横竖屏切换,切方向时会自动重建,导致原来的Fragment实例变成null(就是你提到的fragment == null的情况)。可以给主Activity加配置,让它方向切换时不重建:
在AndroidManifest.xml里给你的主Activity添加:
<activity android:name=".YourMainActivity" android:configChanges="orientation|screenSize|smallestScreenSize"> <!-- 其他配置 --> </activity>
这样方向切换时,系统会调用onConfigurationChanged而不是重建Activity,Fragment的实例就不会丢失了。如果需要处理方向切换后的UI调整,可以重写这个方法:
@Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); // 比如调整横屏后的布局大小等 }
4. 修复Fragment的回调传递逻辑
既然你提到调用时fragment为null,说明回调触发时原Fragment已经被销毁重建了。可以修改Activity的onActivityResult,主动获取当前显示的Fragment来传递结果:
@Override public void onActivityResult(final int requestCode, final int resultCode, final Intent intent) { super.onActivityResult(requestCode, resultCode, intent); // 主动获取当前在容器里的Fragment(替换成你的Fragment容器ID) Fragment currentFragment = getSupportFragmentManager().findFragmentById(R.id.your_fragment_container); if (currentFragment != null && Activity.RESULT_OK == resultCode) { currentFragment.onActivityResult(requestCode, resultCode, intent); } }
内容的提问来源于stack exchange,提问作者zundi

