How can i call a content provider myself in the code? - android

I want to remove this from my androidmanifest file :
<provider android:name="com.facebook.internal.FacebookInitProvider"
android:authorities="%package%.FacebookInitProvider"
android:exported="false" />
because it's make Facebook network request every time my app is launch, even if the user will never use any Facebook api. Instead, I want to call myself com.facebook.internal.FacebookInitProvider when I will need to use a Facebook API. How can I do it?

Related

Prevent network requests from Facebook Android SDK

The Android Facebook SDK is always making a network request to graph.facebook.com when calling FacebookSdk.sdkInitialize(context) even if nothing of the SDK has been used yet.
So if we're initializing it in the Application.onCreate() there will always be at least one network request. Even if the setting is as follows:
<meta-data
android:name="com.facebook.sdk.AutoLogAppEventsEnabled"
android:value="false" />
We've took a closer look at this because a user complained that he is not using the Facebook Login (which is why we have the Facebook SDK in the first place) and still there is "user data" transferred to Facebook. In times of GDPR and suspicious users, this is a very unfavourable behaviour!
What we're doing now is calling FacebookSdk.sdkInitialize(context) only when the user wants to use the Facebook Login (at the time when the user clicks on the button). Additionally, we removed the meta-data for android:name="com.facebook.sdk.ApplicationId" from the AndroidManifest. This prevents the initial network request but then there is the following crash appearing in the CurrentAccessTokenExpirationBroadcastReceiver:
java.lang.RuntimeException: Unable to start receiver com.facebook.CurrentAccessTokenExpirationBroadcastReceiver: The SDK has not been initialized, make sure to call FacebookSdk.sdkInitialize() first.
at com.facebook.internal.Validate.sdkInitialized(Validate.java:143)
at com.facebook.FacebookSdk.getApplicationContext(FacebookSdk.java:518)
at com.facebook.AccessTokenManager.getInstance(AccessTokenManager.java:86)
at com.facebook.CurrentAccessTokenExpirationBroadcastReceiver.onReceive(CurrentAccessTokenExpirationBroadcastReceiver.java:34)
Now there are several questions:
Why is Facebook still making a request at start? If they want to validate the auth token, they can do it as soon as the SDK is really used...
Does Facebook know and tolerate crashes when sdkInitialize() is not called? Because I fear when this NullPointerException is removed there will be other crashes...
Most important: Are there any other ways to prevent network requests from the Facebook SDK when its features are not used?
I have noticed that the Facebook SDK (at least in version 4.33) adds a provider (com.facebook.internal.FacebookInitProvider) in the manifest of your app, which automatically calls FacebookSdk.sdkInitialize with the application context.
Even if you have added:
<meta-data android:name="com.facebook.sdk.AutoLogAppEventsEnabled" android:value="false" />
in your manifest, at least 2 requests will be made to Facebook:
a graph request to get app settings
an Events request "fb_sdk_initialize" which logs all the Facebook frameworks that are included into your app
So to prevent these requests (that we don't want as long as the user didn't allow them (GDPR)), I think you did everything we need to do:
Do not add <meta-data android:name="com.facebook.sdk.ApplicationId" android:value="#string/facebook_app_id"/> in the manifest
Add <meta-data android:name="com.facebook.sdk.AutoLogAppEventsEnabled" android:value="false"/> in the manifest
Only initialize Facebook SDK when you need it.
Like this for example:
FacebookSdk.setApplicationId(<context>.getString(R.string.facebook_app_id));
FacebookSdk.sdkInitialize(<context>);
AppEventsLogger logger = AppEventsLogger.newLogger(<context>); // I don't use FB Login for my project but app events.
But regarding your crash, I don't know why it happens since it seems that the broadcast "com.facebook.sdk.ACTION_CURRENT_ACCESS_TOKEN_CHANGED" is sent locally.
Nevertheless, I think you can prevent it by adding this to your manifest:
<provider
android:name="com.facebook.internal.FacebookInitProvider"
tools:node="remove" />
<receiver
android:name="com.facebook.CurrentAccessTokenExpirationBroadcastReceiver"
tools:node="remove" />
However, doing this may have bad consequences with the use of Facebook SDK and I think you will have to provide (and register in your manifest) your own BroadcastReceiver:
public class CustomCurrentAccessTokenExpirationBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (AccessTokenManager.ACTION_CURRENT_ACCESS_TOKEN_CHANGED.equals(intent.getAction())) {
new CurrentAccessTokenExpirationBroadcastReceiver().onReceive(context, intent); // Call it only if you have initialized the Facebook SDK!
}
}
}
According to Facebook Support,
If you would like to temporarily disable automatic events collection, such as to get end-user consent before collecting data, you can set the value of AutoLogAppEventsEnabled to false in the app's AndroidManifest.xml in the application tag.
For example:
<meta-data android:name="com.facebook.sdk.AutoLogAppEventsEnabled" android:value="false"/>
To re-enable collection, such as after an end-user provides consent, call the setAutoLogAppEventsEnabled() method of the FacebookSDK class.
For example: setAutoLogAppEventsEnabled(true);
If you need to suspend collection again for any reason, you can call setAutoLogAppEventsEnabled(false); and collection will be suspended until re-enabling it.

