Android: 使用zxing扫描条码并返回片段中的结果
Android: Barcode scanning with zxing and returning result in fragment
我正在尝试在 Fragment 中使用 zxing 库。我可以让扫描仪工作并捕获条形码,但 activity 中的 onActivityResult 方法始终是 运行 而不是 Frament 中的 onActivityResult 方法。
我已经尝试了post中提到的不同解决方案,但没有成功。
这是我的代码 activity:
package com.test01.test01_tp2;
import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.view.GravityCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import android.content.Intent;
import android.os.Bundle;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import com.google.android.material.navigation.NavigationView;
import com.google.zxing.integration.android.IntentIntegrator;
import com.google.zxing.integration.android.IntentResult;
public class MainActivityLibrarian extends AppCompatActivity {
DrawerLayout drawerLayout;
String name;
TextView tvName;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_librarian);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
drawerLayout = findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.drawer_open, R.string.drawer_close);
drawerLayout.addDrawerListener(toggle);
toggle.syncState();
NavigationView nav_view = findViewById(R.id.nav_view);
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,new HomeLibrarianFragment()).commit();
//Get the username and update the name in the drawer
name = getIntent().getStringExtra("name");
View headerView = nav_view.getHeaderView(0);
tvName = headerView.findViewById(R.id.txtNameHeader);
tvName.setText(name);
nav_view.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
switch(menuItem.getItemId())
{
case R.id.nav_add_loan:
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,new AddLoanFragment()).commit();
break;
case R.id.nav_list_loans:
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ListLoansFragment()).commit();
break;
case R.id.nav_add_readers:
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new AddReadersFragment()).commit();
break;
case R.id.nav_list_readers:
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ListReadersFragment()).commit();
break;
case R.id.nav_add_books:
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new AddBooksFragment()).commit();
break;
case R.id.nav_list_books:
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ListBooksFragment()).commit();
break;
/*case R.id.close:
finish();
break;*/
}
drawerLayout.closeDrawer(GravityCompat.START);
return true;
}
});
}
@Override
public void onBackPressed() {
if(drawerLayout.isDrawerOpen(GravityCompat.START))
drawerLayout.closeDrawer(GravityCompat.START);
else
super.onBackPressed();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
System.out.println("the code is catch");
}
}
这是我尝试使用条形码的片段代码 reader:
package com.test01.test01_tp2;
import android.content.Intent;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import com.google.zxing.integration.android.IntentIntegrator;
import com.google.zxing.integration.android.IntentResult;
/**
* A simple {@link Fragment} subclass.
*/
public class AddLoanFragment extends Fragment {
//View Objects
private Button btnAdd, btnClear;
private EditText etBarcodeReader, etBarcodeBook;
private ImageButton imBtnBarcodeBook, imBtnBarcodeReader;
//barcode scanner Object
private IntentIntegrator barcodeScanner;
public AddLoanFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_add_loan, container, false);
//View Objects
btnAdd = root.findViewById(R.id.btn_add);
btnClear = root.findViewById(R.id.btn_clear);
imBtnBarcodeBook = root.findViewById(R.id.imageButtonBarcodeBook);
imBtnBarcodeReader = root.findViewById(R.id.imageButtonBarcodeReader);
etBarcodeBook = root.findViewById(R.id.editTextBookBarcode);
etBarcodeReader = root.findViewById(R.id.editTextReaderBarcode);
imBtnBarcodeReader.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
barcodeScanner = new IntentIntegrator(getActivity());
barcodeScanner.forSupportFragment(AddLoanFragment.this).initiateScan();
}
});
// Inflate the layout for this fragment
return root;
}
@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
}
}
当我查看控制台时,我总是看到:代码被捕获。我不明白:从来没有在这里。
请注意,我在 barcodeScanner.forSupportFragment(AddLoanFragment.this).initiateScan();
收到一条警告,提示静态成员 'com.google.zxing.integration.android.IntentIntegrator.forSupportFragment(androidx.fragment.app.Fragment)' 通过实例引用访问。我不确定这是什么意思,是否是问题所在。
我想我已经尝试了上面提到的 post 中提出的所有答案,但没有成功。
感谢您的帮助。
我找到问题所在了。当相机开始寻找条形码时,它会以横向模式启动。我想在纵向模式下使用扫描仪并旋转 phone 以重新启动 activity(并留下我的片段)。我通过以纵向模式启动相机解决了我的问题。为此,我在 AndroidManifest.xml 文件中添加了这段代码:
<activity
android:name="com.journeyapps.barcodescanner.CaptureActivity"
android:screenOrientation="portrait"
tools:replace="screenOrientation" />
这是我的片段的代码:
package com.test01.test01;
import android.content.Intent;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.Toast;
import com.google.zxing.integration.android.IntentIntegrator;
import com.google.zxing.integration.android.IntentResult;
/**
* A simple {@link Fragment} subclass.
*/
public class AddLoanFragment extends Fragment {
private int mode;
//View Objects
private Button btnAdd, btnClear;
private EditText etBarcodeReader, etBarcodeBook;
private ImageButton imBtnBarcodeBook, imBtnBarcodeReader;
public AddLoanFragment() {
// Required empty public constructor
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_add_loan, container, false);
//View Objects
btnAdd = root.findViewById(R.id.btn_add);
btnClear = root.findViewById(R.id.btn_clear);
imBtnBarcodeBook = root.findViewById(R.id.imageButtonBarcodeBook);
imBtnBarcodeReader = root.findViewById(R.id.imageButtonBarcodeReader);
etBarcodeBook = root.findViewById(R.id.editTextBookBarcode);
etBarcodeReader = root.findViewById(R.id.editTextReaderBarcode);
imBtnBarcodeReader.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mode = 1;
scanFromFragment();
}
});
imBtnBarcodeBook.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mode = 2;
scanFromFragment();
}
});
// Inflate the layout for this fragment
return root;
}
public void scanFromFragment() {
IntentIntegrator.forSupportFragment(this).initiateScan();
}
@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(getContext(),"Cancelled from fragment", Toast.LENGTH_LONG).show();
} else {
if (mode == 1) {
etBarcodeReader.setText(result.getContents());
} else if (mode == 2) {
etBarcodeBook.setText(result.getContents());
}
}
}
}
}
现在可以删除我 Activity 中的 OnActivityResult() 方法。
我正在尝试在 Fragment 中使用 zxing 库。我可以让扫描仪工作并捕获条形码,但 activity 中的 onActivityResult 方法始终是 运行 而不是 Frament 中的 onActivityResult 方法。
我已经尝试了post中提到的不同解决方案,但没有成功。
这是我的代码 activity:
package com.test01.test01_tp2;
import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.view.GravityCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import android.content.Intent;
import android.os.Bundle;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import com.google.android.material.navigation.NavigationView;
import com.google.zxing.integration.android.IntentIntegrator;
import com.google.zxing.integration.android.IntentResult;
public class MainActivityLibrarian extends AppCompatActivity {
DrawerLayout drawerLayout;
String name;
TextView tvName;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_librarian);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
drawerLayout = findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.drawer_open, R.string.drawer_close);
drawerLayout.addDrawerListener(toggle);
toggle.syncState();
NavigationView nav_view = findViewById(R.id.nav_view);
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,new HomeLibrarianFragment()).commit();
//Get the username and update the name in the drawer
name = getIntent().getStringExtra("name");
View headerView = nav_view.getHeaderView(0);
tvName = headerView.findViewById(R.id.txtNameHeader);
tvName.setText(name);
nav_view.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
switch(menuItem.getItemId())
{
case R.id.nav_add_loan:
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,new AddLoanFragment()).commit();
break;
case R.id.nav_list_loans:
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ListLoansFragment()).commit();
break;
case R.id.nav_add_readers:
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new AddReadersFragment()).commit();
break;
case R.id.nav_list_readers:
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ListReadersFragment()).commit();
break;
case R.id.nav_add_books:
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new AddBooksFragment()).commit();
break;
case R.id.nav_list_books:
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ListBooksFragment()).commit();
break;
/*case R.id.close:
finish();
break;*/
}
drawerLayout.closeDrawer(GravityCompat.START);
return true;
}
});
}
@Override
public void onBackPressed() {
if(drawerLayout.isDrawerOpen(GravityCompat.START))
drawerLayout.closeDrawer(GravityCompat.START);
else
super.onBackPressed();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
System.out.println("the code is catch");
}
}
这是我尝试使用条形码的片段代码 reader:
package com.test01.test01_tp2;
import android.content.Intent;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import com.google.zxing.integration.android.IntentIntegrator;
import com.google.zxing.integration.android.IntentResult;
/**
* A simple {@link Fragment} subclass.
*/
public class AddLoanFragment extends Fragment {
//View Objects
private Button btnAdd, btnClear;
private EditText etBarcodeReader, etBarcodeBook;
private ImageButton imBtnBarcodeBook, imBtnBarcodeReader;
//barcode scanner Object
private IntentIntegrator barcodeScanner;
public AddLoanFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_add_loan, container, false);
//View Objects
btnAdd = root.findViewById(R.id.btn_add);
btnClear = root.findViewById(R.id.btn_clear);
imBtnBarcodeBook = root.findViewById(R.id.imageButtonBarcodeBook);
imBtnBarcodeReader = root.findViewById(R.id.imageButtonBarcodeReader);
etBarcodeBook = root.findViewById(R.id.editTextBookBarcode);
etBarcodeReader = root.findViewById(R.id.editTextReaderBarcode);
imBtnBarcodeReader.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
barcodeScanner = new IntentIntegrator(getActivity());
barcodeScanner.forSupportFragment(AddLoanFragment.this).initiateScan();
}
});
// Inflate the layout for this fragment
return root;
}
@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
}
}
当我查看控制台时,我总是看到:代码被捕获。我不明白:从来没有在这里。
请注意,我在 barcodeScanner.forSupportFragment(AddLoanFragment.this).initiateScan();
收到一条警告,提示静态成员 'com.google.zxing.integration.android.IntentIntegrator.forSupportFragment(androidx.fragment.app.Fragment)' 通过实例引用访问。我不确定这是什么意思,是否是问题所在。
我想我已经尝试了上面提到的 post 中提出的所有答案,但没有成功。
感谢您的帮助。
我找到问题所在了。当相机开始寻找条形码时,它会以横向模式启动。我想在纵向模式下使用扫描仪并旋转 phone 以重新启动 activity(并留下我的片段)。我通过以纵向模式启动相机解决了我的问题。为此,我在 AndroidManifest.xml 文件中添加了这段代码:
<activity
android:name="com.journeyapps.barcodescanner.CaptureActivity"
android:screenOrientation="portrait"
tools:replace="screenOrientation" />
这是我的片段的代码:
package com.test01.test01;
import android.content.Intent;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.Toast;
import com.google.zxing.integration.android.IntentIntegrator;
import com.google.zxing.integration.android.IntentResult;
/**
* A simple {@link Fragment} subclass.
*/
public class AddLoanFragment extends Fragment {
private int mode;
//View Objects
private Button btnAdd, btnClear;
private EditText etBarcodeReader, etBarcodeBook;
private ImageButton imBtnBarcodeBook, imBtnBarcodeReader;
public AddLoanFragment() {
// Required empty public constructor
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_add_loan, container, false);
//View Objects
btnAdd = root.findViewById(R.id.btn_add);
btnClear = root.findViewById(R.id.btn_clear);
imBtnBarcodeBook = root.findViewById(R.id.imageButtonBarcodeBook);
imBtnBarcodeReader = root.findViewById(R.id.imageButtonBarcodeReader);
etBarcodeBook = root.findViewById(R.id.editTextBookBarcode);
etBarcodeReader = root.findViewById(R.id.editTextReaderBarcode);
imBtnBarcodeReader.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mode = 1;
scanFromFragment();
}
});
imBtnBarcodeBook.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mode = 2;
scanFromFragment();
}
});
// Inflate the layout for this fragment
return root;
}
public void scanFromFragment() {
IntentIntegrator.forSupportFragment(this).initiateScan();
}
@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(getContext(),"Cancelled from fragment", Toast.LENGTH_LONG).show();
} else {
if (mode == 1) {
etBarcodeReader.setText(result.getContents());
} else if (mode == 2) {
etBarcodeBook.setText(result.getContents());
}
}
}
}
}
现在可以删除我 Activity 中的 OnActivityResult() 方法。