0

2つのボタンを使用して2つの異なるフラグメントに切り替わります。 1つのフラグメントはカメラビューを持ち、最初はかなり開いていますが、2つ目のフラグメントから同じフラグメントに戻ったときに空白の画面が表示されます。カメラのハードウェアは無料ですが、カメラのプレビューは見られません。私はcamera2 apiを使用していませんが、このバグの解決策が必要です。私は完全なコードと画像を追加しました。 enter image description hereフラグメントの切り替え中にカメラを操作する方法は?

マニフェスト

<?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

なぜdetach()でカメラを再び開いていますか?この問題はおそらく、カメラを適切に解放していないためです。 –

+0

どのように正確にカメラをリリースするには? Plusのデタッチは、私がフラグメントを置き換えているので呼び出されません。削除しない。 –

+0

プラスカメラがフリーであるかどうかを確認するために開いていますか?私は最終的にカメラをrelaseingしていますが、デタッチはどこに呼び出されているのですか?それは太陽と呼ばれていません。 –

答えて

1

これを試すことができますか?onAttachonDetachを削除してください。また、このコードを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

実際には、他のフラグメントに切り替えると、onPause()メソッドのすべてのオブジェクトが最初に解放され、onResume()がカメラに再接続するとオブジェクトは解放されません。次のように試してみてください:

@Override 
public void onResume() { 
    super.onResume(); 
    if (zXingScannerView!= null) { 
     zXingScannerView.stopCameraPreview(); 
     zXingScannerView.resumeCameraPreview(this); 
    } 
} 
関連する問題