Trying to connect Firebase plus FB Auth and get error - android

Trying to connect FB Auth to Firebase. Appears error
FATAL EXCEPTION: main
Process: com.borisruzanov.social, PID: 20684
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.borisruzanov.social/com.borisruzanov.social.FacebookLoginActivity}: A valid Facebook app id must be set in the AndroidManifest.xml or set by calling FacebookSdk.setApplicationId before initializing the sdk.
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2665)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Caused by: A valid Facebook app id must be set in the AndroidManifest.xml or set by calling FacebookSdk.setApplicationId before initializing the sdk.
at com.facebook.FacebookSdk.sdkInitialize(FacebookSdk.java:276)
at com.facebook.FacebookSdk.sdkInitialize(FacebookSdk.java:232)
at com.borisruzanov.social.FacebookLoginActivity.onCreate(FacebookLoginActivity.java:49)
at android.app.Activity.performCreate(Activity.java:6679)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2618
Here is my manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.borisruzanov.social">
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".AuthPage">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".GoogleSignInActivity" >
</activity>
<activity android:name=".PhoneAuthActivity" >
</activity>
<activity android:name=".FacebookLoginActivity"
>
<meta-data android:name="com.facebook.sdk.ApplicationId"
android:value="#string/facebook_app_id"/>
</activity>
<activity android:name="com.facebook.FacebookActivity"
android:configChanges=
"keyboard|keyboardHidden|screenLayout|screenSize|orientation"
android:label="#string/app_name" />
<activity
android:name="com.facebook.CustomTabActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="#string/fb_login_protocol_scheme" />
</intent-filter>
</activity>
</application>
</manifest>
And also i dont understand why initialization of SDK is not actual and it stroked. I have tried solutions which on stack. Doesn't help.
Also if any1 know the good example where Firebase and Facebook auth integrated well? Because as always firebase guide is totally collapsed my brain.

You need add
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//initialize Facebook SDK
FacebookSdk.sdkInitialize(getApplicationContext());
if (BuildConfig.DEBUG) {
FacebookSdk.setIsDebugEnabled(true);
FacebookSdk.addLoggingBehavior(LoggingBehavior.INCLUDE_ACCESS_TOKENS);
}
setContentView(R.layout.activity_main); }
Need add meta-data to Application
<application android:label = "#string/app_name" ... >
...
<meta-data android:name = "com.facebook.sdk.ApplicationId" android:value = "#string/facebook_app_id" />
...
</ application>
instead of
<activity android:name=".FacebookLoginActivity"
>
<meta-data android:name="com.facebook.sdk.ApplicationId"
android:value="#string/facebook_app_id"/>
</activity>

You don't really need to initialize FacebookSDK manually as it gets initialized automatically, just change your manifest file as #Boris showed. Hope it will work now.

Related

Android: Amplify SignOut closes app before actually signin out

