AppIndexing test failed(FireBase) - android

I'm going implementation of appIndexing and I'm failed one of the firabase appindexing test in android studio. There is a result of my test.
In project I have 2 flavors each of them contains a google-service.json file.
Google-service.json files come from different gmail accounts because there are 2 different owners.
When I don't use flavors test is run fine. But when I start to use flavors test is fail.
The structure is simular like in this blog(section is Dev, QA, Stage, Prod environment isolation) : https://firebase.googleblog.com/2016/08/organizing-your-firebase-enabled-android-app-builds.html
My manifest file contain intent-filter:
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<!-- Accepts URIs that begin with "https://www.example.com/articles/" -->
<data android:scheme="https"
android:host="www.example.com"
android:pathPrefix="/articles/" />
</intent-filter>
My activity has this code:
private static final String TITLE = "Sample Article";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_one);
}
#Override
public void onStart() {
super.onStart();
final Uri BASE_URL = Uri.parse("https://www.example.com/articles/");
Indexable articleToIndex = new Indexable.Builder()
.setName(TITLE)
.setUrl(BASE_URL.toString())
.build();
FirebaseAppIndex.getInstance().update(articleToIndex);
}
#Override
public void onStop() {
super.onStop();
}
When I start to test "Verify URLs open to app activities" in this url https://firebase.google.com/docs/app-indexing/android/test it work fine and I'm able to launch app with specific page.
My questions:
Does this test important to pass?
Does this test mean that app- indexing will work correct or I can ignore this test and publish app to store and app indexing will work fine?
If this test is important how to pass this test success with my project architecture?
Additional info:
1.web-site indexing is done and url's comes from site-map.xml.
2.App is min level 17 for now.
Any ideas?

Related

Cannot understand how to open a simple TWA inside an app (using AndroidX)

I am trying to open a TWA inside my app and have researched for 2 days.
I've already managed to create a single TWA app, no fuss, just edit the manifest and a few things more.
Now I need to have my own app - let's say the app has a splash screen activity at first which then opens the TWA inside the app.
Can I launch a TWA inside my app through a simple splash screen activity, for example?
I did try to use CustomTabs way, but it says it is deprecated and to use TrustedWebActivityIntentBuilder instead, but there is 0, I repeat, ZERO documentation on how to use that!
Android development documentation is horrible. Among other things, the documentation pointers are out-dated. (Read videos on their channel linking to guides that are no longer valid for what is discussed in the video itself)
The closest thing I found was this sample project. This uses a shocking number of deprecated things rendering the adaptation of that method into my app completely useless. It also makes use of a countless number of custom Classes/Helpers created just for that project, leading me to a never ending marathon of copy-pasting each one of them just to find out that inside that one there are more that need to be copied over to the project.
To my opinion there is a simpler approach.
First: declare your TWA activity in AndroidManifest.xml like shown below. Note that it won't start by default because it doesn't handle the android.intent.action.MAIN intent, so you can implement your own main activity.
<activity
android:name="com.google.androidbrowserhelper.trusted.LauncherActivity">
<!-- Edit android:value to change the url opened by the TWA -->
<meta-data
android:name="android.support.customtabs.trusted.DEFAULT_URL"
android:value="https://YOUR_SITE_URL" />
<!--
This intent-filter allows the TWA to handle Intents to open
YOUR_SITE_URL
-->
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE"/>
<!-- Edit android:host to handle links to the target URL-->
<data
android:scheme="https"
android:host="YOUR_SITE_URL"/>
</intent-filter>
</activity>
Second: somewhere in your code start the TWA activity with the intent like this. You can also pass site url in the intent if you wish.
Intent intent = new Intent(this, com.google.androidbrowserhelper.trusted.LauncherActivity.class);
intent.setData(Uri.parse("ANOTHER_SITE_URL"));
startActivity(intent);
Also note the dependencies required to use TWA with AndroidX:
implementation 'androidx.browser:browser:1.0.0'
implementation 'com.github.GoogleChrome:android-browser-helper:ff8dfc4ed3d4133aacc837673c88d090d3628ec8'
When launching the Trusted Web Activity from an existing Activity, the recommended approach is using TwaLauncher, from android-browser-helper. There's a demo for this use-case, but the implementation would be:
Import android-browser-helper in the build.gradle:
dependencies {
...
implementation 'com.google.androidbrowserhelper:androidbrowserhelper:2.0.0'
}
Launch the Trusted Web Activity from an Activity:
public void launchTwa(Uri uri) {
TrustedWebActivityIntentBuilder builder = new TrustedWebActivityIntentBuilder(uri)
.setNavigationBarColor(Color.RED) // Use the builder to customise.
.setToolbarColor(Color.BLUE);
TwaLauncher launcher = new TwaLauncher(this);
launcher.launch(builder, null, null);
}
Comparing to other approaches:
Using LauncherActivity: Using LauncherActivity adds an extra level of indirection, which will introduce delays when launching the Trusted Web Activity from an existing Activity (eg: Activity X starts the LauncherActivity, which in turn starts the Trusted Web Activity).
Using androidx.browser directly: There's nothing wrong with this approach, but TwaLauncher encapsulates almost everything needed to handle that already.
After a lot of trial and error as always I've managed to launch a TWA inside the app. Note that this is not like a WebView, it merely starts an activity on your app's stack.
The following is in my Activity's code:
final static String PACKAGE_NAME = "com.android.chrome";
final static String BASE_URL = "https://your.website.com";
CustomTabsClient mClient;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_launcher);
CustomTabsClient.bindCustomTabsService(this, PACKAGE_NAME, getConnection(BASE_URL));
}
private CustomTabsServiceConnection getConnection(final String url) {
return new CustomTabsServiceConnection() {
#Override
public void onServiceDisconnected(ComponentName componentName) {
mClient = null;
}
#Override
public void onCustomTabsServiceConnected(
ComponentName name,
CustomTabsClient client
) {
final Intent intent;
final CustomTabsSession customTabsSession;
final TrustedWebActivityIntentBuilder intentBuilder;
mClient = client;
mClient.warmup(0);
if ((customTabsSession = mClient.newSession(new CustomTabsCallback())) == null) {
return;
}
intentBuilder = new TrustedWebActivityIntentBuilder(Uri.parse(url))
.setToolbarColor(Color.parseColor("#ffffff"))
.setNavigationBarColor(Color.parseColor("#ffffff"));
intent = intentBuilder.build(customTabsSession);
startActivity(intent);
}
};
}

