difference between intent.setClass() and intent.setComponent() - android

I am looking at a tutorial and see the author using intent.setClass() to get the to the next Activity and then on the same page he uses intent.setComponent() to get to the next Activity.
So what is the difference and what is the advantage in using any of them?

Other than different parameters.
intent.setcomponent() = Explicitly set the component to do the handling of the intent.
intent.setClass() = Convenience for calling setComponent(ComponentName) with the name returned by a Class object.
another difference is that .setComponent() can find the appropiate class for you.
*From android Developers*
SetComponent Android Dev
You should only set this value when you know you absolutely want a specific class to be used; otherwise it is better to let the system find the appropriate class so that you will respect the installed applications and user preferences.

Related

does the context passed on getDefaultSharedPreferences affects the result?

I'm getting an weird error so I'm trying to eliminate the possibilities.
Does the context passed to PreferenceManager.getDefaultSharedPreferences() changes the result?
I mean, when i'm writting setting to my app i never pay attention which context i pass to this method since it is a valid context...
Sometimes i put the Activity, sometimes the Appliaction whatever context i've on hands
Is it wrong? I've noticed that i'm getting wrong preferences values at some point, and i dont know if there is a bug in my code or if this be
It doesn't matter whether you provide an Application or an Activity as the Context parameter for PreferenceManager.getDefaultSharedPreferences().
If you look at the source for getDefaultSharedPreferences():
return context.getSharedPreferences(getDefaultSharedPreferencesName(context),
getDefaultSharedPreferencesMode());
Looking further, into getDefaultSharedPreferencesName(context):
return context.getPackageName() + "_preferences";
This means that for any Context of your application, you'll get the same SharedPreferences back, as your application ID does not change based on Activity or Application.
The only time you could run into a potential issue is if you are manually creating a Context for another package (e.g. using Context.createPackageContext()).
SharedPreferences data stores all have a name, and as long as you use the same name you'll always get the same data store.
Hat tip to #kcoppock who has pointed out that in the particular case of PreferenceManager.getDefaultSharedPreferences(), the only thing the generated name is dependent on is the Context's package. Since any Application or Activity instance you pass is exceedingly likely to have the same package name, in your case you should always get the same data store.
There are other ways to retrieve SharedPreferences stores, though. Activity.getPreferences() will generate the name based on the Activity's class name, so calling getPreferences() from inside two different activities will give you two different data stores.
You can also call Context.getSharedPreferences() directly (both PreferenceManager and Activity just call through to this) and pass a data store name explicitly. There's no requirement for how the name should look; as long as you use the same name you'll always get the same data store.
https://developer.android.com/reference/android/content/Context#getSharedPreferences(java.lang.String,%20int)

How to get programmatically the data usage limit set by user on Android OS configuration?