I decided to use Amplify on a school project, after I went through the Login process following this guide: https://docs.amplify.aws/lib/auth/signin/q/platform/android/
And also after adding the social sign in: https://docs.amplify.aws/lib/auth/social_signin_web_ui/q/platform/android/
After following these guides I decided to also add a signout feature and test it out: https://docs.amplify.aws/lib/auth/signOut/q/platform/android/
It should have worked fine but when i lauch the signout method in the guide (literally after copying and pasting it in the project) the app closes as soon as I test it, and it isn't even consistent with the errors, the usual pattern is: it closes, after a while the console says that the signout timed out (obviously) when I reopen the app from the VM it says that it signout successfully then crashes giving this error (the project is called natour):
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.natour, PID: 7330
java.lang.RuntimeException: Unable to resume activity {com.example.natour/com.amazonaws.mobileconnectors.cognitoauth.activities.CustomTabsManagerActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.content.Intent.migrateExtraStreamToClipData()' on a null object reference
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3400)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3440)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2713)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.content.Intent.migrateExtraStreamToClipData()' on a null object reference
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1516)
at android.app.Activity.startActivityForResult(Activity.java:4224)
at android.app.Activity.startActivityForResult(Activity.java:4183)
at android.app.Activity.startActivity(Activity.java:4507)
at android.app.Activity.startActivity(Activity.java:4475)
at com.amazonaws.mobileconnectors.cognitoauth.activities.CustomTabsManagerActivity.onResume(CustomTabsManagerActivity.java:69)
at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1269)
at android.app.Activity.performResume(Activity.java:6766)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3377)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3440)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2713)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)
I tried different things, thinking that if the login worked just fine, then something weird happened for the logout redirect uri, but nope, i changed it with "amplify update auth" on the console, changed the callback uri and nothing appened, the same error, the login worked just fine too even though I wrote an activity that wasn't even launched.
I changed the manifest because maybe the custom tab manager activity gave problems but to no avail (meaning it either gives far worse problems to which I know the cause or the same)
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.natour">
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" tools:ignore="QueryAllPackagesPermission" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission
android:name="android.permission.GET_ACCOUNTS"
android:maxSdkVersion="22" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<queries>
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="natour" />
</intent>
<intent>
<action android:name="android.support.customtabs.action.CustomTabsService" />
</intent>
</queries>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.NaTour">
<activity
android:name=".view.TransazioneRegister"
android:exported="false" />
<activity
android:name=".visualizza_foto_inserite"
android:exported="false" />
<activity
android:name=".visualizza_segnalazioni_effettuate"
android:exported="false" />
<activity
android:name=".visualizza_itinerari_inseriti"
android:exported="false" />
<activity
android:name=".visualizza_recensioni_inserite"
android:exported="false" />
<activity
android:name=".view.InserimentoItinerario"
android:exported="false" />
<activity
android:name=".view.Profile"
android:exported="false" />
<activity
android:name=".view.Register"
android:exported="false" />
<activity
android:name=".view.Login"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".view.VisualizzaItinerario"
android:exported="false" />
<activity
android:name=".view.TabActivity"
android:exported="false" /> <!-- Facebook Requirements -->
<meta-data
android:name="com.facebook.sdk.ApplicationId"
android:value="#string/facebook_app_id" />
<activity
android:name="com.amplifyframework.auth.cognito.activities.HostedUIRedirectActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="natour"/>
</intent-filter>
</activity>
<activity
android:name=".view.Signout"
android:exported="true">
<intent-filter>
<data android:scheme="natour"/>
</intent-filter>
</activity>
<!--<activity
android:name="com.amazonaws.mobileconnectors.cognitoauth.activities.CustomTabsRedirectActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="natour" />
</intent-filter>
</activity>-->
</application>
</manifest>
this is the manifest in the final attempt, after that i gave up.
I searched this problem online and even though they got pretty close to our problem, either they didn't show the solution, the code is written in other programming language, they didn't explain what was going on. I hope to find some help here, thanks in advance.
I know this has been a while but I found that you need to change launchMode. I tried singleTask it works fine. Maybe singleInstance also works. But I get a time out error: Timed out while waiting for sign-out redirect response.
I found amplify is difficult to deal with because lack of documents and potential bugs, maybe also because not many people use it.

android.content.ActivityNotFoundException: Unable to find explicit activity class {com.myapp/androidx.fragment.app.FragmentActivity}