OAuth2 CallBack Google Custom Tabs

I am developing an Android Application that uses the FitBit API to retrieve a User's data. These are then used further in the application. In order to make this work, OAuth2 is used for authorization. First step is to get the user's consent to use data in a particular scope.
In order to make this work, I use Google Custom Tabs as prescribed by FitBit. The url works in a web browser, when I test it on an Android device it works too, directs me to the User Consent Page. When I hit the "Agree" button, I do not get redirected to the Application. Instead, I end up on the callback_url page with the Authorization Code.. Still I get nothing back through "System.in.println()". HOW DO I END UP BACK IN MY APPLICATION WITH THE AUTHORIZATION CODE IN SYSTEM.IN?
The following is the page I end up on..
I use a redirect_url for Development purposes, "http://locallhost.com/", to allow me to test in development. This is set up in the Manifest as an Intent Filter (see below), the Application settings of my Application at Fitbit API EndPoint.
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final CustomTabsIntent intent = new CustomTabsIntent.Builder().build();
final String url = "https://www.fitbit.com/oauth2/authorize/myApplicationParameters";
intent.launchUrl(this, Uri.parse(url));
System.out.println(in.hasNextLine());
The Manifest
<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="locallhost.com/"
android:scheme="http"/>
</intent-filter>
I ended up using callback_uri "niels://fitbitcallback". It was confusing to the Android Studio to use http:// or https://. This did not work for me. On top of that I used an additional activity to redirect the user to. Also adapted the Android Manifest accordingly.

App not being recognized by Android Auto

