【问题标题】:zxing onActivityResult not called in Fragment only in Activityzxing onActivityResult 不在 Fragment 中仅在 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

标签: android android-intent zxing onactivityresult


【解决方案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

        【讨论】:

        【解决方案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) {
             }
            

            【讨论】:

              猜你喜欢
              • 2019-07-20
              • 2015-04-14
              • 2013-06-09
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-02-08
              • 1970-01-01
              • 2019-07-08
              相关资源
              最近更新 更多