I am using BottomNavigation Menu in my app which has 4 submenus: Address, Dashboard, Home, Notifications.
When I want to startActivity from HomeFragment to Dashboard Fragment it gives me error that I have depicted below.
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.karatasyazilim.su, PID: 21216
android.content.ActivityNotFoundException: Unable to find explicit activity class {com.karatasyazilim.su/androidx.fragment.app.FragmentActivity}; have you declared this activity in your AndroidManifest.xml?
at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:2069)
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1717)
at android.app.Activity.startActivityForResult(Activity.java:5252)
at androidx.fragment.app.FragmentActivity.startActivityForResult(FragmentActivity.java:675)
at androidx.core.app.ActivityCompat.startActivityForResult(ActivityCompat.java:234)
at androidx.fragment.app.FragmentActivity.startActivityFromFragment(FragmentActivity.java:790)
at androidx.fragment.app.FragmentActivity$HostCallbacks.onStartActivityFromFragment(FragmentActivity.java:932)
at androidx.fragment.app.Fragment.startActivity(Fragment.java:1257)
at androidx.fragment.app.Fragment.startActivity(Fragment.java:1245)
at com.karatasyazilim.su.ui.home.HomeFragment$5.onClick(HomeFragment.java:333)
at android.view.View.performClick(View.java:7869)
at android.widget.TextView.performClick(TextView.java:14958)
at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:992)
at android.view.View.performClickInternal(View.java:7838)
at android.view.View.access$3600(View.java:886)
at android.view.View$PerformClick.run(View.java:29362)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:8016)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:496)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1087)
My manifest is :
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.Su">
<activity android:name=".CreateAddress"></activity>
<activity android:name=".PhoneActivation" />
<activity
android:name=".Genel"
android:label="#string/title_activity_genel" />
<activity android:name=".SignUp" />
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data
android:name="com.facebook.sdk.ApplicationId"
android:value="#string/facebook_app_id" />
<activity
android:name="com.facebook.FacebookActivity"
android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation"
android:label="#string/app_name" />
<activity
android:name="com.facebook.CustomTabActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="#string/fb_login_protocol_scheme" />
</intent-filter>
</activity>
</application>
And here is my activiy code.
Intent kalimera = new Intent(getActivity(), FragmentActivity.class);
startActivity(kalimera);
What am I doing wrong?
You're trying to start the androidx FragmentActivity class directly. This is a parent class that you should subclass to create your own Activity.
Instead, make sure that you're using the name of the Activity you want to launch instead:
Intent intent = new Intent(getActivity(), NameOfTheActivityThatYouWantToLaunch.class);
startActivity(intent);
Alternately, if you aren't trying to launch an Activity and just got this code from somewhere, simply remove those lines.
If you're trying to launch a Fragment instead, take a look at How to start Fragment from an Activity

Android&Quickblox (api 3.2): Subscribing to push notifications

I'm not able to subscribe to push notifications. I did:
1) I created a firebase application, with the same package name as my MainActivity package name;
2) I downloaded the google-service.json file and stored it in my /app/ next to the gradle file;
3) I added the C2D and WAKE-LOCK permissions as the google guide showed;
4) I added the API-KEY in the pushnotification's setting tab in quickblox admin panel;
5) I modified the manifest as showed by the quickblox guide;
6) I added a push-notification listener and a local broadcast receiver as shown by the same guide as above.
That's how my manifest looks like:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="it.unical.sistemidistribuiti.ddf.appraia">
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<permission android:name="it.unical.sistemidistribuiti.ddf.appraia.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="it.unical.sistemidistribuiti.ddf.appraia.permission.C2D_MESSAGE"/>
<meta-data android:name="com.quickblox.messages.TYPE" android:value="FCM" />
<meta-data android:name="com.quickblox.messages.SENDER_ID" android:value="#string/sender_id" />
<meta-data android:name="com.quickblox.messages.QB_ENVIRONMENT" android:value="DEVELOPMENT" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:largeHeap="true"
android:theme="#style/AppTheme"
android:name="it.unical.sistemidistribuiti.ddf.appraia.AppraiaApplication">
<activity
android:name="it.unical.sistemidistribuiti.ddf.appraia.StartActivity"
android:label="#string/app_name"
android:theme="#style/AppTheme.NoActionBar"
android:screenOrientation="portrait"
android:configChanges="orientation|keyboardHidden">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="it.unical.sistemidistribuiti.ddf.appraia.MainActivity"
android:label="#string/app_name"
android:theme="#style/AppTheme.NoActionBar"
android:screenOrientation="portrait"
android:configChanges="orientation|keyboardHidden">
</activity>
<activity
android:name="it.unical.sistemidistribuiti.ddf.appraia.NewsDetailActivity"
android:label="#string/app_name"
android:theme="#style/AppTheme.NoActionBar"
android:screenOrientation="portrait"
android:configChanges="orientation|keyboardHidden">
</activity>
<activity
android:name="it.unical.sistemidistribuiti.ddf.appraia.CreatePostActivity"
android:label="#string/app_name"
android:theme="#style/AppTheme.NoActionBar"
android:screenOrientation="portrait"
android:configChanges="orientation|keyboardHidden">
</activity>
<activity
android:name="it.unical.sistemidistribuiti.ddf.appraia.UserProfileActivity"
android:label="#string/app_name"
android:theme="#style/AppTheme.NoActionBar"
android:screenOrientation="portrait"
android:configChanges="orientation|keyboardHidden">
</activity>
<receiver
android:name="com.google.android.gms.gcm.GcmReceiver"
android:exported="true"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.example.gcm" />
</intent-filter>
</receiver>
<service
android:name="com.quickblox.messages.services.fcm.QBFcmPushListenerService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
</application>
Since I'm using 3.2 sdk version, the app should automatically subscribe the user to push-notifications, but this not happen. Actually the listener code prints nothing:
//This is in AppraiaApplication extends Application
#Override
public void onCreate() {
super.onCreate();
QBSettings.getInstance().init(getApplicationContext(), APP_ID, AUTH_KEY, AUTH_SECRET);
QBSettings.getInstance().setAccountKey(ACCOUNT_KEY);
QBPushManager.getInstance().addListener(new QBPushManager.QBSubscribeListener() {
#Override
public void onSubscriptionCreated() {
System.out.println("onSubscriptionCreated");
}
#Override
public void onSubscriptionError(final Exception e, int resultCode) {
System.out.println("onSubscriptionError" + e);
if (resultCode >= 0) {
System.out.println("Google play service exception");
}
System.out.println("onSubscriptionError " + e.getMessage());
}
});
QBSettings.getInstance().setEnablePushNotification(true);
LocalBroadcastManager.getInstance(this).registerReceiver(pushBroadcastReceiver,
new IntentFilter("new-push-event"));
System.out.println("Application creation ended");
}
What am I doing wrong?
Looks like you don't make signIn with user, and subscription is not performed. Also have a look in logs, there is can be info something like D/QBASDK: SubscribeService: SubscribeService created. So, you can figure out whether the subscription is executed at all.