How to create a ContactsContract.Directory provider and call it in Incoming/outgoing call?

I'm creating a ContactsContrat.Directory in my android app. That I want to do is: In incoming/outgoing call, the Android dialer do a query to my custom directory that I've registered.
This is the resource that I've read to do it: https://developer.android.com/reference/android/provider/ContactsContract.Directory.html
This is my code in the AndroidManifest:
<provider
android:name=".CustomContactProvider"
android:authorities="com.myapp.CustomContactProvider"
android:enabled="true"
android:exported="true"
android:grantUriPermissions="true"
android:multiprocess="true"
android:readPermission="android.permission.READ_CONTACTS"
android:writePermission="android.permission.WRITE_CONTACTS">
<meta-data
android:name="android.content.ContactDirectory"
android:value="true" />
</provider>
According with the android developer resource
"Custom Directories are discovered by the Contacts Provider following
this procedure: It finds all installed content providers with meta
data identifying them as directory providers in AndroidManifest.xml:
This tag should be placed inside the
corresponding content provider declaration."
with the meta-data should be working and do a call to my custom provider every time that the Contacts Provider is call it, but it doesn't work when I do a call or I open the contacts in my phone.
Any suggestion or idea of how to can do this?

Android Facebook ContentProvider and multiple Build Types

I have setup Facebook sharing with the below, build type specific content provider:
<provider
android:name="com.facebook.FacebookContentProvider"
android:authorities="com.facebook.app.FacebookContentProviderXXX${applicationId} ...
applicationId is different per build type, so that I am able to run debug and live builds side by side on one device.
This setup gives me an error on Facebook (image file) sharing:
IllegalStateException: A ContentProvider for this app was not set up in the AndroidManifest.xml, please add com.facebook.app.FacebookContentProviderXXX as a provider to your AndroidManifest.xml file. See https://developers.facebook.com/docs/sharing/android for more info.
How can I overcome this problem? How can I get Facebook to take into account my applicationId?
You Manifest code look like below for facebook login and sharing:
<meta-data
android:name="com.facebook.sdk.ApplicationId"
android:value="#string/{facebook_app_id}" />
<!-- To use Facebook Login or Share, also add the FacebookActivity to the manifest:-->
<activity
android:name="com.facebook.FacebookActivity"
android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation"
android:label="#string/app_name"
android:theme="#android:style/Theme.Translucent.NoTitleBar" />
<!-- If you're sharing links, images or video via the Facebook for Android app, you also need to declare
the FacebookContentProvider in the manifest. -->
<provider
android:name="com.facebook.FacebookContentProvider"
android:authorities="com.facebook.app.FacebookContentProvider${facebook_app_id}"
android:exported="true" />
NOTE:
Your app is currently live and available to the public.
Follow below step to make your facebook app live and public:
1) Goto https://developers.facebook.com/
2) Select your app and goto App Review tab.
3) Check YES for Your app is currently live and available to the public. option.
See I am new How do I make my app live on FB
Your “applicationId” probably is "com.myname.blabla", and XXX your facebook app id?
I think you should switch to using 2 facebook APP_ID's, and not "applicationId". Put the facebook APP_ID's in your build types and reference them in your manifest. You then don't need to add the "applicationId" from your app.
<provider
android:name="com.facebook.FacebookContentProvider"
android:authorities="com.facebook.app.FacebookContentProvider${FACEBOOK_APP_ID}"
android:exported="true" />
Try with this:
If your APP_ID is 95xxx3xx60xx73xx, then it should be like:
<provider
android:name="com.facebook.FacebookContentProvider"
android:authorities="com.facebook.app.FacebookContentProvider95xxx3xx60xx73xx"
android:exported="true" />
For more information, you can follow this link.

How can I automatically get OAuth 2.0 token and re-open my app?

