android.app.Application cannot be cast to android.app.Activity - java

I'm trying to change a LinearLayout from another class, but when i run this code:
public class IRC extends PircBot {
ArrayList<String> channels;
ArrayList<Integer> userCount;
ArrayList<String> topics;
LinearLayout channelLayout;
Context context;
public IRC(Context ctx) {
this.setName("xxxx");
channels = new ArrayList<String>();
userCount = new ArrayList<Integer>();
topics = new ArrayList<String>();
context = ctx;
channelLayout = (LinearLayout) ((Activity) context).findViewById(R.id.channels);
}
i get a ClassCastException
context is the Main activity that extends Activity passed with a getApplicationContext();
LOGCAT
05-08 17:53:55.102 3736-3799/g.d.allinonechat E/AndroidRuntime﹕ FATAL EXCEPTION: Thread-5357
java.lang.ClassCastException: android.app.Application cannot be cast to android.app.Activity
at g.d.xxx.IRC.<init>(IRC.java:34)
at g.d.xxx.MainActivity$1.run(MainActivity.java:49)
at java.lang.Thread.run(Thread.java:856)

You are passing the Application Context not the Activity Context with
getApplicationContext();
Wherever you are passing it pass this or ActivityName.this instead.
Since you are trying to cast the Context you pass (Application not Activity as you thought) to an Activity with
(Activity)
you get this exception because you can't cast the Application to Activity since Application is not a sub-class of Activity.

in case your project use dagger, and then this error show up
you can add this at android manifest
<application
...
android: name = ".BaseApplication"
...> ...

In my case, when I'm in an activity that extends from AppCompatActivity, it did not work(Activity) getApplicationContext (), I just putthis in its place.

You are getting this error because the parameter required is Activity and you are passing it the Application.
So, either you cast application to the Activity like: (Activity)getApplicationContext();
Or you can just type the Activity like: MyActivity.this

In my case I just put android:name=".CustomBaseClass" inside the activity tag instead of the application tag inside the manifest, hope it helps someone.

You can also try this one.
override fun registerWith( registry: PluginRegistry) {
GeneratedPluginRegistrant.registerWith(registry as FlutterEngine)
//registry.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin")
}
I think this one is far better solution than creating a new class.

I had a similar problem when checking for internet connection in my viewmodel.
The error in my logcat:
java.lang.ClassCastException: android.app.Application cannot be cast to com.example.newsapplication.util.AppApplication in viewmodel
I added this line in the manifest and my application worked just fine.
android:name="com.example.newsapplication.util.AppApplication"

In my case, I just put add name property inside the application tag in the Manifest file
<application
android:name=".TodoApplication"
...

In my case I removed the line android:name ="<some_name>" and it worked. Looks like it was looking for a class with the name that was provided earlier whereas my Project does not have the class.

In my case, I deleted the android:name=".TodoApplication" from application and added it inside the activity tag.
<activity android:name=".BaseApplication"/>
Ensure you delete from the Application tag

Related

Is an Activity equal to a Context?

I've been wondering about something in android development.
I have a class for requesting permissions to the device in an easier way for me, this class name is PermissionRequester
public class PermissionRequester{
int sdk;
Context context;
public PermissionRequester(Context context) {
this.context = context;
sdk = Build.VERSION.SDK_INT;
}
}
In a beginning, I was requesting a Context in my constructor for checking if the permission was allowed or denied by the user. Using Context didn't work, so I change "Context" to "Activity" and it worked.
public class PermissionRequester {
int sdk;
Activity activity;
public PermissionRequester(Activity activity) {
this.activity = activity;
sdk = Build.VERSION.SDK_INT;
}
}
In my MainActivity, I instanciate like this
PermissionRequester requester = new PermissionRequester(MainActivity.this);
So my question is the next:
Why didn't I get a compile error in both cases using Context and Activity?
Context is the Base Object. To be more precise an Activity is a specialization of Context. That's why you Activity works in your case.
Take a look at this architecture of an Activity:
java.lang.Object
↳ android.content.Context
↳ android.content.ContextWrapper
↳ android.view.ContextThemeWrapper
↳ android.app.Activity
Add to DEX7RA's answer.
Another important Context is Appication, which is base class for those who need to maintain global application state. You can provide your own implementation by specifying its name in your AndroidManifest.xml's tag, which will cause that class to be instantiated for you when the process for your application/package is created.
I usually do application wide initialization in Application's OnCreate event, like creating database, log file, etc.

Communication Between Two Android Activities via Reference to Caller or Callee

I have two activities Activity A and Activity B inside of the same application and they need to be able to call methods on each other. A needs to communicate to B at the start (possibly see "code" below).
B will call a lot of methods on A (this means that I cannot use the startActivityForResult method for communication because this would close B (Activity B is a Bluetooth Client and Server because it is a Peer to Peer app)). I do use startActivityForResult to start B for more of a kill signal than anything as the result.
Activity A uses a SupportMapFragment and Activity B cannot be a fragment because I want to be able to switch from B to A and then never use B again.
Originally, I started with one activity and tried switching between views using a ViewFlipper and just a call to setContentView(R.layout.my_layout_A) or setContentView(R.layout.my_layout_B). The fragment of course caused a lot of problems for both.
Using Fragments were confusing. The SupportMapFragment is the code for a Google Map which is a Fragment.
When I click a menu option inside of the MapsActivity (Activity A), I would like to be able to start myBluetoothActivity (Activity B) with a reference to the MapsActivity (Activity A) OR start myBluetoothActivity and then be able to set a reference to the caller inside of myBluetoothActivity (but this option would require having a reference to the BluetoothActivity inside of the MapsActivity or having some way to obtain the started activity from the intent).
//the following code is in Kotlin, but this can easily be converted over to java:
//option A: (pass it inside of the constructor)
var mbta:myBluetoothActivity = myBluetoothActivity(this)
//line for intent that I am unsure of
//intent so that I can start the activity with the pointer to the caller already passed into the new activity
startActivity(mbta)
//option B: (set this reference after obtaining a reference from intent):
var mintent:Intent = Intent(this.applicationContext, myBluetoothActivity::class.java)
startActivity(mintent)
//obtain the reference to the BluetoothActivity from the intent (NOT SURE HOW TO DO THIS???)
mbta.setCallerReference(this)
How can I accomplish this communication between the two activities via reference between the two activities? Should I use an interface for communication? If I should use it, (which I did try) how should I?
In other words, I am trying to access the caller activity (Activity A) from (Activity B) directly via a reference to Activity A inside of B OR trying to get the reference to B from the intent that started it inside of Activity A. I am trying to get a reference to that, so I can use it for communication/method calling/member variable and UI modification purposes.
NOTES: 1. The BluetoothActivity and the MapsActivity are NOT SERIALIZABLE. I tried serializing it and then adding it to the extras Bundle in the Intent and it just crashed saying that that was impossible to serialize due to BroadCastReciever. As this also deals with WIFI. Which I am highly considering separating out to be put with the BluetoothActivity in a future release.
I am also ASSUMING that Activity B will never just be started up by anything other than my MapsActivity class.
I am also new to Kotlin, but I know Java.
When I tried using an interface, I caused a StackOverflow error and I have no idea why.
I have read the documentation for Intents on the website.
I have done some research on here which gave me those ideas above. I am not sure how to implement them.
You are using the wrong approach. The solution requires a bit more work than you would think. The correct approach is to:
First, realize that these activities Activity A and Activity B (and any other activities) are activities that are specific to your application and you want to establish direct communication between them.
Second, realize that you are trying to get the current (or a previous) activity's context. The context will help serve the reference.
Third, you can create your own Activity and Application classes by extending the desired classes. The Application class is a low-level class used for the activities.
From here, you will be able to make use of the getApplicationContext() which will return your custom Application class.
Design: It is inside of your CustomApplication class that you must track the references to the activities that you want. From there all that you have to do is cast the getApplicationContext() to your CustomApplication class and then call your methods that access the Activity(ies). You must of course cast your Activities if you want to access certain instances of a specific activity that you created to its "type." For example:
MapsActivity mact = (MapsActivity)(((MyApplication)(this.getApplicationContext())).getCurrentActivity())
You must of course note that this activity must be already created (the onCreate method was already called) for this to return the current activity. The same of course goes for the other life-cycle methods for the activity as you will make a baseActivity which will deal with these as well as you will also have an Application life-cycle that will help deal with this too.
To answer the question: "How to get the current foreground activity context in android?" I turned to StackOverflow and found user: gezdy 's answer to be exactly what I needed at: How to get current foreground activity context in android?.
(BEGIN QUOTATION FROM: GEZDY)
You should manage activities references. Add the name of the
application in the manifest file :
<application
android:name=".MyApp"
....
</application>
Your application class :
public class MyApp extends Application {
public void onCreate() {
super.onCreate();
}
private Activity mCurrentActivity = null;
public Activity getCurrentActivity(){
return mCurrentActivity;
}
public void setCurrentActivity(Activity mCurrentActivity){
this.mCurrentActivity = mCurrentActivity;
}
}
Create a new Activity :
public class MyBaseActivity extends Activity {
protected MyApp mMyApp;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mMyApp = (MyApp)this.getApplicationContext();
}
protected void onResume() {
super.onResume();
mMyApp.setCurrentActivity(this);
}
protected void onPause() {
clearReferences();
super.onPause();
}
protected void onDestroy() {
clearReferences();
super.onDestroy();
}
private void clearReferences(){
Activity currActivity = mMyApp.getCurrentActivity();
if (this.equals(currActivity))
mMyApp.setCurrentActivity(null);
}
}
So, now instead of extending Activity class for your activities, just
extend MyBaseActivity. Now, you can get your current activity from
application or Activity context like that :
Activity currentActivity = ((MyApp)context.getApplicationContext()).getCurrentActivity();
(END OF QUOTATION FROM: GEZDY)
Note: All code is written in java for this answer.