So, I followed the official guide here https://developer.android.com/training/auto/start/index.html to create a very basic Android Auto Audio App. For the moment it does nothing, other then declaring what needs to be declared in the manifest and implementing empty onGetRoot() and onLoadChildren().
Problem is, that it is not being recognized by the Android Auto app.
Any idea where to get a working example? What could be wrong?
Manifest:
<service
android:name=".MyService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name=
"android.media.browse.MediaBrowserService"/>
</intent-filter>
</service>
automotive_app_desc.xml:
<automotiveApp>
<uses name="media" />
</automotiveApp>
service:
public class MyService extends MediaBrowserServiceCompat {
public static final String MEDIA_ID_ROOT = "__ROOT__";
#Override
public BrowserRoot onGetRoot(String clientPackageName, int clientUid,
Bundle rootHints) {
//TODO: check if the client is allow access
return new BrowserRoot(MEDIA_ID_ROOT, null);
}
#Override
public void onLoadChildren(final String parentMediaId,
final Result<List<MediaBrowserCompat.MediaItem>> result) {
// Assume for example that the music catalog is already loaded/cached.
List<MediaBrowserCompat.MediaItem> mediaItems = new ArrayList<>();
// Check if this is the root menu:
if (MEDIA_ID_ROOT.equals(parentMediaId)) {
// build the MediaItem objects for the top level,
// and put them in the mediaItems list
} else {
// examine the passed parentMediaId to see which submenu we're at,
// and put the children of that menu in the mediaItems list
}
result.sendResult(mediaItems);
}
You have to go to Android Auto settings, tap many times on the Version entry (the last one) to unlock Developer settings. Then tap on Developer settings menu item and enable Unknown sources. Restart Android Auto and if your app it's ok it will be listed. Worked for me
I didn't see this included in your snippet from the manifest, but double check that this line is also there.
<application>
...
<meta-data android:name="com.google.android.gms.car.application"
android:resource="#xml/automotive_app_desc"/>
...
</application>
I created a sample app matching everything you have (plus the line above), and it appears in Android Auto on the mobile device, as well as the Desktop Head Unit.

Branch.io and Instant Apps

I have an app that's using Branch.io and am in process of updating it to support Instant Apps. Part of this change will require using app links to navigate from one part of app to another.
The Activity that I'm opening is configured to use Branch.io (e.g. using instructions in https://dev.branch.io/marketing-channels/android-instant-apps/guide/) and includes following in it's onStart() method. However I'm not seeing parameters I'm including in deep link in referringParams.
Branch.getInstance().initSession(new Branch.BranchReferralInitListener() {
#Override
public void onInitFinished(JSONObject referringParams, BranchError error) {
Log.d("Branch", "onInitFinished() with deep link data: " + referringParams);
}
});
Do I need to trigger opening of the branch link in particular way from Android code for this to work?
BTW referringParams above does show +clicked_branch_link being false.
UPDATE
Just to clarify a few things. I'm trying for example to launch ActivityB from ActivityA using app deep link. ActivityB includes <intent-filter> as described in https://dev.branch.io/marketing-channels/android-instant-apps/guide/ for example. In ActivityA I'm currently trying to open/create Branch.io link as follows (have also formed link directly, as is used in that android-instant-apps sample for example, but that's not considered a "branch link")
HashMap<String, String> metadata = new HashMap<>();
metadata.put(PARAM, param);
BranchUniversalObject branchUniversalObject = new BranchUniversalObject().addContentMetadata(metadata);
LinkProperties linkProperties = new LinkProperties();
branchUniversalObject.generateShortUrl(context, linkProperties, (url, error) -> {
if (error == null) {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
context.startActivity(intent);
}
});
If I try to open the url generated (by generateShortUrl) directly on device (clicking on link for example) then ActivityB is launched and I see the param I included in initSession callback. If I try to open it using code above (navigating betweeen ActivityA and ActivityB then ActivityB is launched but don't get the params (and +clicked_branch_link is false)
Sojan from Branch here
If you are trying to deep link to a new feature from another instant app apk unfortunetely Branch is not supporting this feature now.
If you are trying to get deep link params on opening an activity B in a new feature from activity A from another feature in an installed app you can achieve it in the following way.
ActivityA.java
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("yourBranchLink"));
intent.putExtra("branch","yourBranchLink");
intent.putExtra("branch_force_new_session",true);
Hope this helps
In order to configure the Branch SDK with your Instant App supported Android App you can follow the steps below:
1. Initialize the Branch SDK
Initialize the Branch SDK in the onCreate() method of your Application class. If you plan on deep linking from your Android Instant App to your full Android app after its installed, you'll need to add the line enablePlayStoreReferrer. This adds a delay to the initialization to wait for the Google Play Referrer, which can take up to a second.
public void onCreate() {
super.onCreate();
// This is needed to deferred deep link from an Android Instant App to a full app
// It tells the Branch initialization to wait for the Google Play Referrer before proceeding.
Branch.enablePlayStoreReferrer(1000L);
// Initialize the Branch SDK
Branch.getAutoInstance(this);
}
2. Add your Branch keys and register for Install Referrer
Instant Apps can be rather confusing as there are many different manifests, but you want to find the Manifest that contains your application tags. Make sure your Application class name is defined here, and then specify the Branch keys inside the application element.
<application
android:allowBackup="true"
android:label="#string/app_name"
android:theme="#style/AppTheme"
android:supportsRtl="true"
android:name=".MyApplication">
<!-- Set to true to use Branch_Test_Key -->
<meta-data android:name="io.branch.sdk.TestMode" android:value="false" />
<meta-data android:name="io.branch.sdk.BranchKey" android:value="key_live_app_live_key" />
<meta-data android:name="io.branch.sdk.BranchKey.test" android:value="key_test_app_test_key" />
<receiver android:name="io.branch.referral.InstallListener" android:exported="true">
<intent-filter>
<action android:name="com.android.vending.INSTALL_REFERRER" />
</intent-filter>
</receiver>
</application>
3. Configure your Branch links as Android App Links
Assuming you've already configured Branch for Android App Links for your Android App the next step is to add the intent filter for App links support in your Application Tag. Make sure to replace the xxxx with your link Domain. (If you haven't configured your full native app to use Branch as Android App Links you can follow the steps mentioned here and here.)
<application
......
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" android:host="xxxx.app.link" />
<data android:scheme="https" android:host="xxxx-alternate.app.link" />
</intent-filter>
</application>
4. Retrieve Branch deep link data
Add Branch initSession in Activities which are configured to open from a link click in order to receive the deep link params. This will return the deep link data from the referring link.
protected void onStart() {
super.onStart();
Branch.getInstance().initSession(new Branch.BranchReferralInitListener() {
#Override
public void onInitFinished(JSONObject referringParams, BranchError error) {
Log.d("Branch","onInitFinished() with deep link data: " + referringParams);
}
});
}
5. Configure the deep linking from Instant App to your Full App
To convert your user who just arrived in your Instant App to your full native app, Branch SDK provides convenient methods to check for app types and full app conversion. This eliminates the dependency on Google IA support SDK ('com.google.android.instantapp'). Here are some of the methods:
Branch.isInstantApp()
This convenience method checks whether the current version of app running is Instant App or Full Android App
Branch.showInstallPrompt()
This methods shows an install prompt for the full Android app, allowing you an easy way to pass Branch referring deep data to the full app through the install process.

How to override the behavior of opening Appboy web activity in deeplink In App messge

I am facing a problem in override the On Click Behavior in Appboy deeplink
Please find the following data
1- Register Appboy in BaseActivity which is the parent activity for all Application Activities
#Override
protected void onResume() {
AppboyInAppMessageManager.getInstance().registerInAppMessageManager(this);
Appboy.getInstance(this).requestInAppMessageRefresh();
}
#Override
protected void onPause() {
AppboyInAppMessageManager.getInstance().unregisterInAppMessageManager(this);
}
2- Add the receivers in Manifest File as following
<receiver android:name="com.forsale.forsale.appboy.AppboyGcmReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.forsale.forsale" />
</intent-filter>
</receiver>
<receiver
android:name="com.forsale.forsale.appboy.AppBoyOpenReceiver"
android:exported="false" >
<intent-filter>
<action android:name="com.forsale.forsale.intent.APPBOY_PUSH_RECEIVED" />
<action android:name="com.forsale.forsale.intent.APPBOY_NOTIFICATION_OPENED" />
</intent-filter>
</receiver>
Know I can send in app message using app boy dashboard, and receive the message, but when I click the message it open appboy web activity with the link
I need to override this behaviour to be able to get the link that I sent in In app message and parse some parameters from it and direct the use to an activity inside my app
I have tried the following
remove default app boy web activity from manifest file /// the app crash
implement the IInAppMessageManagerListener /// the app stop receiving any messages
Please note that the application call the onReceive method when trying to register appboy and print the log (action = REGISTRATION, RegId = "..."), but it never lo any other actions like RECEIVE, or OPEN
public void onReceive(Context context, Intent intent) {
AppboyLogger.i("AMIRA", String.format("Amira %s", intent.toString()));
String action = intent.getAction();
AppboyLogger.i("AMIRA", String.format("Amira %s", action));
Bundle bundle = intent.getExtras();
for (String key : bundle.keySet()) {
Object value = bundle.get(key);
AppboyLogger.i("AMIRA", String.format("Amira %s", key + ":" + value.toString()));
}
}
The root of the problem is that we differentiate deep links and http links based on schema of the URI, so http (and some other schemes) links are detected as web links, and other formats are seen as deep links (see https://github.com/Appboy/appboy-android-sdk/blob/master/android-sdk-ui/src/com/appboy/ui/actions/ActionFactory.java).
We’ll consider how to instrument things for the use case you have, but in the meantime there’s a couple of ways you could solve the issue:
1) Create a deep link that is not also an http link. Everything should work if your link instead looks like, for example, forsale://mylink?a=b&2=3....etc.
2) Set a custom in-app message manager listener: https://documentation.appboy.com/Android/#in-app-message-customization. You can see an example of how we do this in our Droidboy sample app. In your case, you’d want to return defaults for everything but onInAppMessageButtonClicked and onInAppMessageClicked where you’d want to handle the link yourself if it’s of the format of your deep link. Your ticket indicates you’ve tried this, but I’d suggest starting with "the default one we create in the AppboyInAppMessageManager.java (#L608) in the Android SDK - and then just modifying the *clicked methods.
3) Download our UI code and modify the source. You could optionally download the Appboy Android SDK and modify the ActionFactory to handle your deep link in the way you want. Though, at the point you are going to do something like this, solution #2 is likely going to be a nicer one to implement and maintain.
Please let us know if one of these solutions works for you and if you have any other comments/questions.
Thanks,
Waciuma

Categories

Resources