i'm actually trying to use Dialogflow v2 with java sdk in android.
I can already make queries to dialogflow but I wanted to send some payload with my query.
Because of this, I discovered the QueryParameters object and I already set it with my desired payload.
The problem is, I have both QueryInput and QueryParameters defined but there is no documentation (or code references in the source code) about how to apply the parameters to the input before trying to detect the intent.
SessionsClient.create().use { sessionsClient ->
// Set the session name using the sessionId (UUID) and projectID
val session = SessionName.of(PROJECT_ID, UUID)
System.out.println("Session Path: $session")
// Set the text (input) and language code (en) for the query
val textInput = TextInput.newBuilder().setText(text).setLanguageCode(LANGUAGE_CODE)
// Build the query with the TextInput
val queryInput = QueryInput.newBuilder().setText(textInput).build()
// Set payload
val payload = "{someid: $someid}"
val queryParameters = QueryParameters.newBuilder().setPayload(Struct.parseFrom(payload.toByteArray())).build()
// (HERE I NEED TO ADD THE PARAMETERS TO INPUT)
// Performs the detect intent request
val response = sessionsClient.detectIntent(session, queryInput)
// returns the query result
return response.queryResult
}
After hours of deep searching, I managed to find the DetectIntentRequest class.
//Build the request
val request = DetectIntentRequest.newBuilder()
.setSession(session.toString())
.setQueryInput(queryInput)
.setQueryParams(queryParameters)
.build()
// Performs the detect intent request
val response = sessionsClient.detectIntent(request)
Note: if you are using other languages probably you 'll have a third
parameter in detectIntent function to place your queryParameters
For Kotlin ,
val queryInput1211 = QueryInput.newBuilder()
.setText(TextInput.newBuilder().setText(msg).setLanguageCode("en-US"))
.setEvent(com.google.cloud.dialogflow.v2beta1.EventInput.newBuilder()
.setName("Welcome")
.setLanguageCode("en-US")
.setParameters(
Struct.newBuilder().putFields("user_id",
Value.newBuilder().setStringValue("1234").build())
.build())
.build())
.build()
For java
QueryInput queryInput1211 = QueryInput.newBuilder()
.setText(TextInput.newBuilder().setText(msg).setLanguageCode("en-US"))
.setEvent(com.google.cloud.dialogflow.v2beta1.EventInput.newBuilder()
.setName("Welcome")
.setLanguageCode("en-US")
.setParameters(
Struct.newBuilder().putFields("user_id",
Value.newBuilder().setStringValue("1234").build())
.build())
.build())
.build();
Where Welcome is intent event name and user_id as parameter name
Related
We are trying with new ApiV2 with base plan id new feature in Play Store but unable to update it to the latest use case as we are unable to fetch the base plan id with getProductDetails().
val queryProductDetailsParams =
QueryProductDetailsParams.newBuilder()
.setProductList(
ImmutableList.of(
Product.newBuilder()
.setProductId("product_id_example")
.setProductType(ProductType.SUBS)
.build()))
.build()
billingClient.queryProductDetailsAsync(
queryProductDetailsParams,
ProductDetailsResponseListener { billingResult, productDetailsList ->
// check billingResult
// process returned productDetailsList
}
)
here we are looking to have values with product details like offers and base plan id for the following subscriptions.
val activity : Activity = ...;
// Retrieve a value for "productDetails" by calling queryProductDetails()
// extension function.
val flowParams = BillingFlowParams.newBuilder()
.setProductDetails(productDetails)
.setOfferToken(selectedOfferIdToken)
.build()
val responseCode = billingClient.launchBillingFlow(activity, flowParams).responseCode
The launchBillingFlow() method returns one of several response codes listed in BillingClient.BillingResponseCode. Be sure to check this result to ensure there were no errors launching the purchase flow. A BillingResponseCode of OK indicates a successful launch.
Proposal
Update the SDK versions which help us to have relevant output like this.
I have a retrofit request
#GET("{link}")
suspend fun getFilePart(#Path(value = "link") link: String): Deferred<NetworkResponse<ResponseBody, NetworkError>>
and when i call it i pass a 'link'
val base = if (BuildConfig.DEBUG) BuildConfig.TRANSFER_URL_DEBUG else BuildConfig.TRANSFER_URL
apiManager.appApiService(base).getFilePart(it.link)
Lets say the link is something like "https://storage_dev.example.com/10002/6d197e1e57e37070760c4ae28bf1..." but in the Logcat i see that some characters get urlEncoded.
For example
the following Url
https://storage_dev.example.com/10002/6d197e1e57e37070760c4ae28bf18d813abd35a372b6a1f462e4cef21e505860.1&Somethingelse
turns to
https://storage_dev.example.com/10002/6d197e1e57e37070760c4ae28bf18d813abd35a372b6a1f462e4cef21e505860.1%3FSomethingelse
As i can see the link is a String that has many characters inside that get encoded like "&" has turned to "%3F"
How can i prevent this?
You can add encoded = true to your request param to tell retrofit to not encode it again:
/**
* Specifies whether the parameter {#linkplain #value() name} and value are already URL encoded.
*/
boolean encoded() default false;
Example:
#Path(value = "link", encoded = true)
If your link includes the baseurl part you should use #Url to avoid that problem
#GET
suspend fun getFilePart(#Url link: String): Deferred<NetworkResponse<ResponseBody, NetworkError>>
I think I'm late but however this is how I solved it ..
my issue was the url to containes " so on request url it gets encoded then looks like this domain.com/api/%22SOME_URL_%22
simply just add interceptor to catch the request and decode it.
if(it.request().url().toString().contains("api/MY_SUB_DOMAIN")){
val newUrl = java.net.URLDecoder.decode( it.request().url().toString(),
StandardCharsets.UTF_8.name()) // <--- This is your main solution (decode)
.replace("\"", "") // <---- I had to do this to remove parenthasis "
requestBuilder.url(newUrl) // <--- DONT FORGET TO ASSAIGN THE NEW URL
}
I have a strange behaviour when I click on a link in a webview that is a PDF file link.
For example: https://my.server.com/foobar.pdf
So I have made some research and this link will start a dowload in my webview.
I have a DownloadListener and a onDownloadStart method.
In it I send the URL to Android so that PDF apps on phone can open it.
My strange behaviour is here. If the link in the webview does not have parameters I am not able to add parameters in the URL but if the URL have one parameter -> my parameters are added.
Example will be more meaningful.
Here url in link is "https://my.server.com/foobar.pdf"
val uriTest = Uri.parse(url).buildUpon()
.appendQueryParameter("key1", val1)
.appendQueryParameter("key2", val2)
.build()
val intent = Intent(Intent.ACTION_VIEW, uriTest)
startActivity(intent)
So when the PDF app called by startActivity(intent) call the URL on my server I have no parameters in URL and on my server I see a call to "https://my.server.com/foobar.pdf" not to "https://my.server.com/foobar.pdf?key1=val1&key2=val2".
BUT
If the url in link is "https://my.server.com/foobar.pdf?t=t" when my Android code is executed on my server side I can see a call to ""https://my.server.com/foobar.pdf?t=t&key1=val1&key2=val2". My parameters are added in this case.
Is it normal? Am I missing something?
Thanks for your help!
---EDIT---
I also tried to add my parameters in the string directly and it is the same -> my parameters are ignored until the URL I get has one parameter.
Example: I get "https://my.server.com/foobar.pdf" and I do:
val url1 = url + "?key1=" + val1
or
val url1 = "$url?key1=$val1"
val yourUrl = StringBuilder("https://my.server.com/foobar.pdf")
val parameters = hashMapOf<String, String>()
parameters["key1"] = "val1"
parameters["key2"] = "val2"
var count = 0
for (i in parameters.entries) {
if (count == 0)
yourUrl.append("?${i.key}=${i.value}&")
else
yourUrl.append("${i.key}=${i.value}&")
count++
}
val yourNewUrl = yourUrl.substring(0, yourUrl.length - 1)
Timber.e("URL: $yourNewUrl")
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(yourNewUrl))
startActivity(intent)
Happy coding :)
I have implemented an Android Autofill Service for my password manager app. Users have reported issues with the Paypal app, where the service does not seem to work.
I have investigated this and found that the following code (Xamarin) in onFillRequest does work: ("does work" means the fields are filled after clicking the autofill popup)
var responseBuilder = new FillResponse.Builder();
var autofillIds = FindAutoFillIds(); //gets the autofill ids for each EditText
RemoteViews presentation = AutofillHelper.NewRemoteViews(PackageName, "fill data from onFillRequest", AppNames.LauncherIcon);
var datasetBuilder = new Dataset.Builder(presentation);
foreach (AutofillId autofillId in autofillIds)
{
datasetBuilder.SetValue(autofillId, AutofillValue.ForText("some data"));
}
responseBuilder.AddDataset(datasetBuilder.Build());
callback.OnSuccess(responseBuilder.Build());
It basically creates a fill response with a single dataset which has values set for each autofill field.
Now I need to add an authentication activity:
var responseBuilder = new FillResponse.Builder();
var autofillIds = FindAutoFillIds(); //gets the autofill ids for each EditText
Intent intent = new Intent(this, typeof(MyAuthActivity));
var sender = PendingIntent.GetActivity(this, 0, intent, PendingIntentFlags.CancelCurrent).IntentSender;
RemoteViews presentation = AutofillHelper.NewRemoteViews(PackageName, "fill data after auth", AppNames.LauncherIcon);
var datasetBuilder = new Dataset.Builder(presentation);
//Main difference here:
datasetBuilder.SetAuthentication(sender);
foreach (AutofillId autofillId in autofillIds)
{
datasetBuilder.SetValue(autofillId, AutofillValue.ForText("some placeholder data"));
}
responseBuilder.AddDataset(datasetBuilder.Build());
callback.OnSuccess(responseBuilder.Build());
where MyAuthActivity.OnCreate is like this:
RemoteViews presentation = AutofillHelper.NewRemoteViews(PackageName, "dataset from auth activity", AppNames.LauncherIcon);
var datasetBuilder = new Dataset.Builder(presentation);
var autofillIds = GetAutofillIds(...); //returns the same autofillIds as in the onFillRequest
foreach (AutofillId autofillId in autofillIds)
{
datasetBuilder.SetValue(autofillId, AutofillValue.ForText("some other data"));
}
var ReplyIntent = new Intent();
bool returnDataset = true; //tried both true and false, neither works
if (returnDataset)
{
ReplyIntent.PutExtra(AutofillManager.ExtraAuthenticationResult, datasetBuilder.Build());
}
else
{
var responseBuilder = new FillResponse.Builder();
responseBuilder.AddDataset(datasetBuilder.Build());
ReplyIntent.PutExtra(AutofillManager.ExtraAuthenticationResult, responseBuilder.Build());
}
SetResult(Result.Ok, ReplyIntent);
Finish();
which basically creates another dataset using the same autofill ids, but neither returning them with a FillResponse nor a Dataset response works: The input fields on the target app remain empty.
I noticed that the same behavior appears in Bitwarden's implementation of their autofill service.
My questions are: Is there anything wrong with the code of the authentication activity? Or does this show an issue with Paypal's app? And is there anything I can do to debug this further?
This is a known WebView issue, which is fixed on Chrome M64.
You can verify it's fixed by installing a newer Chrome and changing the default WebView implementation through Settings -> Developer Options.
My request fails doing a call
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(MyAPI.BASE_URL)
.addConverterFactory(JacksonConverterFactory.create())
.build();
// prepare call in Retrofit 2.0
MyAPI myAPI = retrofit.create(MyAPI.class);
**// Debug fails here on line below**
Call<List<Place>> call = myAPI.loadPlaces(3, "restaurant");
My interface
// Base search url, trailing slash needed
String BASE_URL = "https://test.domain.com/";
#GET("place/search")
Call<List<Place>> loadPlaces(
#Query("count") int amountOfResults,
#Query("filter_category") String category);
Unfortunately this question did not helped, while most search results are using Gson and RxJava
Is there a way to get results without using a call?
You can use rxJava library, for that you have to use specific call adapter factory during Retrofit instance creation: .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .
Advantage of this method is that you can easily handle request in background and be notified about errors.
Observable<List<Place>> pendingResult = myApi.getPlaces();
pendingResult.subscribeOn(Schedulers.io)
.map(places -> {
// pre- process places somehow
})
.subscribe(places -> {
// process result
}, error -> {
// handle error
}}
See this tutorial: https://medium.freecodecamp.com/rxandroid-and-retrofit-2-0-66dc52725fff#.5h0ecp5dg