User can define at Data Usage screen a limite and/or a warning limit for mobile data usage. So how can I get this information by code?
Screen of Data Usage configuration of native OS.
I wanna the limit value and warning value.
I've already tried this but not work and always return NULL to both:
final Long recommendedBytes = DownloadManager.getRecommendedMaxBytesOverMobile( this.context );
final Long maximumBytes = DownloadManager.getMaxBytesOverMobile( this.context );
// recommendedBytes and maximumBytes are NULL
And TrafficStats class just have a data transferred not the limits.
After days searching and research about this problem I couldn't find a answer for that. Bellow I will lift every attempt that I did.
1. Download Manager
With this class you can start download over any network or device
state and it will handle all states e.g. network loss, device reboot,
etc...
There are two methods called getMaxBytesOverMobile and
getRecommendedMaxBytesOverMobile, they was a pretty candidate
to solve this problem at first time. But after code tests and
Download Manager implementantion research I'd found that there is
no way to get thoose values by DownloadManager.
Reason
Thoose methods call Settings.Secure.getLong with they
respective labels
Settings.Secure.DOWNLOAD_MAX_BYTES_OVER_MOBILE and
Settings.Secure.DOWNLOAD_RECOMMENDED_MAX_BYTES_OVER_MOBILE in
the turn makes a call to a lazy String map inside inside a
inner class called NameValueCache.
Ok so far but none of inner classes or Settings implementation it
self use DOWNLOAD_MAX_BYTES_OVER_MOBILE or
DOWNLOAD_RECOMMENDED_MAX_BYTES_OVER_MOBILE inside.
I considered the lazy map was populate by a third entity, what
actually happens, so I found the NameValueTable Settings
inner class that handle the new values to lazy map. The
putString is a protected method call by Settings.Secure
and Settings.System inner classes (calls of Secure and
System).
So I could conclude that if the OS implementantion do not put thoose String values I can't get them.
2. TrafficStats
Just a quick look on official reference I could notice that it will
not help me because this class just provide the amount of bytes and
packages that was trafficked since last device boot.
http://developer.android.com/reference/android/net/TrafficStats.html
3. NetworkPolicyManager and NetworkPolicy
As #bina posted here the both classes are hidden and could not
be use by normal apps e.g. that will be published in Google Play.
https://stackoverflow.com/a/24445424/575643
4. ConnectivityManager
In short, you just can get the NetworkInfo that not provide
much information about user preferences (really none!). Just provide
informations about network and e.g. mobile network provider.
http://developer.android.com/reference/android/net/ConnectivityManager.html
After all I assume that no way to get this information nowadays. Please if you read it and found a way post here!
Thanks for all.
PS.: Sorry by english mistakes.
Do you want to get limit value(5GB) and warnning value(2GB) in this example?
If so, you can get limitBytes and warningBytes by the following code, if you can use android.permission.MANAGE_NETWORK_POLICY and android.permission.READ_PHONE_STATE.
However, android.permission.MANAGE_NETWORK_POLICY protectionLevel is signature.
NetworkPolicyManager manager = (NetworkPolicyManager) getSystemService("netpolicy");
NetworkPolicy[] networkPolicies = manager.getNetworkPolicies();
Log.d("NetworkPolicy", "limitBytes is " + networkPolicies[0].limitBytes);
Log.d("NetworkPolicy", "warningBytes is " + networkPolicies[0].warningBytes);
(NetworkPolicyManager and NetworkPolicy classes are hidden)

How to make a small change to Android source code, and incorporate into your own project

I want to make a small change to the Android standard TimePicker class. Specifically, I'm trying to change it so it works in 15 minute increments, rather than 1 minute increments.
This post helped me constrain the range of minute values to {0, 15, 30, 45}, as required in my app. But as I pointed out in a follow up comment, the minute spinner still shows previous minute as current value - 1, and the next minute as current value + 1, which creates a sloppy-feeling user interface.
I looked into the relevant Android source code, and it appears that the changes I would need to make are pretty simple. But when I tried copying the source code into my project I got about a zillion errors relating to the package declaration, where to find Widget, how to resolve R.id variables, etc.
So my question is:
What's the best way to make a small change to a given class from Android source code, and incorporate it into your own project?
In my case, I just need to make a few small changes to TimePicker and NumberPicker, but I'm not sure how to properly set this up in my project.
Thanks for any suggestions.
But when I tried copying the source code into my project I got about a zillion errors relating to the package declaration
Your source file's directory needs to match the package name. And since you cannot overwrite android.widget.TimePicker, you will either need to move that class to a new package or give it a new name.
where to find Widget
That implies that you copied TimePicker into one of your packages. That is fine, but then you need to add in the appropriate import statements for classes that TimePicker referred to from its original package. Or, you need to keep your (renamed) TimePicker in android.widget, adding this package to your project. This is rudimentary Java.
how to resolve R.id variables
If TimePicker relies upon resources that are not part of the Android SDK, you will need to copy those resources from the AOSP into your project as well.
What's the best way to make a small change to a given class from Android source code, and incorporate it into your own project?
IMHO, that cannot be answered readily in the abstract. Generally speaking, you do the sorts of things that I listed above.
You are best off subclassing the relevant classes and overriding the methods you would like to change.
In Java, you can do the following in a subclass:
The inherited fields can be used directly, just like any other
fields.
You can declare a field in the subclass with the same name as
the one in the superclass, thus hiding it (not recommended).
You can
declare new fields in the subclass that are not in the superclass.
The inherited methods can be used directly as they are.
You can write a new instance method in the subclass that has the same signature as the one in the superclass, thus overriding it.
You can write a new static method in the subclass that has the same signature as the one in the superclass, thus hiding it.
You can declare new methods in the subclass that are not in the superclass.
You can write a subclass constructor that invokes the constructor of the superclass, either implicitly or by using the keyword super.
More info on subclassing in Java