java.lang.ClassCastException: android.app.Application cannot be cast to android.app.Activity [duplicate]

I'm trying to change a LinearLayout from another class, but when i run this code:
public class IRC extends PircBot {
ArrayList<String> channels;
ArrayList<Integer> userCount;
ArrayList<String> topics;
LinearLayout channelLayout;
Context context;
public IRC(Context ctx) {
this.setName("xxxx");
channels = new ArrayList<String>();
userCount = new ArrayList<Integer>();
topics = new ArrayList<String>();
context = ctx;
channelLayout = (LinearLayout) ((Activity) context).findViewById(R.id.channels);
}
i get a ClassCastException
context is the Main activity that extends Activity passed with a getApplicationContext();
LOGCAT
05-08 17:53:55.102 3736-3799/g.d.allinonechat E/AndroidRuntime﹕ FATAL EXCEPTION: Thread-5357
java.lang.ClassCastException: android.app.Application cannot be cast to android.app.Activity
at g.d.xxx.IRC.<init>(IRC.java:34)
at g.d.xxx.MainActivity$1.run(MainActivity.java:49)
at java.lang.Thread.run(Thread.java:856)
You are passing the Application Context not the Activity Context with
getApplicationContext();
Wherever you are passing it pass this or ActivityName.this instead.
Since you are trying to cast the Context you pass (Application not Activity as you thought) to an Activity with
(Activity)
you get this exception because you can't cast the Application to Activity since Application is not a sub-class of Activity.
in case your project use dagger, and then this error show up
you can add this at android manifest
<application
...
android: name = ".BaseApplication"
...> ...
In my case, when I'm in an activity that extends from AppCompatActivity, it did not work(Activity) getApplicationContext (), I just putthis in its place.
You are getting this error because the parameter required is Activity and you are passing it the Application.
So, either you cast application to the Activity like: (Activity)getApplicationContext();
Or you can just type the Activity like: MyActivity.this
In my case I just put android:name=".CustomBaseClass" inside the activity tag instead of the application tag inside the manifest, hope it helps someone.
You can also try this one.
override fun registerWith( registry: PluginRegistry) {
GeneratedPluginRegistrant.registerWith(registry as FlutterEngine)
//registry.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin")
}
I think this one is far better solution than creating a new class.
I had a similar problem when checking for internet connection in my viewmodel.
The error in my logcat:
java.lang.ClassCastException: android.app.Application cannot be cast to com.example.newsapplication.util.AppApplication in viewmodel
I added this line in the manifest and my application worked just fine.
android:name="com.example.newsapplication.util.AppApplication"
In my case, I just put add name property inside the application tag in the Manifest file
<application
android:name=".TodoApplication"
...
In my case I removed the line android:name ="<some_name>" and it worked. Looks like it was looking for a class with the name that was provided earlier whereas my Project does not have the class.
In my case, I deleted the android:name=".TodoApplication" from application and added it inside the activity tag.
<activity android:name=".BaseApplication"/>
Ensure you delete from the Application tag

getContext() method is undefined for the type MainActivity when get apps icon

I'm trying to get an icon of the installed app. Using the following way, I'm getting the error:
The method getContext() is undefined for the type MainActivity
try{
String pkg = "com.app.my";//your package name
Drawable icon = getContext().getPackageManager().getApplicationIcon(pkg);
imageView.setImageDrawable(icon);
}
catch (PackageManager.NameNotFoundException ne) {
}
It would be very helpful if someone could guide me. Thanks in advance!!
Delete getContext(). Activity extends Context. Just call getPackageManager().getApplicationIcon(pkg).
Activity class extends Context .So just call getContext();
This will make use of the activities layout defined context.

IllegalStateException while casting context

I am trying to cast an activity to a FragmentActivty object so I could get FragmentManager object
public class Main extends ListActivity {
...
public void showTimePickerDialog(View v) {
FragmentActivity myContext=(FragmentActivity) getApplicationContext(); //Here: java.lang.IllegalStateException: Could not execute method of the activity
FragmentManager fragManager = myContext.getFragmentManager();
DialogFragment newFragment = new uSharedUtility.TimePickerFragment();
newFragment.show(fragManager, "timePicker");
}
}
But when doing it I get:
java.lang.IllegalStateException: Could not execute method of the activity
I cant use getFragmentManager directly because my activity extends from ListActivity which is very necessary.
Please suggest me to get around this error, i really need to use both ListAdapter & Date/Time pickers in the same activity.
I cant use getFragmentManager directly because my activity extends from ListActivity which is very necessary.
It isn't necessary. You can have a ListView in any activity.
Since you're already using fragments, consider using a ListFragment with a FragmentActivity.
You can't cast Application Context to Activity, you must need Activity Context.
(FragmentActivity) getApplicationContext() // Not Possible
getContext(): Returns the context the view is currently running in. Usually the currently active Activity.
getApplicationContext(): Returns the context for the entire application (the process all the Activities are running inside of). Use this instead of the current Activity context if you need a context tied to the lifecycle of the entire application, not just the current Activity.

Categories