我使用2个按钮在2个不同的片段之间切换。一个片段具有摄像机视图并且第一次打开得非常好,但是当从第二个片段再次返回到相同的片段时会出现空白屏幕。虽然相机硬件是免费的,但是无法看到相机预览。我不使用camera2 api但是需要一个解决这个bug的方法。我添加了完整的代码和图像以获得帮助。
清单
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.root.meeransunday" >
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar"
android:screenOrientation="portrait"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<supports-screens android:smallScreens="true"
android:normalScreens="true"
android:largeScreens="true"
android:xlargeScreens="true"
android:anyDensity="true"
android:resizeable="true"/>
</application>
<activity android:name="meeranSunday"
android:configChanges="orientation|keyboardHidden"
/>
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.CAMERA">
</uses-permission>
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-feature android:name="android.hardware.camera" />
</manifest>
片段java类
public class scan extends Fragment implements ZXingScannerView.ResultHandler {
private ZXingScannerView zXingScannerView;
private SurfaceView mySurfaceView;
private Camera mCamera;
private CameraPreview mPreview;
private String m_Text = "";
private String number = "";
private OnFragmentInteractionListener mListener;
public scan() {}
@Override
public void handleResult(Result rawResult) {
// Do something with the result here
Log.e("handler", rawResult.getText()); // Prints scan results
Log.e("handler", rawResult.getBarcodeFormat().toString()); // Prints the scan format (qrcode)
// show the scanner result into dialog box.
AlertDialog.Builder builder = new AlertDialog.Builder(this.getActivity());
builder.setTitle("Scan Result");
builder.setMessage(rawResult.getText());
number = rawResult.getText().substring(rawResult.getText().length() - 13);
//
final EditText input = new EditText(this.getActivity());
// Specify the type of input expected; this, for example, sets the input as a password, and will mask the text
input.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
builder.setView(input);
// Set up the buttons
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
m_Text = input.getText().toString();
try {
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(number, null, m_Text + " Transferred To Your Account From MTM Account", null, null);
} catch (Exception e) {
e.printStackTrace();
}
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
builder.setNegativeButton("NO",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
//
AlertDialog alert1 = builder.create();
alert1.show();
// If you would like to resume scanning, call this method below:
zXingScannerView.resumeCameraPreview(this);
}
// TODO: Rename and change types and number of parameters
public static scan newInstance() {
scan fragment = new scan();
Bundle args = new Bundle();
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_scan, container, false);
if (checkCameraHardware(getActivity().getApplicationContext())) {
Toast.makeText(this.getActivity(), "camera hardware is free", Toast.LENGTH_SHORT).show();
zXingScannerView = new ZXingScannerView(this.getActivity().getApplicationContext());
zXingScannerView.setResultHandler(this);
zXingScannerView.startCamera(0);
} else {
Toast.makeText(this.getActivity(), "camera hardware is NOT free", Toast.LENGTH_SHORT).show();
}
FrameLayout preview = (FrameLayout) view.findViewById(R.id.camera_preview);
preview.addView(zXingScannerView);
return view;
}
@Override
public void onPause() {
super.onPause();
try {
mCamera = Camera.open();
} catch (RuntimeException e) {
Log.d("camera opening attempt:", e.getMessage());
} finally {
if (mCamera != null) {
Log.d("camera opening attempt:", "yups ");
mCamera.release();
zXingScannerView.stopCamera();
zXingScannerView.stopCameraPreview();
}
}
}
@Override
public void onResume() {
super.onResume();
zXingScannerView.setResultHandler(this); // Register ourselves as a handler for scan results.
zXingScannerView.startCamera(0); // Start camera on resume
}
public boolean checkCameraHardware(Context context) {
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
return true;
} else {
return false;
}
}
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString() +
" must implement OnFragmentInteractionListener");
}
}
@Override
public void onDetach() {
Log.d("aa", "sdsdssdsddssssd");
try {
mCamera = Camera.open();
} catch (RuntimeException e) {
Log.d("camera opening attempt:", e.getMessage());
} finally {
if (mCamera != null) {
mCamera.release();
zXingScannerView.stopCamera();
zXingScannerView.stopCameraPreview();
}
}
super.onDetach();
mListener = null;
}
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name\
void onFragmentInteraction(Uri uri);
}
}
MAinactivity
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
public int check = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
message frags = new message();
fragmentTransaction.add(R.id.content_main, frags, "text");
fragmentTransaction.commit();
check += 1;
}
public void message(View v) {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
message sms = new message();
fragmentTransaction.replace(R.id.content_main, sms, "text");
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
public void scan(View v) {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
scan scan = new scan();
fragmentTransaction.replace(R.id.content_main, scan, "scan");
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
public void loadooncreate() {
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
message frags = new message();
fragmentTransaction.add(R.id.content_main, frags, "text");
fragmentTransaction.commit();
check += 1;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
Toolbar toolbar2 = (Toolbar) findViewById(R.id.toolbar1);
toolbar2.inflateMenu(R.menu.notify);
toolbar2.getMenu().findItem(R.id.notifications).setIcon(buildCounterDrawable(2, R.drawable.notification));
toolbar2.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem arg0) {
if (arg0.getItemId() == R.id.notifications) {
arg0.setIcon(buildCounterDrawable(0, R.drawable.notification));
((RelativeLayout) findViewById(R.id.content_main)).removeAllViews();
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
BlankFragment frag = new BlankFragment();
fragmentTransaction.add(R.id.content_main, frag, "first");
fragmentTransaction.commit();
}
return false;
}
});
check = 1;
return true;
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
//code to reset view
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
if (fragmentManager.findFragmentByTag("first") != null) {
fragmentTransaction.remove(fragmentManager.findFragmentByTag("first"));
fragmentTransaction.commit();
loadooncreate();
} else {
finish();
}
return true;
}
return super.onKeyDown(keyCode, event);
}
private Drawable buildCounterDrawable(int count, int backgroundImageId) {
LayoutInflater inflater = LayoutInflater.from(this);
View view = inflater.inflate(R.layout.counter_menuitem_layout, null);
view.setBackgroundResource(backgroundImageId);
if (count == 0) {
View counterTextPanel = view.findViewById(R.id.counterValuePanel);
counterTextPanel.setVisibility(View.GONE);
} else {
// TextView textView = (TextView) view.findViewById(count);
// textView.setText("1");
}
view.measure(
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
view.setDrawingCacheEnabled(true);
view.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
Bitmap bitmap = Bitmap.createBitmap(view.getDrawingCache());
view.setDrawingCacheEnabled(false);
return new BitmapDrawable(getResources(), bitmap);
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
if (check > 3) {
Toast.makeText(this.getApplicationContext(), "sdsdsdfdsfsd", Toast.LENGTH_SHORT).show();
MenuItem item = menu.getItem(R.id.notifications);
item.setIcon(buildCounterDrawable(2, R.drawable.notification));
}
//MenuItem item = (MenuItem)findViewById(R.id.notifications);
// item.setIcon(buildCounterDrawable(2, R.drawable.notification));
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.Home) {
//close current fragment;
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
if (fragmentManager.findFragmentByTag("first") != null)
fragmentTransaction.remove(fragmentManager.findFragmentByTag("first"));
fragmentTransaction.commit();
loadooncreate();
}
return super.onOptionsItemSelected(item);
}
@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.nav_camera) {
// Handle the camera action
} else if (id == R.id.nav_gallery) {
} else if (id == R.id.nav_slideshow) {
} else if (id == R.id.nav_manage) {
} else if (id == R.id.nav_share) {
} else if (id == R.id.nav_send) {
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
}
上次堆叠错误
W/MessageQueue: Handler (android.hardware.Camera$EventHandler) {428e2000} sending message to a Handler on a dead thread
java.lang.RuntimeException: Handler (android.hardware.Camera$EventHandler) {428e2000} sending message to a Handler on a dead thread
at android.os.MessageQueue.enqueueMessage(MessageQueue.java:294)
at android.os.Handler.sendMessageAtTime(Handler.java:473)
at android.os.Handler.sendMessageDelayed(Handler.java:446)
at android.os.Handler.sendMessage(Handler.java:383)
at android.hardware.Camera.postEventFromNative(Camera.java:852)
at dalvik.system.NativeStart.run(Native Method)
答案 0 :(得分:1)
您可以尝试此操作,移除onAttach
和onDetach
。也请在onCreate
if (checkCameraHardware(getActivity().getApplicationContext())) {
Toast.makeText(this.getActivity(), "camera hardware is free", Toast.LENGTH_SHORT).show();
zXingScannerView = new ZXingScannerView(this.getActivity().getApplicationContext());
zXingScannerView.setResultHandler(this);
zXingScannerView.startCamera(0);
} else {
Toast.makeText(this.getActivity(), "camera hardware is NOT free", Toast.LENGTH_SHORT).show();
}
有了这个。
zXingScannerView = new ZXingScannerView(this.getActivity().getApplicationContext());
然后改变onPause和onResume。
@Override
public void onPause()
super.onPause(); {
if (zXingScannerView != null) {
zXingScannerView.stopCamera();
zXingScannerView.stopCameraPreview();
}
}
@Override
public void onResume() {
super.onResume();
if (checkCameraHardware(getActivity().getApplicationContext())) {
Toast.makeText(this.getActivity(), "camera hardware is free", Toast.LENGTH_SHORT).show();
zXingScannerView.setResultHandler(this); // Register ourselves as a
zXingScannerView.startCamera(0); // Start camera on resume
}
}
同时删除所有这些对象
private SurfaceView mySurfaceView;
private Camera mCamera;
private CameraPreview mPreview;
不需要它们,它位于zXingScannerView中。
答案 1 :(得分:1)
实际上,当切换到其他片段时,您不是释放对象,首先释放onPause()方法中的所有对象,并且onResume()重新连接相机。试试这个:
@Override
public void onResume() {
super.onResume();
if (zXingScannerView!= null) {
zXingScannerView.stopCameraPreview();
zXingScannerView.resumeCameraPreview(this);
}
}