zxing onActivityResult 不在 Fragment 中仅在 Activity 中调用

Posted

技术标签:

【中文标题】zxing onActivityResult 不在 Fragment 中仅在 Activity 中调用【英文标题】:zxing onActivityResult not called in Fragment only in Activity 【发布时间】:2013-11-29 13:29:54 【问题描述】:

我在使用 zxing onActivityResult() 时遇到了一些问题。

正如您在代码中看到的那样,我确实正确地调用了https://code.google.com/p/zxing/wiki/ScanningViaIntent 中描述的新意图。

问题是如何在 Fragment 中捕获 onActivityResult(),因为我需要在 Fragmnet 中而不是在 Activity 中的数据?

package com.example.testingcodereading;

import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;

public class MainFragment extends Fragment 

private Button mButtonXZing;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle     savedInstanceState)
    View v = inflater.inflate(R.layout.fragment_main, parent, false);

    mButtonXZing = (Button) v.findViewById(R.id.button_xzing);
    mButtonXZing.setOnClickListener(new View.OnClickListener() 
        @Override
        public void onClick(View v) 

            IntentIntegrator integrator = new IntentIntegrator(getActivity());
            integrator.initiateScan();

        
    );

    return v;



@Override 
public void onActivityResult(int requestCode, int resultCode, Intent intent) 
    System.out.println("never here");
      IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
      if (scanResult != null) 
        // handle scan result
      
      // else continue with any other code you need in the method
    



public class MainActivity extends FragmentActivity 

@Override
protected void onCreate(Bundle savedInstanceState) 
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

FragmentManager fm = getSupportFragmentManager();
Fragment f = fm.findFragmentById(R.id.fragmentContainer);

if(f == null)
  f = new MainFragment();
  fm.beginTransaction()
    .add(R.id.fragmentContainer, f)
    .commit();



@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) 
    super.onActivityResult(requestCode, resultCode, intent);
    System.out.println("the code is catch");



【问题讨论】:

使用Integrator.forSupportFragment(this)Integrator.forFragment(this),具体取决于您使用的是哪个Fragment 【参考方案1】:

正如Martynnw 指出的那样,问题是调用fragment.startActivityForResult 而不是activity.startActivityForResult。所以只需使用下一个包装器:

import android.content.Intent;
import android.support.v4.app.Fragment;

import com.google.zxing.integration.android.IntentIntegrator;

public final class FragmentIntentIntegrator extends IntentIntegrator 

    private final Fragment fragment;

    public FragmentIntentIntegrator(Fragment fragment) 
        super(fragment.getActivity());
        this.fragment = fragment;
    

    @Override
    protected void startActivityForResult(Intent intent, int code) 
        fragment.startActivityForResult(intent, code);
    

【讨论】:

但是你如何使用这个类? @PhilippLudwig 只需替换 IntentIntegrator integrator = new IntentIntegrator(MyActivity.this);与 FragmentIntentIntegrator 积分器 = new FragmentIntentIntegrator(MyFragment.this); 使用Integrator.forSupportFragment(this)Integrator.forFragment(this),具体取决于您使用的是哪个Fragment【参考方案2】:
integrator.initiateScan();

把上面那行改成

integrator.forSupportFragment(fragment_name.this).initiateScan();

【讨论】:

我尝试在片段中使用它。可以显示二维码摄像头,但是扫码时不会调用onActivityResult @user1872384 我遇到了同样的问题,直到我意识到扫描仪以横向模式启动并且我正在旋转正在重新启动活动的手机。如果您不旋转手机,它对我有用。我最终将相机设置为纵向模式以避免这种情况。【参考方案3】:

替代ZXing Android Embedded,实现:

import com.google.zxing.integration.android.IntentIntegrator;
import com.google.zxing.integration.android.IntentResult;

@Override
public void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);

    new IntentIntegrator(this).initiateScan(); // `this` is the current Activity


从片段中使用:

IntentIntegrator.forFragment(this).initiateScan(); // `this` is the current Fragment

// If you're using the support library, use: 
// IntentIntegrator.forSupportFragment(this) instead.

得到结果:

@Override
public void onActivityResult(int requestCode, int resultCode,Intent data) 
    IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
    if(result != null) 
        if(result.getContents() == null) 
            Toast.makeText(this, "Cancelled", Toast.LENGTH_LONG).show();
         else 
        Toast.makeText(this, "Scanned: " + result.getContents(), Toast.LENGTH_LONG).show();
    
     else 
        super.onActivityResult(requestCode, resultCode, data);
    

more info and options

【讨论】:

【参考方案4】:

如果有人有同样的问题,这是我的解决方案。

package com.example.testingcodereading;

import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;

public class MainActivity extends FragmentActivity 

@Override
protected void onCreate(Bundle savedInstanceState) 
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fragment);

FragmentManager fm = getSupportFragmentManager();
Fragment f = fm.findFragmentById(R.id.fragmentContainer);

if (f == null) 
  f = MainFragment.newInstance("Start Application");
  fm.beginTransaction().add(R.id.fragmentContainer, f).commit();



@Override
protected void onActivityResult(int requestCode, int resultCode,
  Intent intent) 
super.onActivityResult(requestCode, resultCode, intent);
System.out.println("the code is catch");

IntentResult scanResult = IntentIntegrator.parseActivityResult(
    requestCode, resultCode, intent);
