Calling startActivity() outside of an Activity context requires FLAG_ACTIVITY_NEW_TASK - android

I am getting the error AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. The full stack trace:
main Process: com.kd.book, PID: 3487 android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want? at android.app.ContextImpl.startActivity(ContextImpl.java:1238) at android.app.ContextImpl.startActivity(ContextImpl.java:1225) at com.kd.book.Adapter.MyComicAdapter$1.onClick(MyComicAdapter.java:63) at com.kd.book.Adapter.MyComicAdapter$MyViewHolder.onClick(MyComicAdapter.java:99)
I am new to Android development and do not know how to solve it.
My Code:
public class MyComicAdapter extends RecyclerView.Adapter<MyComicAdapter.MyViewHolder> {
Context context;
List<Comic> comicList;
LayoutInflater inflater;
public MyComicAdapter(Context context, List<Comic> comicList) {
this.context = context;
this.comicList = comicList;
inflater=LayoutInflater.from(context);
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View itemView = inflater.inflate(R.layout.comic_item, viewGroup, false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder myViewHolder, final int i) {
Picasso.get().load(comicList.get(i).Image).into(myViewHolder.comic_image);
myViewHolder.comic_name.setText(comicList.get(i).Name);
//Event
myViewHolder.setRecyclerItemClickListener(new IRecyclerItemClickListener(){
#Override
public void onClick(View view, int position) {
//save the comic selected
Common.comicSelected = comicList.get(position);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(new Intent(context,ChapterActivity.class));
}
});
}
#Override
public int getItemCount() {
return comicList.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView comic_name;
ImageView comic_image;
IRecyclerItemClickListener recyclerItemClickListener;
public void setRecyclerItemClickListener(IRecyclerItemClickListener recyclerItemClickListener) {
this.recyclerItemClickListener = recyclerItemClickListener;
}
public MyViewHolder(#NonNull View itemView) {
super(itemView);
comic_image = itemView.findViewById(R.id.image_comic);
comic_name = itemView.findViewById(R.id.comic_name);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View view) {
recyclerItemClickListener.onClick(view, getAdapterPosition());
}
}
}
Any ideas?

The problem is that you are doing "new Intent" twice:
Once here: Intent intent = new Intent(Intent.ACTION_VIEW);
Second time here: context.startActivity(new Intent(context,ChapterActivity.class))
FLAG_ACTIVITY_NEW_TASK is not set when the activity is started. The corrected version where the Intent is only created once looks like:
Intent intent = new Intent(context, ChapterActivity.class))
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
But your real problem is that you need to call startActivity on the Activity context.
getActivity().startActivity(new Intent(getActivity(), ChapterActivity.class));
More discussion here:
How do I start an activity from within a Fragment?
What you were attempting to do with FLAG_ACTIVITY_NEW_TASK should be reserved for rare cases like when you need to launch an Activity from a Service. But it is not necessary or desirable to set that flag when starting an Activity from within a UI context.
This is why the warnings asks:
Is this really what you want?
Setting specialised flags when launching the Activity often leads to unwanted backstack/navigation behaviours.
Also, I cannot see if your adapter is located inside an Activity or Fragment. [You can use "this" inside an Acitivity and getActivity() inside a Fragment]
Lastly, I cannot how you are creating the Adapter, but the way your code is currently organised you need to pass the Activity context into the Adapter for it to work. From a Fragment:
adapter = new MyComicAdapter(getActivity(), list);
From an Activity:
adapter = new MyComicAdapter(this, list);
This will most likely prevent the exception that you are getting.

Try this way,
1. create an interface in your adapter and pass the position to it (hope you know how to make and use an interface).
2. implement that interface to your activity class.
3. in its override method, you will get the position of a list.
4. by using that position, get the required data and call intent in it.
Done.

Change your call to the new activity as follows,
Intent intent=new Intent(context, ChapterActivity.class);
Activity activity=(Activity) context;
activity.startActivity(intent);

Related

Delivery of Listener from Service to Activity

My App adds a specific Activity by adding a Task in the Service, and performs a specific function within the Service based on the result of that Activity. And when the Activity starts, it inflates the Fragment and wants the result from this Fragment to be passed to the Service. So I tried to use Intent, but I couldn't deliver the instance. I know I can only ship objects
public interface TuneListener {
void tune(Uri channelUri);
}
private final class ItemViewClickedListener implements OnItemViewClickedListener {
#Override
public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item,
RowPresenter.ViewHolder rowViewHolder, Row row) {
Channel channel = (Channel) item;
Uri channelUri = TvContract.buildChannelUri(channel.getId());
listener.tune(channelUri);
getActivity().finishAndRemoveTask();
}
}
Above is the implementation in my fragment
And this is the contents of the Service Class that implements this tunelistener.
#Override
public void tune(Uri channelUri) {
onTune(channelUri);
}
This part is the call of Activity
Intent intent = new Intent();
intent.setClassName(getPackageName(), getPackageName() + ".MyActivity");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
How can I deliver that Listener to Activity or Fragment within this structure?

Get shared element transitions inside the recylerView

I need a shared transition in recylerview to an activity but getting the error "Application cannot be cast to Activity" tried passing Adpater.this/this/Adapter.class but nothing is working
ViewCompat.setTransitionName(holder.imageView, photo.getId());
holder.imageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(mContext, Fullscreen.class);
ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation((MainActivity) mContext, holder.imageView, ViewCompat.getTransitionName(holder.imageView));
mContext.startActivity(intent, options.toBundle());
}
});
}
problem is in (MainActivity)mContext line. Your mContext is Application type but you try to cast it to Activity type, thats why it throws ClassCastException. Declare your field as Activity mContext; instead of Context mContext; and IDE will show you that you init your mContext variable with wrong type object.

