What's the alternative of "ContactsContract.Contacts.LAST_TIME_CONTACTED"? - java

What should I use instead of ContactsContract.Contacts.LAST_TIME_CONTACTED? According to documentation, LAST_TIME_CONTACTED variable was deprecated. Even it was written in ContactsContract.class
/** #deprecated */
#Deprecated
String LAST_TIME_CONTACTED = "last_time_contacted";
Since it was deprecated then there must be another alternative. But why there's no alternative? Or why the documentation didn't link any alternative?
This constant was deprecated in API level 29.
Contacts affinity information is no longer supported as of Android version Build.VERSION_CODES.Q. This column always contains 0.
In Android Q or higher version, there's no alternative variable either?

There's no alternative - and it's intentional.
Google no longer wants developers with Contacts permission to be able to get access to data related to communication between the user and their contacts.
If you app is eligible to get the CALL_LOG or SMS permissions you can figure out the last contacted timestamp based on the call log / messaging history.
But these permissions are not allowed in Google Play unless your app is of a very specific use-case documented here.

Related

How do I use the amadeus-java SDK to test pricing and booking flights?

I understand that the amadeus-java SDK offers methods that simplify GET and POST calls to the Amadeus Self-Service API endpoint Flight Offers Search.
Is there a way to make POST calls to Flight Offers Price and Flight Create Orders within the SDK?
If the SDK does not have methods for this, how would I retrieve the access token I fetched via SDK to make those calls explicitly?
Thanks in advance!
Flight Offers Price and Flight Create Orders are about to be integrated into the Java SDK (PRs opened, a bit more work to do and you will be able to use them).
The other solution will be to use the methods post and get directly from our client like in the example below (that you can find the README description of the Java SDK):
You can make any arbitrary API call as well directly with the .get
method. Keep in mind, this returns a raw Resource
Response response = amadeus.get("/v2/reference-data/urls/checkin-links", Params.with("airlineCode", "BA"));
response.getResult();

queryPurchases() vs queryPurchaseHistoryAsync() in order to 'restore' functionality?

I'm using the Play Billing Library in order to trigger and manage purchases which in turn unlocked extra functionality within an app. This part is working.
However, what is the best way to 'restore' purchases. Say for example someone who has bought the app buys a new phone. Logs in to the Play Store, downloads my app and then finds that the payment screen to 'upgrade' is being displayed. iOS has a specific method for this but I'm not aware of one for Android.
My thoughts are to query the Play Store and confirm whether the account has previously SUCCESSFULLY purchased the item, if so then I will call the local upgrade function within the app.
It appears there are two similar methods. But which one should I used in this scenario? Where a user has either wiped their phone or bought a new one?
queryPurchases()? Or queryPurchaseHistoryAsync()?
You should use queryPurchases. That gives you all the current active (non-consumed, non-cancelled, non-expired) purchases for each SKU.
queryPurchaseHistoryAsync won't do what you need because it will only give you a list of the most recent purchases for each SKU. They may have expired, been cancelled or been consumed, and there's no way to tell. Therefore this response can't be used to tell what purchases to apply in your app.
So far as I can see, the only valid use for queryPurchaseHistoryAsync is to provide a user with a list of their purchase history. It's a bit of an oddball.
Note also: queryPurchases is synchronous so in most cases it needs to be run in some kind of background worker thread. I run mine in an AsyncTask.
Per documentation queryPurchases uses the Play Store app cache to get the results while queryPurchaseHistoryAsyncactually checks the Purchase AP for the most recent purchases. So, in your case you should check the Asyncmethod.
queryPurchases
Get purchases details for all the items bought within your app. This method uses a cache of Google Play Store app without initiating a network request.
queryPurchaseHistoryAsync
Returns the most recent purchase made by the user for each SKU, even if that purchase is expired, canceled, or consumed.
Also, make sure to check the documentation. It recommends to Cache purchase details on your servers.
https://developer.android.com/google/play/developer-api.html#practices
I know it's a bit late, but I just discovered this myself. Sharing my answer for others to benefit.
So I learned that queryPurchases() is cached locally on your device, but is updated when you call queryPurchaseHistoryAsync()
I discovered from this Stackoverflow answer here
So my solution, is when wanting to restore a purchase on a new device, or a fresh install of my app. Call queryPurchaseHistoryAsync() Then in the callback onPurchaseHistoryResponse() call queryPurchases() and look within the List<Purchase> from the PurchasesResult for the purchase status of any of the user's past purchases.
If there's an expected purchase your app can grant the entitlements of their past purchase.
The documentation has been updated for the latest versions of BillingClient. queryPurchases() is deprecated. Also note that queryPurchases() only ever returned purchases made by the current device, so that method will not inform your scenario of a new wiped phone. To get accurate information use the async calls.
queryPurchasesAsync() will return all active subscription and unconsumed one-time Purchase objects for the sku type provided. It gets the purchases from the local Play Services cache, so there are no guarantees the cache will contain purchases from another device in your "new phone" scenario, and no guarantees the cache will yet be current in your "wiped phone" scenario.
queryPurchaseHistoryAsync() will make a network request and return the most recent PurchaseHistory object for each sku matching the provided sku type, even if cancelled or consumed.
Also, to perform the upgrade call launchBillingFlow() with the appropriate BillingFlowParams and BillingFlowParams.SubscriptionUpdateParams for the sku you now know to be purchased.