// handle scan result
if (scanResult != null) 
  FragmentManager fm = getSupportFragmentManager();

  Fragment newFrame = MainFragment.newInstance(scanResult.toString());

  fm.beginTransaction().replace(R.id.fragmentContainer, newFrame).commit();






package com.example.testingcodereading;

import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.test.suitebuilder.annotation.MediumTest;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;

public class MainFragment extends Fragment 

private static final String EXTRA_CODE = "com.example.testingcodereading.code";
private Button mButtonXZing;
private TextView mTextView;


public static MainFragment newInstance(String code) 
Bundle args = new Bundle();
args.putSerializable(EXTRA_CODE, code);

MainFragment fragment = new MainFragment();
fragment.setArguments(args);

return fragment;



@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle    savedInstanceState)
View v = inflater.inflate(R.layout.fragment_main, parent, false);

mTextView = (TextView) v.findViewById(R.id.text_code);
mTextView.setText((String) getArguments().getSerializable(EXTRA_CODE));

mButtonXZing = (Button) v.findViewById(R.id.button_xzing);
mButtonXZing.setOnClickListener(new View.OnClickListener() 
  @Override
  public void onClick(View v) 

    IntentIntegrator integrator = new IntentIntegrator(getActivity());
    integrator.initiateScan();
  
);

return v;



@Override 
public void onActivityResult(int requestCode, int resultCode, Intent intent) 
super.onActivityResult(requestCode, resultCode, intent);
System.out.println("never here");
IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
if (scanResult != null) 
  // handle scan result

// else continue with any other code you need in the method



【讨论】:

足够好。需要注意的一件事是上下文,因为片段使用的上下文是从托管片段的父 Activity 继承的,然后一旦片段被实例化,它就会接受这个上下文并在它自己的空间中工作。 从 Google 的文档 (developer.android.com/guide/components/fragments.html) 中了解有关操作片段及其实际工作方式的更多信息 为什么你没有使用以前的分析器。这是更优雅的设计)【参考方案5】:

我遇到了这个问题,用下面的代码解决了:

IntentIntegrator integrator = new IntentIntegrator(getActivity());                
integrator.forSupportFragment(MyFragment.this).initiateScan();

【讨论】:

【参考方案6】:

应该这样调用扫描:

IntentIntegrator.forSupportFragment(YourFragment.this)
                    .setDesiredBarcodeFormats(IntentIntegrator.QR_CODE)
                    .setBeepEnabled(true/false)
                    .setPrompt("blahblahblah")
                    .initiateScan();

然后就可以在Fragment的onActivityResult中得到扫描结果了

【讨论】:

【参考方案7】:

确保您的Activity 中的OnActivityResult 正在调用super.OnActivityResult()。这应该确保它也被 Fragment 调用。

或者,您可以修改IntentIntegrator 代码,使其在Fragment 上调用StartActivityResult,方法是将片段传递给构造函数,或者将其传递给initiateScan

【讨论】:

我确实通过替换片段解决了问题。这是解决方案:androide-examples.blogspot.com/2013/11/…【参考方案8】:

尝试在Fragment 中创建IntentIntegrator 对象,如下所示。

        val scanIntegrator = IntentIntegrator.forSupportFragment(this@HomeFragment)
        scanIntegrator.setPrompt("Scan")
        scanIntegrator.setBeepEnabled(true)
        //The following line if you want QR code
        scanIntegrator.setDesiredBarcodeFormats(IntentIntegrator.QR_CODE_TYPES)
        scanIntegrator.captureActivity = CaptureActivityAnyOrientation::class.java
        scanIntegrator.setOrientationLocked(true)
        scanIntegrator.setBarcodeImageEnabled(true)
        scanIntegrator.initiateScan()

【讨论】:

【参考方案9】:
public void scanCode() 
        IntentIntegrator.forSupportFragment(this).
        setCaptureActivity(CaptureAct.class).
        setOrientationLocked(false)
        .setDesiredBarcodeFormats(IntentIntegrator.PRODUCT_CODE_TYPES)
        .setPrompt("Scanning code")
        .initiateScan();
    

【讨论】:

【参考方案10】:

解决方案:如何管理它的基本示例

主要活动

public static int tapTrick = 0;

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) 
    //super.onActivityResult(requestCode, resultCode, data);
    if(tapTrick!=0 && tapTrick==1) 
        Tab1.onActivityResult(requestCode, resultCode, data, MainActivity.this);
    else if (tapTrick!=0 && tapTrick==2)
        //Tab2.onActivityResult(requestCode, resultCode, data, MainActivity.this);
    

片段 1

MainActivity.tapTrick=1; // onCreateView  or onClick (load images/files)

 public static void onActivityResult(int requestCode, int resultCode, Intent intent, Context context) 
 

片段 2

MainActivity.tapTrick=2;
 public static void onActivityResult(int requestCode, int resultCode, Intent intent, Context context) 
 

片段 x

MainActivity.tapTrick=x;
 public static void onActivityResult(int requestCode, int resultCode, Intent intent, Context context) 
 

【讨论】:

以上是关于zxing onActivityResult 不在 Fragment 中仅在 Activity 中调用的主要内容,如果未能解决你的问题,请参考以下文章

Zxing QR扫描仪onActivityResult未在片段中调用[重复]

onActivityResult 不在 Fragment 中调用

从画廊返回后,不在 Fragment 中调用 onActivityResult

安卓调用zxing扫码之后返回结果为空

Android 使用Zxing报错:Channel is unrecoverably broken and will be disposed!

Android 使用Zxing报错:Channel is unrecoverably broken and will be disposed!