I'm working with the Delivery.com API in building my app, and my current understanding of how the OAuth flow works is:
I redirect the user to the browser, where they explicitly sign in to their account. I supply a redirect_uri in the process.
Upon sign in, the user is redirected to the redirect_uri with an access token
I get the access token somehow, and use this to authenticate future actions in my app
It's step 3 that I'm struggling with - I've set up an Intent and intent-filter such that I correctly open the browser for step 1, and the user is correctly redirected back to my app in step 2. But this leaves two problems:
The redirect_uri which re-opens my app does so in the background - the browser never closes. I'm assuming there's a simple fix for this, but haven't been able to find it.
How do I get the access token? Is the only solution to redirect to another webpage which will display the token, and then have the user manually copy and paste this back into my app? Or can I somehow automatically get the token, re-open my app, and proceed?
EDIT: I was able to get this working - I'm not sure what was causing the issue in point #1 above, but after changing things back and forth a few times it started working as I originally had it. For anyone who looks into this in future, I had to include all the following elements in my Manifest.xml for it to work:
<action android:name=android.intent.action.VIEW"/>
<category android:name="android.intent.category.BROWSABLE"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="myapp.randomname" android:host="my_url"/>
Regarding problem #2, I was able to parse the response by using Uri data = getIntent().getData() and then calling data.getQueryParameter("fieldname").
Instead of launching external browser and using intent filters you should benefit more from using WebView directly in your app and getting thru OAuth with it.

Fiksu SDK Integration

I am trying to implement Fiksu SDK for Android and iOS.
I am able to add code to track registration and purchase :
FiksuTrackingManager.uploadRegistration(Context, FiksuTrackingManager.RegistrationEvent.EVENT1);
FiksuTrackingManager.uploadPurchase(Context, FiksuTrackingManager.PurchaseEvent.EVENT1, 0, "USD");
In iOS i am able to get the logs in the console, but in android i am only getting logs which event is called.How can i check the logs in Android ?
Also how to track the app events in Fiksu dashboard ?
They have also mentioned to add client id , from where will i get the client id ?
if any one has implemented it please guide me how to proceed ?
this might be too late but it may help someone that comes across this post.
I just had to integrate the Fiksu SDK for android for a client and face similar issues when testing.
How can i check the logs in Android ?
If the SDK has been properly installed you should be able to see some logs like below which means the events have been succesfully sent to their server.
11-25 10:04:31.010 21588-23132/ D/FiksuTracking? Event: Resume
11-25 10:04:32.320 21588-23132/ D/FiksuTracking? Successfully uploaded tracking information.
11-25 10:05:40.500 21588-23383/ D/FiksuTracking? Event: Purchase
11-25 10:05:42.180 21588-23383/ D/FiksuTracking? Successfully uploaded tracking information.
how to track the app events in Fiksu dashboard ?
This part is quite annoying as they don't have a way to create Apps in the dashboard and link them to your android app so you can see your events coming through. Instead you have to actually perform the test and send them an email for someone from Fiksu to check their servers and track your events.
These are the test steps as per their documentation:
Download and install your application on an Android device and perform your tests.
Fill a form they have and send it via email to their support team.
Someone will get back to you confirming if they have received your events.
They have also mentioned to add client id , from where will i get the client id ?
The clientId is just an identifier for your users within your app. In other words you can set that to whatever you want (e.i. email address). The suggestion is to set this after a user has registered or logged in in your app.
FiksuTrackingManager.setClientId(Context, "XXX");
Based on their documentation: "Where XXX would be the ID you want to send and can be any alphanumeric string up to 64 characters long. All events sent after this call is made would send the Client ID that has been set. If you call setClientID again it will overwrite whatever was there before. However the first Client ID sent with an event will be the Client ID that is in the export on the Fiksu Client Dashboard and it will not get updated."
if any one has implemented it please guide me how to proceed ?
So to sum up below are the steps to integrate the Fiksu SDK for android.
Downlaod the SDK.
Add the SDK jar to your project.
Set the isntall receiver (Only if you want to track app installs). NOTE that they expect to be the only receiver in the AndroidManifest.xml file. If you are using other third party SDKs to track the same you either:
Use fiksu to forward the intent:
<receiver android:name="com.fiksu.asotracking.InstallTracking"
android:exported="true">
<intent-filter>
<action android:name="com.android.vending.INSTALL_REFERRER" />
</intent-filter>
<!-- Forward to other receivers -->
<meta-data android:name="forward.1"
android:value="com.google.android.apps.analytics.AnalyticsReceiver" />
<meta-data android:name="forward.2" android:value="com.mypackage.thirdparty.MdotmReceiver" />
</receiver>
Or set the below flag in your AndroidManifest and have another install receiver forward it to the fiksu SDK.
<meta-data android:name="FiksuDisableReceiverCheck" android:value="true" />
Set the permissions in your AndroidManifest.
android.permission.INTERNET
android.permission.READ_PHONE_STATE
Initialize the SDK. Normally on your Application onCreate() method.
FiksuTrackingManager.initialize(this);
Setting up Google Play Services on your project.

Categories

Resources