I'm setting up a notification class that needs to be independent of any Activity, but called through my main Application class. I'm having trouble accessing resources.
The Application class gets its context via context.getApplicationContext(), and this is passed to the constructor of my notification class:
NotificationService notificationService = new NotificationService(context, notifications);
I need to set the small icon from my Drawables, and when I add the R.drawable.tv_logo_notext_bw resource, the compiler cannot locate it:
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
builder.setSmallIcon(R.drawable.tv_logo_notext_bw);
Obviously, it needs a context, but the context was passed to the constructor of both my notification class and the NotificationCompatBuilder class, so I don't understand why the compiler cannot see the drawable.
Am I missing some crucial step?
Resource Id's are public static filed and being auto-generated by your Gradle & IDE, this means you should be able to call the from any part of you project,
your code looks fine.
Try the next step to "Refresh" your IDE (Android Studio)
1. Try to rebuild your project Build | Rebuild
2. Also try Choose File | Invalidate Caches/Restart.
Related
I try to create a template object of task using existing task object. When i use a special constructor I get the error:
incompatible types: Task cannot be converted to TaskTemplate
Here is the code I'm using the create the TaskTemplate:
TaskTemplate bean = new TaskTemplate(newTask);
Here is the constructor I'm calling:
public TaskTemplate(Task task) {
this.setTitle(task.getTitle());
this.setDate(task.getDate());
}
But when I set all properties in the place where object is created everything is ok.
TaskTemplate bean = new TaskTemplate();
bean.setTitle(newTask.getTitle());
bean.setDate(newTask.getDate());
Why does it happen?
How can I create a constructor which will get a task and create a template?
It is highly likely that you need to rebuild your project.
This kind of problem can happen when the compiled class the calling code is using is out of date with the source code you are viewing, causing great consternation when recent changes (such as creating a new constructor) do not seem to exist from the perspective of the calling code.
Most IDEs automatically rebuild as you code: Check that your IDE is configured to build automatically. If you aren't using an IDE, consider using one.
I am combining a static code analysis with a dynamic one. I basically create a new activity and set it up as the starting activity. During the run various methods in existing activities should be called.
I can call e.g. onCreate from outside, however, the super call to Activity will fail (or calls to SharedPreferences or other interesting classes) since Android does some initialization stuff when using the intents in order to call an activity (e.g. setting the context). But I need to somehow call methods like onCreate or onPause from outside while giving the target activity a valid context.
In my newly created activity I have got a valid context. I tried to pass it via calling ContextWrapper.attachBaseContext, but there is still a NullPointerException somewhere in Android due a the missing context. Is there some way to hack this somehow into a working state? Using reflection or other hacks would be no problem, since it is for analysis purposes only.
Thank you very much for any tips. I'd be able to modify the analyzed apps in any way to get this working.
However: Using an Intent is no option, since I cannot control which Activity-methods are being called, when and how often. I know that android has not been made for calling these methods directly, but it is not a common use case either :);
I have created a hack, which seems to help (I can get a valid context in the hacked activity). Let's see how far I get using this.
public static void hack(Activity hack, Activity main) {
try {
Field mActivityInfo = getField(Activity.class, "mActivityInfo");
mActivityInfo.set(hack, getClass("android.content.pm.ActivityInfo").newInstance());
Field mFragments = getField(Activity.class, "mFragments");
Field mContainer = getField(Activity.class, "mContainer");
Field mApplication = getField(Activity.class, "mApplication");
Field mWindow = getField(Activity.class, "mWindow");
Class FragmentManagerImpl = getClass("android.app.FragmentManagerImpl");
FragmentManager manager = (FragmentManager) mFragments.get(hack);
mApplication.set(hack, main.getApplication());
mWindow.set(hack, main.getWindow());
Class<?> FragmentContainer = getClass("android.app.FragmentContainer");
Method attachActivity = getMethod(FragmentManagerImpl, "attachActivity", Activity.class, FragmentContainer, Fragment.class);
attachActivity.invoke(manager, hack, mContainer.get(hack), null);
Method attachBaseContext = getMethod(ContextWrapper.class, "attachBaseContext", Context.class);
attachBaseContext.invoke(hack, new HackContext(main));
System.out.println("Hack performed");
} catch (Exception e) {
e.printStackTrace();
System.err.println("Hack failed :(");
}
}
I am trying to understand why we pass a Context instance to the Intent constructor? Why isn't it enough to do new Intent(SomeActivity.class)? Does Android enforce some restrictions or what?
I was trying to look at the code but all I find is that it gets the package name.
Intent documentation
To identify an Activity in an Android application unambiguously, you need to have both, the name of the application (aka Android application package), and the full name of the activity (java package name + class name of activity class). These are exactly those two parameters you give in constructor. Context is used to get Android application package name, and the class to get full class name.
An Activity with the same full name can be used in two applications. If you do not provide Context, then Android won't know which application an activity belongs to.
As you guessed, the Context in the constructor is used to get the package name of the application.
Inferring the package name from the class as in SomeActivity.class.getPackage().getName() does not work in every case, as it could be different from the application's package name.
I have Android application and own Application derived class holding some internal data.
Among other there are some string fields. The problem is that if I put the application in foreground, work on other application, switch back to my app again, the app may be restarted because it got killed by system. Unfortunatelly the Application object seems not to be created again because the onCreate method of application object doesn't get called and all fields are set to null. My Activity gets recreated but all Application's object fields are null. When is the Application.onCreate method called? How to handle it?
there is no onCreate that you can register to.in later API's there's a way to register to the Activity lifecycle functions. and then you can do what ever you want.
basically, what you should do is use SharedPrefrences for storing information.
what I would do is:
class MyApp extends Application {
private static String someResource = null;
public static String getSomeResource(Context context) {
if(someResource == null) {
SharedPrefrences prefs = (SharedPrefrences)
context.getSystemService(Context.SHARED_PREFRENCES);
someResource = prefs.getString(SOME_RESOURCE, null);
}
return someResource;
}
Application onCreate() will called only for one time during its life-cycle, i.e.. only when application is started.
As suggested by thepoosh below answer is valid ,if your application is killed,still the data is saved in shared preference.
This is confusing. I'm look at the Android 2.2.2_r1 source code for the NotificationManager class, and I see the method getService() which is defined as public and static. However, eclipse is telling me:
The method getService() is undefined for the type NotificationManager
on the line
Object o = NotificationManager.getService();
My project is building against Android 2.2/ API Level 8. I tried to use reflection to see the method names and modifiers, and sure enough, I got back
public static getService
Am I missing something here? Why would eclipse tell me this method doesn't exist?
You will find a very detailed answer in this post.
In short: Because you compile against the android.jar, which has all hidden methods (like the one you are trying to access) removed. They will only be there on runtime, for internal android usage.
But since you perhaps also need it. The right way to access the NotificationManager is via the getSystemService method of a context:
NotificationManager nm = (NotificationManager)ctx.getSystemService(Context.NOTIFICATION_SERVICE);
With context being a valid context (like your current activity).