zxing onActivityResult not called in Fragment only

2019-02-03 10:10发布

问题:

I'm having some issue with zxing onActivityResult().

As you can see in the code I did properly invoke new intent as described in https://code.google.com/p/zxing/wiki/ScanningViaIntent.

The question is how can I catch onActivityResult() in Fragment, since I need this data in my Fragmnet and not in 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");
}

}

回答1:

As Martynnw pointed out the issue is to call fragment.startActivityForResult instead of activity.startActivityForResult. So just use next wrapper:

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);
    }
}


回答2:

integrator.initiateScan();

Change the above line as

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


回答3:

If any one have the same issue here is my solution.

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
}

}


回答4:

Alternative Project (ZXing Android Embedded):

dependencies {
    compile 'com.journeyapps:zxing-android-embedded:3.3.0@aar'
    compile 'com.google.zxing:core:3.2.1'
}

And implement on Activity:

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

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

    IntentIntegrator.forFragment(this).initiateScan();

}

@Override
public void onActivityResult(int requestCode, int resultCode,Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    switch (requestCode) {
        case IntentIntegrator.REQUEST_CODE:
        if (resultCode == Activity.RESULT_OK) {
            // Parsing bar code reader result
            IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
            if (DEBUG) Log.d(TAG, "Parsing bar code reader result: " + result.toString());

        }
        break;
    }
}

more info and options



回答5:

Make sure OnActivityResult in your Activity is calling super.OnActivityResult(). That should ensure it's called on the Fragment as well.

Alternatively, you could modify the IntentIntegrator code so it calls StartActivityResult on the Fragment, either by passing the fragment to the constructor, or passing it to initiateScan.



回答6:

A solution : A basic example of how you can manage it

Main Activity

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);
    }
}

Fragment 1

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

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

Fragment 2

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

Fragment x

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


回答7:

Try creating IntentIntegrator object in Fragment as below.

        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()