1

I am trying to implement the Commonsware CWAC-Camera and I am running into an issue incorporating it into an existing fragment.

I am getting an issue where I cannot use .add or .replace and it wants me to change CameraFragment to Fragment.

ERROR:

The method add(int, Fragment, String) in the type FragmentTransaction is not applicable for the arguments (int, CameraFragment, String)

<uses-sdk
    android:minSdkVersion="13"
    android:targetSdkVersion="21" />


 import java.io.File;
 import java.text.SimpleDateFormat;
 import java.util.Date;

import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ImageButton;

import com.commonsware.cwac.camera.CameraFragment;




public void takePicture() {

    CameraFragment f = new CameraFragment();
    getFragmentManager().beginTransaction()
            .add(R.id.contentFragment, f, TAG_CAMERA_FRAGMENT)
            .commit();
}

Has anyone experienced this before? Here is the entire fragment.

public class FeedActivity extends Fragment implements OnClickListener {

    ImageButton btnCamera, btnGallery;
    private final String TAG_CAMERA_FRAGMENT = "camera_fragment";

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.activity_feed, container, false);

        btnCamera = (ImageButton) view.findViewById(R.id.btn_Camera);
        btnCamera.setOnClickListener(this);
        btnGallery = (ImageButton) view.findViewById(R.id.btn_Gallery);
        btnGallery.setOnClickListener(this);

        return view;
    }

    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
        switch (v.getId()) {

        case R.id.btn_Camera:
        Log.e("CAMERA", "CAMERA BUTTON PRESSED");
            //takePicture();
            break;

        case R.id.btn_Gallery:
            Log.e("Gallery", "GALLERY BUTTON PRESSED");
            break;

        }

    }

    public void takePicture() {

        CameraFragment f = new CameraFragment();
        getFragmentManager().beginTransaction()
                .add(R.id.contentFragment, f, TAG_CAMERA_FRAGMENT)
                .commit();
    }
}
Coova
  • 1,818
  • 5
  • 36
  • 63
  • "I cannot use .add or .replace and it wants me to change CameraFragment to Fragment" -- I do not know what you mean by this. Please provide the exact message and indicate what is giving you the message (an IDE? LogCat? something else?) If I had to guess, you have the wrong imports and are trying to mix the fragments backport with native API Level 11+ fragments, but that's just a guess. – CommonsWare Sep 23 '14 at 13:37
  • The method add(int, Fragment, String) in the type FragmentTransaction is not applicable for the arguments (int, CameraFragment, String) – Coova Sep 23 '14 at 13:44
  • I just included the error. The quick fix read "change f to Fragment". My apologies. – Coova Sep 23 '14 at 13:49
  • Please edit your question to paste in the full list of `import` statements for this Java source file. My guess was correct, and you are mixing some fragments backport classes with the API Level 11+ fragments classes, but without the imports, I cannot tell you precisely what to change. – CommonsWare Sep 23 '14 at 13:50

2 Answers2

2
import android.support.v4.app.Fragment;

and:

import com.commonsware.cwac.camera.CameraFragment;

are incompatible. You need to decide if you want to use the fragments backport from the Android Support package or if you want to use native API Level 11+ fragments. And you need to modify your entire activity to support your choice (e.g., inherit from FragmentActivity if you are using the backport).

If you want to use the backport, you will need to use the camera-v9 library and import com.commonsware.cwac.camera.acl.CameraFragment, though this also uses ActionBarSherlock. If you want the backport of fragments but not ActionBarSherlock, you will need to fork one of my CameraFragment implementations to support that combination.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
0

Issues

I would like to show you my way to solve the CameraFragment incompatibility issue. My app use V4 Support Library (somehow I don't know why) but no ActionBarSherlock. Because my target platform is V11 and above (yes, not supporting 2.3 and below).

  • com.commonsware.cwac.camera.CameraFragment -> not compatible with V4 Support Library, hence not compatible with our V4 FragmentActivity and other fragments.

  • com.commonsware.cwac.camera.acl.CameraFragment -> won't work because I don't have ActionBarSherlock.

Common Solution

Usually, the app will have lots of fragments and some with list or grid. They all share some common functions. We might use a static utils class but it might create more problems than it solved. For example, it will require passing this fragment pointer in function calls. End up we have these:

java.lang.Object
↳ android.support.v4.app.Fragment
  ↳ com.example.app.BaseFragment           <- with common functions

java.lang.Object
↳ android.app.Fragment
  ↳ android.app.ListFragment
    ↳ com.example.app.BaseListFragment     <- with common functions

java.lang.Object
↳ android.app.Fragment
  ↳ com.commonsware.cwac.camera.CameraFragment
    ↳ com.example.app.BaseCameraFragment   <- with common functions

Problems

  • The middle class fragments may extends from different fragment: original or V4 support library.
  • There are multiple copies of common functions, inside those Base...Fragment classes. Maintenance is difficult and time wasting.

However, I notice somethings about these fragments we extended from:

  1. they are well-completed, and very unlikely to change.
  2. they are mostly open sourced.
  3. they usually won't care whether their parent is original or V4 support - they work on their own.

Solution

So, instead of extending from them, we can either (a) change their parent class, or (b) clone them and extends from whichever fragment we like:

java.lang.Object
↳ android.support.v4.app.Fragment
  ↳ com.example.app.BaseFragment           <- with common functions
    ↳ com.example.app.BaseListFragment     
      // with content from android.app.ListFragment
    ↳ com.example.app.BaseCameraFragment
      // with content from com.commonsware.cwac.camera.CameraFragment

(please note, we still have to follow the GNU license where applicable)

Usually, I prefer not to alter their source code, so I can easily update to latest version when available. So, I will keep the original inside the app and use method b. The only work is to diff their version with my clones.

Benefits

  1. maintain one fragment with common functions.
  2. resolve base type incompatibility.
  3. easy to change the base-base fragment type.
  4. (for CWAC) I can avoid camera-v9 which requires ActionBarSherlock, and I have all fragments extends from v4 fragment.

Enjoy~

John Pang
  • 2,403
  • 25
  • 25
  • Oh regarding why I use v4 fragment even the min-target is Android 4.0+: one day, my teammate told me that in some early version (such as 4.0), there are problems with their built-in fragment. It is wiser to use v4 support library. So that the app will be using the bug-fixed version of fragment and FragmentActivity. Correct me if I'm wrong. As I see no harm in using V4 library, so...... – John Pang Dec 12 '14 at 08:01