0

I am having a problem with intens from fragments in Android. I have an Activity that holds a Fragment which in turn holds a ListView. I have registered an onItemClickListener to the ListView and this worked well when I had the listView right in the Activity. I needed to wrap it in the fragment however.

So instead of calling getContext() I call now getActivity() as was recomended everywhere. This does in fact return the correct Activity. The click is registered as well, as my LogCat is being printed. But the intent is never started. Nothing happens. Can anyone tell me what I am missing please?

Here is my code:

_dealList.setOnItemClickListener(new AdapterView.OnItemClickListener()
        {
            @Override
            public void onItemClick(AdapterView<?> parent, View v, int position, long id)
            {
                Intent in = new Intent(getActivity(), DealView.class);
                in.putExtra("deal", position);
                in.putExtra("city", _citySearchBar.getText());
                startActivity(in);
                Log.d("BASE_FRAGMENT", "Activity should have been started here");
            }
        });
    }

This code lives inside an abstract class but moving it to the subclasses does not make a difference.

This is the DealView class the intent is aimed at:

public class DealView extends AppCompatActivity {
    private TextView _priceView;
    private TextView _descriptionView;
    private TextView _titleView;
    private TextView _storeView;
    private ImageView _imageView;
    private String _cityName;

    @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_deal_view);

            Intent fromDealSelection = getIntent();
            _cityName = fromDealSelection.getStringExtra("city");

            //Initializing the different components of the view
            _priceView = (TextView) findViewById(R.id.priceInputDealView);

            _descriptionView = (TextView) findViewById(R.id.dealDescriptionDealView);

            _titleView = (TextView) findViewById(R.id.dealTitleDealView);

            _storeView = (TextView) findViewById(R.id.storeDealView);

            _imageView = (ImageView) findViewById(R.id.imageViewDealView);

            _cityName = fromDealSelection.getStringExtra("city");

        }

Here is the LogCat output:

03/01 09:42:23: Launching app
W/System: ClassLoader referenced unknown path: /data/data/de.coding.mb.konstisapp/lib
Hot swapped changes, activity restarted
D/BASE_FRAGMENT: Activity should have been started here
D/BASE_FRAGMENT: Activity should have been started here

Here is my AndroidManifest.xml file:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="de.coding.mb.konstisapp">

    <uses-feature
        android:name="android.hardware.camera"
        android:required="false"/>

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission
        android:name="android.permission.WRITE_EXTERNAL_STORAGE"
        android:maxSdkVersion="18"/>
    <uses-permission android:name="android.permission.INTERNET"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".activities.GreatingsActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
        <activity
            android:name=".activities.DealSelectionActivity"
            android:label="@string/title_activity_deal_selection"
            android:parentActivityName=".activities.GreatingsActivity"
            android:theme="@style/AppTheme.NoActionBar">
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value="de.coding.mb.konstisapp.activities.GreatingsActivity"/>
        </activity>
        <activity
            android:name=".activities.DealCreationActivity"
            android:label="@string/title_activity_activity_deal_creation"
            android:parentActivityName=".activities.DealSelectionActivity"
            android:theme="@style/AppTheme.NoActionBar">
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value="de.coding.mb.konstisapp.activities.DealSelectionActivity"/>
        </activity>
        <activity android:name=".activities.DealView"
                  android:label="@string/title_activity_deal_view"
                  android:parentActivityName=".activities.DealSelectionActivity"
                  android:theme="@style/AppTheme.NoActionBar">
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value="de.coding.mb.konstisapp.activities.DealSelectionActivity">

            </meta-data>
        </activity>
</manifest>
EarlGrey
  • 531
  • 7
  • 29
Timbo
  • 487
  • 1
  • 5
  • 17
  • have you added the activity in manifest file..? – Keerthivasan Mar 01 '17 at 08:51
  • 1
    can you show your logcat? – Harry T. Mar 01 '17 at 08:52
  • getContext() use this – android_jain Mar 01 '17 at 08:54
  • The activity is added in the Manifest.xml. Calling getContext() form within a fragment does not work – Timbo Mar 01 '17 at 08:55
  • 1
    I would recommend using an interface callback in your fragment – sanket pahuja Mar 01 '17 at 08:58
  • Is `DealView` really an Acivity? Is it declared in `AndroidManifest.xml`? – Eduard B. Mar 01 '17 at 09:02
  • @Timbo If your log gets printed invalidate cache and re run and see and is that only thing you have in your log – Charuක Mar 01 '17 at 09:06
  • @Charuක this is in fact the only output I get in the logcat. Nothing else seems to be going on. This is also true for a real device. I will post the manifest too above – Timbo Mar 01 '17 at 09:09
  • Dumb question, but do you ran through debugging? Step into startActivity(in) and go through it. Maybe there is some sort of control structure preventing the Activity from starting, without writing a message to the log. – EarlGrey Mar 01 '17 at 09:11
  • @EarlGrey not a dumb question in my opinion. But there is nothing. It just runs through but does nothing. There is no abort and there is not point where it turns to fail – Timbo Mar 01 '17 at 09:24
  • @Timbo Okay...this is tricky...Can you post your `DealView` class? At least the signature of it? – EarlGrey Mar 01 '17 at 09:38
  • @EarlGrey this is all there is to it. That is the whole class. Thank you so much for you help! – Timbo Mar 01 '17 at 09:43
  • @Timbo Maybe I've used the wrong terminology (sorry, if this is the case), but I would like to have a look at the surrounding class block: `public class DealView extends...` and so on. I learned, sometimes the superclass of an Activity changes everything. Also, I have another idea on dealing with the calling of a new Activity and will eventually post another answer. – EarlGrey Mar 01 '17 at 09:48
  • @EarlGrey changed it. Do you also need the imports? – Timbo Mar 01 '17 at 09:51
  • @Timbo The imports aren't necessary. I have no idea, why `DealView` won't start. Looking at all the documentation, it should work. So, I added another answer, circumventing starting the new Activity directly in the Fragment. – EarlGrey Mar 01 '17 at 10:11