Facebook data extraction

Can we extract/read the posts and comments from groups, which I am not owning on Facebook using Facebook4j or by some other API or method?
Check if group's privacy setting is OPEN.
Using getGroupFeed(String groupId), you could get the group's wall.
Once you are aware of groupId and that particular group is OPEN, I guess you could extract posts from that group.
Please check Facebook4j's documentation : Groups Interface in Facebook4j
Also, check Reference docs in Facebook developers regarding access token for groups here.
Hope it helps

Why use reflection for HttpResponseCache?

In the documentation of HttpResponseCache there is a section:
Working With Earlier Releases
This class was added in Android 4.0 (Ice Cream Sandwich). Use
reflection to enable the response cache without impacting earlier
releases:
try {
File httpCacheDir = new File(context.getCacheDir(), "http");
long httpCacheSize = 10 * 1024 * 1024; // 10 MiB
Class.forName("android.net.http.HttpResponseCache")
.getMethod("install", File.class, long.class)
.invoke(null, httpCacheDir, httpCacheSize);
}
catch (Exception httpResponseCacheNotAvailable) {
}
You can see this call via reflection in a questions here on SO (e.g. here), and examples on the web. I also took over code that contains this exact snippet to set up the cache (including the comment, so its probably just copypasta). However, I don't quite understand why you have to use reflection here.
Normally when I want to use a method added at a certain API level above my defined minSdkVersion, I would use the following pattern:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
// do something here
}
so why isn't this the default pattern for HttpResponseCache. What is the advantage of using reflection? It certainly doesn't add to the readability of my code. Does HttpResponseCache actually work below ICS when using reflection this way?
EDIT: I don't have an old Android device here and my emulator refuses to start at all, so I can't simply test it at the moment. Maybe it just crashes horribly without reflection.
What is the advantage of using reflection?
First, quoting the documentation:
This class was added in Android 4.0 (Ice Cream Sandwich).
By "was added", they mean "was added to the Android SDK", and by "Ice Cream Sandwich", they really mean Android 3.2 (API Level 13) based on the rest of the JavaDocs.
However, the HttpResponseCache class itself has existed in the framework for longer, hopefully since Android 1.0 given their recommendations. However, that class was marked with the #hide annotation, so it could not be used directly by apps until API Level 13.
Your Java version guard block using Build will avoid referencing this class directly on older devices. However, it does not actually configure the cache on older devices, either.
Their approach will work on all versions of Android and will allow you to configure the cache, as the class has existed since the beginning.
It is fairly rare that Google explicitly authorizes the use of reflection to get at hidden classes or methods this way, which is why you don't see it often in official documentation.
Unfortunately your suggestion will not work for older versions. Think about the following. They added method install(File, long) to new version. But the code that calls this method is packaged into other jar.
Now you have old version of jar that contains HttpResponseCache and new version of jar that calls it. If you write there
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
cache.install(file, number);
}
NoSuchMethodError will be thrown even if expression of if is false.
Using reflection is a ugly but useful technique to prevent this.

Getting exceptions from reccurent events in Google Calenader API v3

I have been developing an application to download whole calendars from all users in domain and save them in ICS format. The app is written in Java. I get access using 2L OAuth. So far I'm able to get most of calendar's data, excluding exceptions from recurrent events. Google API docs say that every recurrent event should contain a list of recurrence, including EXRULEs. But when I call the API I got only recurrent rule without exception.
It there any way to get these exceptions?
You get the exceptions as regular item and
event.getOriginalEvent()
will return reference to reccuring event.

Categories