Ever since KitKat was released, I've noticed a whole bunch of my apps updating with "Fixing a crash in Kit Kat". Recently when I released my own app, I figured out the likely source of that is the new "isValidFragment" requirement for using preference activities. I haven't been able to get anyone, however, to explain why this new class is suddenly needed to validate fragments. Can anyone offer me an explanation of why this is required?
Subclasses should override this method and verify that the given fragment is a valid type to be attached to this activity. The default implementation returns true for apps built for android:targetSdkVersion older than KITKAT. For later versions, it will throw an exception.
A New Vulnerability in the Android Framework: Fragment Injection
We have recently disclosed a new vulnerability to the Android Security
Team. The vulnerability affected many apps, including Settings (the
one that is found on every Android device), Gmail, Google Now, DropBox
and Evernote. To be more accurate, any App which extended the
PreferenceActivity class using an exported activity was automatically
vulnerable. A patch has been provided in Android KitKat. If you
wondered why your code is now broken, it is due to the Android KitKat
patch which requires applications to override the new method,
PreferenceActivity.isValidFragment, which has been added to the
Android Framework.
http://securityintelligence.com/new-vulnerability-android-framework-fragment-injection/
http://securityintelligence.com/wp-content/uploads/2013/12/android-collapses-into-fragments.pdf
Here: http://commonsware.com/blog/2013/12/13/sanitize-all-the-extras.html it is suggested that this was introduced as a security fix:
PreferenceActivity supports extras to load specific
PreferenceFragments into the activity. This is used heavily by the
Settings app, to allow apps to drive straight into particular screens
(actually fragments). Unfortunately, there was no logic in
PreferenceActivity to ensure that only those fragments that were
supposed to be externally reachable were loaded via these extras —
hence, the addition of isValidFragment(). So, a properly-crafted
Intent can open any exported PreferenceActivity and launch any
PreferenceFragment from it, in the absence of such defenses.
(bold text added by me)
You got this documented:
Subclasses should override this method and verify that the given
fragment is a valid type to be attached to this activity. The default
implementation returns true for apps built for
android:targetSdkVersion older than KITKAT. For later versions, it
will throw an exception.
so as long as your targetSdk is below 19, you do not need to care. If it is 19 then your app will crash due to the exception, unless you implement isValidFragment()..
Taken from a blog of commonsware.
Once you target API Level 19 or higher, you will need to override isValidFragment() in your PreferenceActivity, to validate that the supplied fragment class name is indeed something that should be displayed. Off the cuff, this feels like some hack to deal with a security flaw.
Documentation says
protected boolean isValidFragment (String fragmentName)
Subclasses should override this method and verify that the given fragment is a valid type to be attached to this activity. The default implementation returns true for apps built for android:targetSdkVersion older than KITKAT. For later versions, it will throw an exception.
Related
I saw this class before but cannot use it and I don't see many sample that use it. What exactly is the difference of NotificationChannelCompat from regular NotificationChannel?
NotificationChannels are only supported on SDK 26+. So the idea is that NotificationChannelCompat gracefully handles the situation where you call methods related to NotificationChannels on unsupported SDKs. Rather than crashing your app, it simply does nothing or returns an empty list on an unsupported SDK. So this avoids the situation where you need to handle notifications differently on SDK 26+ and SDK < 26. In practice, this isn't a big deal so nobody bothers with it.
I was going through the Android documentation and I came across below lines:
In a very small number of cases, parts of the API may be modified or
removed, although typically such changes are only needed to ensure API
robustness and application or system security.
Is there an example of such removal of public API?
It would be interesting insight for all of us, developers, to understand why an API is removed and what can possibly be removed in Future based on this previous history.
The Apache HTTP client was deprecated in API 22 and removed in API 23. In this case it appears that they only removed it from the stub library, so apps using it will still run on Android M. You just can't compile them for Android M.
Google has also effectively removed features by changing the way APIs work. An example of this was the change to ActivityManager#getRunningTasks(int) in API 21. The method is still there, but it no longer allows you to discover what other apps are running, which is what many developers were using it for. Another example is how network activity on the main thread started throwing a NetworkOnMainThreadException in Android 3.0. In both of these examples, the documentation described the intended use of the API long before they began enforcing it.
AndroidStudio began to show me warning "WebView.addJavascriptInterface should not be called". But this method exists and is not deprecated. What's wrong with it? May be I am missing something and now there is better way to make interaction with Javascript?
It has known security vulnerabilities in earlier Android versions. From the docs:
This is a powerful feature, but also presents a security risk for
applications targeted to API level JELLY_BEAN or below, because
JavaScript could use reflection to access an injected object's public
fields. Use of this method in a WebView containing untrusted content
could allow an attacker to manipulate the host application in
unintended ways, executing Java code with the permissions of the host
application. Use extreme care when using this method in a WebView
which could contain untrusted content.
I see quite a few good old useful methods or even entire classes being "deprecated and obsolete".
But code that used to call those methods continues to work. So, what does this mean to me, as an Android applications developer?
Continue using this method as long as I want, because newer SDKs
will always remain backward compatible.
It will work as long as I build for older targets (e.g. API 8), but
if I build from API 14 up, the compiler will refuse to complete
the build.
Both (1) and (2)
Other?
This is especially confusing when no alternatives are provided, as in the case of WebView.PictureListener.html#onNewPicture.
It usually means that there's either a better way of doing things or that the deprecated functionality had some irreparable flaw and should be avoided. You can usually keep using deprecated methods, but you are advised to either switch to some new API (in the first case) or find some other way of doing what you want (in the second).
Regarding onNewPicture in particular, the entire PictureListener interface is deprecated. There's no sign of what, if anything, is supposed to replace it. A comment by #CommonsWare in this thread is food for thought:
It is conceivable that upstream changes in WebKit are driving the deprecation and that support for PictureListener might be totally lost in some future release.
I would go with 4:
It will basically tell you that the use of the method or class is discouraged; it is NOT 100% that they will keep backward compatibility (they can decide to not include that method in future releases), so you should try to use the replacement of the method or class. This is sometimes not possible to use the new methods (for instance, if you want to support devices running older versions).
Some other times it is actually possible. For instance, the showDialog method is now deprecated and they recommend to use DialogFragment class. You can achieve that even in older versions of Android by using the compatibility library.
Deprecated methods are not guaranteed to remain backwards compatible. They might remain in there for a few more releases just to give everyone a chance to migrate away from them before the developers remove them. The fact that they're deprecated means that the developers think that there's an easier, faster, neater, or otherwise better way to do whatever that class or method does.
It's probably better to change your code to use a non-deprecated interface now, since if you wait and it does get removed, your users will see crashes and errors.
Even when they are deprecated, they may compile but not work. Google has decided to delete various functionality at the low OS level.
Case in point. Google, at android release 2.3 deprecated many but not all method API's that allowed call recording. They compile OK but do not function since Android 2.3 and forward on any android phone device, or tablet with phone capabilities.
As an example for a deprecated interface that has been removed in a later API level, consider the org.apache.http package: It has been deprecated in API level 22 and removed in API level 23.
Of course on actual Android devices, the classes contained in that package will still be available in the system libraries (otherwise, applications targeting an older Android release would no longer run on that device).
They are however not available in the SDK anymore, so compilation will fail unless you either change the target/build SDK to an older version (or manually include the deprecated classes).
If Google were really determined to discourage use of those libraries, they could modify the implementation so that the affected classes check the target API version of the running application and complain and/or throw a runtime exception.
I'm trying to (correctly) implement a preferences screen, but the problem is that all the methods used to read preferences from xml files are deprecated (or I just don't recognize them). The official sample code on the dev site (PreferenceActivity) uses deprecated methods. Has anyone found out a way to implement a preferences screen with an xml file but without using either: addPreferencesFromResource(int) or findPreference(CharSequence)? Or have the methods just been marked deprecated without implementing the alternative yet?
EDIT: Developing for Android version 2.1
Why its deprecated and what is the alternative is pretty well explained in documentation:
This is the base class for an activity to show a hierarchy of preferences to the user. Prior to HONEYCOMB this class only allowed the display of a single set of preference; this functionality should now be found in the new PreferenceFragment class. If you are using PreferenceActivity in its old mode, the documentation there applies to the deprecated APIs here.
In other words, if you want to be HONEYCOMB compliant, then you should use PreferenceFragment for your PreferenceActivity. A detailed explanation on how to use fragments can be found in dev guide.
In Android 3, API Level 11, the fragment-based preference model was introduced, thus deprecating methods that "is not relevant for a modern fragment-based PreferenceActivity."
Since the online reference is the latest version, it shows the methods as deprecated. By manipulating the API Level dropdown, you can mark the methods that are not in the given Android version, but it doesn't update the descriptions to match, which is why it still shows up as deprecated.
If you don't plan on supporting Android 3+ you should just use the old methods, as the fragment-based solutions will not work to versions prior to this.