4 Answers4

2

As the starting of a new Activity from within the Fragment doesn't work, you could try migrating the code to the hosting Activity. A clean and reusable way is to create an Interface in a new file.

public interface myInterface {
    public void startMyIntent(Intent i);
}

Then, implement this Interface in the Activity class, hosting your Fragment

public class hostingActivity extends AppCompatActivity implements myInterface {
    @Override
    public void startMyIntent(Intent i) {
        startActivity(i);
    }
}

In your Fragment's onItemClickListener, you can call it like this

_dealList.setOnItemClickListener(new AdapterView.OnItemClickListener()
    {
        @Override
        public void onItemClick(AdapterView<?> parent, View v, int position, long id)
        {
            Activity parentActivity = getActivity();
            Intent in = new Intent(parentActivity, DealView.class);
            in.putExtra("deal", position);
            in.putExtra("city", _citySearchBar.getText());
            ((myInterface)parentActivity).startMyIntent(in);
            Log.d("BASE_FRAGMENT", "Activity should have been started here");
        }
    });
}
EarlGrey
  • 531
  • 7
  • 29
  • Thank you very much! No clue why the other method did not work but this does it. – Timbo Mar 01 '17 at 10:17
  • @Timbo You're welcome! Besides from a working, this seems to be the preferable solution for Fragments doing 'Activity stuff'. Maybe this convention emerged from problems like yours ;) – EarlGrey Mar 01 '17 at 10:24
  • @Timbo As I looked over this answer again, I decided to save the reference to the parent Activity in a local variable, as it is needed twice. It isn't really necessary in this case, but it is better practise in my eyes. – EarlGrey Mar 13 '17 at 08:32
0

From inside a Fragment, you can't just use startActivity()
You have to use getActivity().startActivity(in)

_dealList.setOnItemClickListener(new AdapterView.OnItemClickListener()
    {
        @Override
        public void onItemClick(AdapterView<?> parent, View v, int position, long id)
        {
            Intent in = new Intent(getActivity(), DealView.class);
            in.putExtra("deal", position);
            in.putExtra("city", _citySearchBar.getText());
            getActivity().startActivity(in);
            Log.d("BASE_FRAGMENT", "Activity should have been started here");
        }
    });
}

See also How do I start an activity from within a Fragment?

Community
  • 1
  • 1
EarlGrey
  • 531
  • 7
  • 29
0

Changed Code

_dealList.setOnItemClickListener(new AdapterView.OnItemClickListener()
        {
           @Override
            public void onItemClick(AdapterView<?> parent, View v, int position, long id)
            {
                Intent in = new Intent(v.getContext(), DealView.class);
                in.putExtra("deal", position);
                in.putExtra("city", _citySearchBar.getText());
                startActivity(in);
                Log.d("BASE_FRAGMENT", "Activity should have been started here");
            }
        });
    }
Keerthivasan
  • 1,651
  • 1
  • 21
  • 47
  • 1
    This also does not work :( I have no idea why it would not start the activity. Also v.getContext() and getActivity() are returning the same reference – Timbo Mar 01 '17 at 09:01
0

use FLAG_ACTIVITY_NEW_TASK in intent.setFlags(...) method.

_dealList.setOnItemClickListener(new AdapterView.OnItemClickListener()
    {
       @Override
        public void onItemClick(AdapterView<?> parent, View v, int position, long id)
        {
            Intent in = new Intent(v.getContext(), DealView.class);
            in.putExtra("deal", position);
            in.putExtra("city", _citySearchBar.getText());
            in.setFlag(Acitvity.FLAG_ACTIVITY_NEW_TASK);
            getActivity().startActivity(in);
            Log.d("BASE_FRAGMENT", "Activity should have been started here");
        }
    });
}
Ravikant Tiwari
  • 371
  • 3
  • 11