Cause of Error Message "Error:(27) Tag <manifest> attribute package has invalid type 4."

When trying to build my app, I get the following error message: "Error:(27) Tag <manifest> attribute package has invalid type 4." Any ideas on what is causing this? Here is a copy of my manifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.dummy.tanc">
<application
android:supportsRtl="true"
android:allowBackup="true"
android:fullBackupContent="false"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<meta-data android:name="com.google.android.gms.games.APP_ID"
android:value="#string/app_id" />
<meta-data android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version"/>
<activity
android:name="com.google.example.games.tanc.MainActivity"
android:label="#string/title_activity_main"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
I think it is because, in your manifest, you've set your package name (line 2) to be
package="com.dummy.tanc"
and in when defining the activity (line 18), you've used
android:name="com.google.example.games.tanc.MainActivity"
Because of this mismatch, the issue could be arising. Change the line 18 to
android:name="com.dummy.tanc.MainActivity"
It means attribute package has type float but not string.
I guess your package name contains only numbers, something like package="1.0".

Android / Google Plus - Cannot share image from my content provider

I have used this code and can successfully share an image (from my phone's gallery) with text to google+ from my Android app.
However, when I try to post an image from my app's content provider, the image is showing up on my google+ page like this...
...and that is despite the intended image being displayed fine on the google+ app preview screen.
The code I am using to share is:
String message = "My message";
Uri localImageUri = ContentUris.withAppendedId(DbContentProvider.CONTENT_URI_PRODUCTS, mProductId;
PlusShare.Builder builder = new PlusShare.Builder(getActivity());
builder.setText(message);
builder.addStream(localImageUri);
builder.setType("image/jpeg");
Intent shareIntent = builder.getIntent();
startActivityForResult(shareIntent, RC_GOOGLE_PLUS);
...and, like I say, the image is successfully displayed on the final google+ page if the localImageUri value is for a resource in my phone's Gallery - whereas the above placeholder image is shown if I set localImageUri to a uri from my app's own content provider.
So I presume there must be an issue with my content provider, which is defined in my manifest as:
<provider
android:name=".DbContentProvider"
android:authorities="com.example.provider"
android:exported="true"
android:grantUriPermissions="true" />
So, could there be something missing from my manifefst - or even from my searchable.xml file:
<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="#string/app_name"
android:hint="#string/search_hint"
android:searchSuggestAuthority="com.example.provider"
android:searchSuggestIntentAction="android.intent.action.VIEW"
android:searchSuggestIntentData="content://com.example.provider/suggest"
android:searchSuggestThreshold="3"
android:includeInGlobalSearch="true"
android:searchSettingsDescription="#string/search_settings_description"
android:queryAfterZeroResults="true"
android:voiceSearchMode="showVoiceSearchButton" >
</searchable>
If not, then what could the problem be?
Update (Following CommonsWare's comment)
Exceptions were indeed thrown by the Google+ library because as well doing a query on the _data column (which existed), the Google+ API was also looking for columns that didn't exist - namely, datetaken, date_added, date_modified.
So I have added these columns to my database table - adding them all as text columns with recent millis values such as '1419379390000' (ref here) but I still get the same placeholder image being displayed on my Google+ page.
So I added some logging code to the query() method of my DbContentProvider class and when google+ does its single-column query for datetaken, the value returned in the cursor is indeed 1419379390000. However, the value returned for the (separate) _data query is null.
I'm not sure why the google API queries the _data column (because I do not need to call it in my code when I retrieve the image from the database in order to show in on the UI - instead, I call...
Uri localImageUri = ContentUris.withAppendedId(DbContentProvider.CONTENT_URI_PRODUCTS, mProductId);
InputStream in = cr.openInputStream(localImageUri);
Bitmap img = BitmapFactory.decodeStream(in);
imageView.setImageBitmap(img);
...but presumably the null in my cursor for the _data value is the problem. Not sure where to start to address this, though??
30-Dec-2014 Update
Here is the LogCat output. So, when I click my g+ button...
12-30 21:45:34.344: D/DbContentProvider(24633): getType(content://com.example.provider/products/1668)
12-30 21:45:34.534: D/DbContentProvider(24633): getType(content://com.example.provider/products/1668)
12-30 21:45:34.544: D/DbContentProvider(24633): openFile(content://com.example.provider/products/1668, r)
12-30 21:45:34.584: D/DbContentProvider(24633): openFile(content://com.example.provider/products/1668, r)
12-30 21:45:34.604: D/DbContentProvider(24633): openFile(content://com.example.provider/products/1668, r)
12-30 21:45:34.604: D/DbContentProvider(24633): openFile(content://com.example.provider/products/1668, r)
12-30 21:45:34.624: D/DbContentProvider(24633): openFile(content://com.example.provider/products/1668, r)
...that brings up the g+ screen for customising the share message (which, I confirm, does include the image from my content provider). So I then click the Share button on the g+ screen and the LogCat output is...
12-30 21:45:57.526: D/DbContentProvider(24633): openFile(content://com.example.provider/products/1668, r)
12-30 21:45:57.576: D/DbContentProvider(24633): getType(content://com.example.provider/products/1668)
12-30 21:45:57.576: D/DbContentProvider(24633): DbContentProvider - query(content://com.example.provider/products/1668)
12-30 21:45:57.576: D/DbContentProvider(24633): - projection: {"datetaken"}
12-30 21:45:57.576: D/DbContentProvider(24633): - selection: null
12-30 21:45:57.576: D/DbContentProvider(24633): - selectionArgs: null
12-30 21:45:57.576: D/DbContentProvider(24633): - sortOrder: null
12-30 21:45:57.576: D/DbContentProvider(24633): SQL (without selectionArgs): SELECT datetaken FROM products WHERE (_id = 1668) LIMIT 1
12-30 21:45:57.596: D/DbContentProvider(24633): returned value: 1419379390000
12-30 21:45:57.596: D/DbContentProvider(24633): cursor count: 1
12-30 21:46:03.642: D/DbContentProvider(24633): getType("content://com.example.provider/products/1668") - returns "vnd.android.cursor.item/vnd.example.elemental"
23-Jan-2015 Update
Here is my manifest in full:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example"
android:versionCode="10"
android:versionName="0.10" >
<uses-sdk
android:minSdkVersion="11"
android:targetSdkVersion="20" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission
android:name="com.example.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.example.permission.C2D_MESSAGE" />
<uses-permission android:name="com.android.vending.BILLING" />
<application
android:name=".MyApplication"
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<receiver
android:name=".GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.example" />
</intent-filter>
</receiver>
<service android:name=".GcmIntentService" />
<provider
android:name=".DbContentProvider"
android:authorities="com.example.provider"
android:exported="false"
android:grantUriPermissions="false" >
<grant-uri-permission android:pathPrefix="/products" />
</provider>
<activity
android:name="com.google.android.gms.ads.AdActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"
android:theme="#android:style/Theme.Translucent" >
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
</activity>
<activity
android:name=".SplashActivity"
android:label="#string/app_name"
android:launchMode="singleTop" >
<intent-filter android:label="#string/app_name_short">
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".LoginActivity"
android:label="#string/title_activity_login"
android:windowSoftInputMode="stateHidden" >
</activity>
<activity
android:name=".HomeActivity"
android:label="#string/app_name_short"
android:windowSoftInputMode="adjustPan" >
<meta-data
android:name="android.app.default_searchable"
android:value=".SearchResultsActivity" />
</activity>
<activity
android:name=".SearchResultsActivity"
android:label="#string/app_name_short"
android:launchMode="singleTop"
android:parentActivityName=".HomeActivity"
android:windowSoftInputMode="stateHidden" >
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".HomeActivity" />
<meta-data
android:name="android.app.searchable"
android:resource="#xml/searchable" />
<meta-data
android:name="android.app.default_searchable"
android:value=".SearchResultsActivity" />
</activity>
<activity
android:name=".SingleShoppingListActivity"
android:label="#string/shopping_list"
android:parentActivityName=".HomeActivity" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".HomeActivity" />
</activity>
<activity
android:name=".SingleProductActivity"
android:label="#string/shopping_list_item"
android:parentActivityName=".HomeActivity" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".HomeActivity" />
</activity>
<activity
android:name=".InfoMenuActivity"
android:label="#string/why_gmo_free"
android:parentActivityName=".HomeActivity" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".HomeActivity" />
</activity>
<activity
android:name=".InfoContentActivity"
android:label="#string/why_gmo_free"
android:parentActivityName=".InfoMenuActivity" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".InfoMenuActivity" />
</activity>
<activity
android:name=".SettingsActivity"
android:label="#string/settings"
android:parentActivityName=".HomeActivity" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".HomeActivity" />
</activity>
<activity
android:name=".TwitterCallbackActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="twitter"
android:scheme="oauth" />
</intent-filter>
</activity>
<activity
android:name=".DummyActivity"
android:label="#string/title_activity_dummy" >
</activity>
<activity
android:name=".SmartSearchResultsActivity"
android:label="#string/app_name_short"
android:parentActivityName=".SearchResultsActivity"
android:windowSoftInputMode="stateHidden" >
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".SearchResultsActivity" />
<meta-data
android:name="android.app.searchable"
android:resource="#xml/searchable" />
<meta-data
android:name="android.app.default_searchable"
android:value=".SearchResultsActivity" />
</activity>
<activity
android:name=".WebViewActivity"
android:label="#string/app_name_short"
android:parentActivityName=".HomeActivity" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".HomeActivity" />
</activity>
<activity
android:name=".UpgradeActivity"
android:label="#string/upgrade_to_pro_qm" >
</activity>
</application>
</manifest>
This is an interesting problem. If your ContentProvider is exported (which is not entirely clear in the question -- it seems to be in the first snippet you posted, but not in the full AndroidManifest.xml added later) what you're doing should work. Not sure why it doesn't.
In any case, you can certainly share any image file to the Google+ app by means of a FileProvider:
FileProvider is a special subclass of ContentProvider that facilitates
secure sharing of files associated with an app by creating a
content:// Uri for a file instead of a file:/// Uri.
Therefore, if your image is actually a file under getFilesDir() (very likely) or can be at least moved there, then you can apply this solution.
First you must define the provider in your AndroidManifest.xml file:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.example.testshare.fileprovider"
android:grantUriPermissions="true"
android:exported="false">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/filepaths" />
</provider>
Then this file in res\xml\filepaths.xml:
<?xml version="1.0" encoding="utf-8"?>
<paths>
<files-path name="shared_images" path="shared_images/" />
</paths>
Then, to share an image file, first make sure it's in the path specified above (i.e. shared_images under getFilesDir() -- you don't need the WRITE_EXTERNAL_STORAGE permission to copy if there because this location is inside your own app's private storage area). Then build the share intent as follows:
File file = getImageFileToShare();
Uri fileUri = FileProvider.getUriForFile(this, "com.example.testshare.fileprovider", file);
Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_STREAM, fileUri);
intent.setType("image/png");
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);
(Make sure the authority specified in the getUriForFile() method matches the one in the manifest).
This will produce a content:// Uri (like content://com.example.testshare.fileprovider/shared_images/img1.png that the Google+ app will be able to access, and thus include in the post).

Categories

Resources