Robolectric Custom Shadow Object

OOTB, Robolectric does not support Locales that well. Therefore, if your app is dependent on locales (which a lot of apps are if they are i18n'nd properly) this can be a royal pain. Long story short, I created my own ShadowFooGeocoder and ShadowFooAddress that allow me to simulate the locale I want. They're basically re-implementations of the existing shadows.
However, when I bind my class as such: bindShadowClass(ShadowFooGeocoder.class), this works great. At runtime, the correct shadow is returned. The problem is that I want to set up the simulations on this object and I'm not sure how. shadowOf(instance) where instance is an injected GeoCoder returns ShadowGeoCoder. I've tried working directly with the ShadowWrangler, but that also returns a ShadowGeocoder.
How can I get at my shadowed class that I've bound through the bindShadowClass(...) call so I can set my expectations (simulations)?
Note: This is a repost of the same question on the Robolectric group here. I posted here because my success rate of getting anyone to answer questions on the group is fairly low. I'm hoping for a better result here.
What I've basically done here is extend ShadowGeocoder like this:
#SuppressWarnings({"UnusedDeclaration"})
#Implements(Geocoder.class)
public class ShadowFooBarGeocoder extends ShadowGeocoder {
// implementation stuff
}
Then I would bind it using the bindShadowClasss(...) and when I retreive the shadow via the static shadowOf(...) call I get back a "ShadowGeocoder" which is an instance of ShadowFooBarGeocoder. I then cast it to that type and perform whatever work I need to.

Android activity naming

I'm running into more and more naming clashes between Android activities and other classes. I was wondering if you could tell me how you avoid these. Sadly, my particular naming problems are not covered in the related questions on SO.
First example
I have an activity that displays a level of the game. However, the data required for that level (background artwork, entities etc.) is stored in a separate class. Naturally, I would call the latter class Level. However, I would call the activity Level as well, because it displays levels.
Second example
I have an activity that plays back a cut scene. It basically displays several images in a row. The information which image is shown for how long is stored in a separate class. As in the previous case, I would naturally call both classes CutScene.
How would you solve these naming issues? Name the activities LevelActivity and CutSceneActivity? Name the representation classes LevelModel and CutSceneModel? Something else?
I solve those problems by either prefixing or postfixing classes with their "type", like you suggested at the end of your question :
LevelActivity, GameActivity, MainActivity, ...
CommentsListAdapter, ...
CheckNewCommentsService, ...
and so on.
But I generally do an execption for the model classes, which are the objects that contain that data : I would still name my Level model class Level, and not LevelModel, to indicate I'm manipulating, and working with, a Level.
Another solution (longer to type ^^) might be to use fully-qualified names (see here) when referencing your classes :
com.something.yourapp.activity.Level
com.something.yourapp.model.Level
With this, you always know which class is really used.
In general the best way to name android application components is to add its "component type" as suffix.
Example :-
LevelActivity (LevelActivity extends Activity)
InboxUpdateService (InboxUpdateService extends Service)
ContactsContentProvider (ContactsContentProvide extends ContentProvider)
SMSBroadcastReceiver (SMSBroadcastReceiver extends BroadcastReceiver)
By naming using above method there will be minimal chances of losing track when you're working on big code flow with lots of similar names in your application.
So, name your Activities with suffix "Activity".
And name the Class which provides Data to your LevelActivity as Level.
In Contradiction to second part of Pascal MARTIN's answer, you can also use LevelActivity and LevelInfo together. Because they offer clear difference as quoted below:
Distinguish names in such a way that the reader knows what the
differences offer
- Robert. C. Martin, author of Clean Code
But the suffix are often redundant on cognitive basis. Using only the word Level clearly emphasises that class Level offers information about Level.
So, use Level for class that provides data about Level.
NOTE : If you're using suffixes, choose one word per concept.
For Example: If you're using the suffix Info to identify classes that offer information then only Info should be used (not Data or Model) throughout your application to avoid confusions.

Categories

Resources