getStringExtra returns null SINGLE_TOP flag

I made one Fragment (ListA) with a ListView. When I click one item of the ListView I want to start the MainActivity.
public class ListA extends Fragment {
private WearableListView ListV;
...
private WearableListView.ClickListener mClickListener = new WearableListView.ClickListener() {
#Override
public void onClick(WearableListView.ViewHolder viewHolder) {
Intent intent= new Intent(getActivity().getApplicationContext(), MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.putExtra("timestamp", "AAA");
startActivity(intent);
}
This is the MainActivity:
public class MainActivity extends Activity {
#Override
public void onResume() {
super.onResume();
if(getIntent().getStringExtra("timestamp")!=null){
Toast.makeText(getApplicationContext(),"Has Timestamp",Toast.LENGTH_SHORT).show();
}
}
When I add flag Intent.FLAG_ACTIVITY_SINGLE_TOP, getIntent().getStringExtra("timestamp") returns null. If I add flag Intent.FLAG_ACTIVITY_NEW_TASK it is not null.
I want to have flag Intent.FLAG_ACTIVITY_SINGLE_TOP and it returns null, I don't know why.
I think because MainActivity was already started before so no new intents is being passed to it.
Try destroying the main activity before you go to list activity. See if this works

AndroidRuntimeException "Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag"

I create multiple layouts inside a listview, but when i click i get a AndroidRuntimeException "Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?"
Im adding
Intent.FLAG_ACTIVITY_NEW_TASK
to my intent but i get the same message! =(
#Override
public View getView(int position, View convertView, ViewGroup parent) {
retval=LayoutInflater.from(getApplicationContext()).inflate(R.layout.layout_anuncio, null);
ImageView image=(ImageView) retval.findViewById(R.id.imageAD);
LoadAds loadAds= new CargaAnuncios();
clickUrl = LoadAds.cargaImagenAnuncio(image, mContext, GlobalInfo.ANUNCIO_CARRIL_PORTADA);
image.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View view) {
Bundle bundle=new Bundle();
bundle.putString("url", clickUrl);
Intent intent =new Intent(mContext,CustomWebView.class);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent);
}
});
return retval;
}
Replace getApplicationContext() with this. Most likely, you should do that everywhere in your code that you have getApplicationContext() -- only use getApplicationContext() when you specifically need the Application object.
Old thread, but thought this easy solution might help someone. Instead of passing context around, just get it from view. For eg: view.getContext()
#Override
public void onClick(View view) {
Bundle bundle=new Bundle();
bundle.putString("url", clickUrl);
Intent intent =new Intent(view.getContext(),CustomWebView.class);
intent.putExtras(bundle);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
view.getContext().startActivity(intent);
}
I have added:
parent.getApplicationContext()
Instead of just:
getApplicationContext()
Whole line is:
retval=LayoutInflater.from(parent.getApplicationContext()).inflate(R.layout.layout_anuncio, null);
The solution of Warren Lankie Van Tonder is almost the good:
-You should avoid using Activity context and choose Application Context instead, in purpose to prevent memory leaks. This blog of an Android developer explains that http://android-developers.blogspot.be/2009/01/avoiding-memory-leaks.html
-But in the case of Activity context is the only solution for your code (maybe for calling another activity from outside an activity) and regarding the link above, you have to release the static reference in each onPause() with
AppGlobals.setAppContext(null);
In return, set the static field in onResume and not onCreate.
Thanks to CommonsWare i came up with this solution which worked best.
I added a new class
package com.test.test;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
public class AppGlobals extends Activity {
private static Context appContext;
public static Context getAppContext(){
return appContext;
}
public static void setAppContext(Context context){
appContext = context;
}
public static void StartActivity(Intent intent){
appContext.startActivity(intent);
}
}
All i needed to do then was add the below code on each activity onCreate that i navigated to.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
AppGlobals.setAppContext(this);
}
This allowed the new intent to start as if it working with normal application flow and this way i didn't have to set a Flag for the intent.
Calling the start activity method is as easy as:
Intent totalTimerIntent = new Intent(AppGlobals.getAppContext(), TotalTimer.class);
AppGlobals.StartActivity(totalTimerIntent);
Hope this helps someone as it has helped me.
Thank you CommonsWare.
CustomAdapter mAdapter = new CustomAdapter( getApplicationContext(), yourlist);
or
Context mContext = getAppliactionContext();
CustomAdapter mAdapter = new CustomAdapter( mContext, yourlist);
change to below
CustomAdapter mAdapter = new CustomAdapter( this, yourlist);

How to call An activity class from nonactivityclass (class without extends anything) in android?

I want call an activity class from a normal java class(without extends anything) for every some time interval to refresh the Ui, Is it possible to call an activity from normal java class. We can call the activity from another activity using intent and startactivity. But am not sure about calling the activity from class.
For example
class example extends Activity
{
}
class example2 extends Activity
{
// we can call like
Intent intent = new Intent(this.example2,example.class);
startActivity(intent);
}
class test
{
// How can i call example or example2 from here.
}
Thanks,
Lakshmanan
You could provide a parameter consisting of the context of your Activity that has been creating the Object. Then you can use the Context's methods just like within an Activity.
i.g.
public class Foo {
private Context context;
public Foo(Context context) {
this.context = context;
}
public void startActivity() {
context.startActivity(/*your intent here*/);
}
}
Intent intent12 = new Intent(context.getApplicationContext(), ImageClick.class);
context.startActivity(intent12);
It works. I've tried.
I use this to view you tube videos from a non activity class -
Intent intent = new Intent(Intent.ACTION_VIEW,Uri.parse(url));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // important step
context.startActivity(intent);
Hope this helps you.
Salil.

Categories

Resources