android share clickable string url with indication google maps - java

I have a listview of elements. Each element is a different place and when I click into one of this I open a google map intent with the way to go.
Sometimes I need to share the address (for example "Colosseo, Piazza del Colosseo 1, 00184 Roma RM".
How do I share this string with a clickable url? I want to share it and permit other people to click inside it and open google map
This is how I create the intent:
public void OpenMaps(Context context) {
Toast.makeText(context, "Ti porto a: "Colosseo, Piazza del Colosseo 1, 00184 Roma RM", Toast.LENGTH_SHORT).show();
Uri address = Uri.parse("google.navigation:q=Colosseo,+Piazza+del+Colosseo+1,+00184+Roma+RM");
Intent mapIntent = new Intent(Intent.ACTION_VIEW, address);
context.startActivity(mapIntent);
}

Maybe you'll like this:
private String UrlMap(String s) {
try {
String url = "https://www.google.com/maps/search/?api=1&query=" + URLEncoder.encode(s, "UTF-8");
return url;
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return "";
}
I don't know how to set a custom caption, to avoid seeing the entire url

Related

Get value from deeplink parameter rather than dynamic link in android java

I made an application in which users can send links to their friends. With the link, I added some parameters, So when the user clicks on the link the page with the given parameter will open.
The deep link user sends to his friends is:
Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
sharingIntent.setType("text/plain");
String shareBody = "https://shareemotion.page.link/mood?mood=Sad&bottomneg=2";
sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "Subject Here");
sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, shareBody);
context.startActivity(Intent.createChooser(sharingIntent, "Share via"));
While the dynamic link in firebase is:
https://www.myapp.com/?mood=Happy&bottomneg=2
And the code for getting data from link is :
FirebaseDynamicLinks.getInstance()
.getDynamicLink(getIntent())
.addOnSuccessListener(this, new OnSuccessListener<PendingDynamicLinkData>() {
#Override
public void onSuccess(PendingDynamicLinkData pendingDynamicLinkData) {
// Get deep link from result (may be null if no link is found)
Uri deepLink = null;
if (pendingDynamicLinkData != null) {
deepLink = pendingDynamicLinkData.getLink();
}
if(deepLink!=null)
{
String mood = deepLink.getQueryParameter("mood");
String bottomId = deepLink.getQueryParameter("bottomneg");
NewActivity(mood, bottomId);
}
}
})
.addOnFailureListener(this, new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.e( "getDynamicLink", " "+e);
}
});
So Now when I share the link with mood=Sad the app run but at the fetching point it fetches "Happy"(which is present in the dynamic link) but I want to fetch mood=Sad from the link that sends to another user.
Note
mood=Sad will replace by variable, for now, it uses for testing purposes.

Write ndef message to NFC Tag fails with java.io.exception

I want to write simple text data to my NXP MiFARE DesFire EV1 (NDEF Type 4 Tag). However, the writing process always fails with an IOExcetion
For writing I get the NFC-Tag I use the function write:
private void write(String mimeType, String text, Tag tag) throws IOException, FormatException {
NdefRecord[] records = {createRecord(mimeType, text)};
NdefMessage message = new NdefMessage(records);
Ndef ndef = Ndef.get(tag);
ndef.connect();
ndef.writeNdefMessage(message);
ndef.close();
}
The result in the third line (Ndef ndef = Ndef.get(tag)) is the following:
TAG: Tech [android.nfc.tech.IsoDep, android.nfc.tech.NfcA, android.nfc.tech.Ndef]
From this I assumed, the Tag is formatted correclty (as NDEF).
Now, when calling ndef.connect() it just says java.io.exception without any additional information about the error. The other parts of the code, that get called is appended.
#Override
public void onNewIntent(Intent intent) {
super.onNewIntent(intent);
String action = intent.getAction();
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {
tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
if (tag != null) {
String serialId = Utility.bytesToHex(tag.getId());
Log.d("[WriteCard]", "Serial Number: " + serialId);
Toast.makeText(this, serialId, Toast.LENGTH_SHORT).show();
}
}
}
// When the write Button is clicked
public void onClick(View view) {
if (nfc_adapter == null) {
Toast.makeText(this, "No NFC", Toast.LENGTH_SHORT).show();
return;
}
int id = view.getId();
Intent intent = getIntent();
try {
write("type/1", spinner_location.toString(), tag);
}
catch(Exception e) {
Log.d("[WriteCard]", e.toString());
Toast.makeText(this, e.toString(), Toast.LENGTH_SHORT).show();
}
}
The NXP Tag Info App reports the following:
IC Type: MiFARE DESFire EV1
Type 4 Tag
NFC data set access: Read&Write
Additional Info: The writing process with Android-Apps like NFC TagWriter by NXP or wakdev NFC Tools works without any problem, thus I assume, the Tag is working correctly.
Really trying to write to a Tag on a Button click will always be unreliable and also using enableForeGroundDispatch is also unreliable in real life as it is highly likely that the Tag will be moved slightly that it will go out of range and thus generate I/O errors.
The two Apps you mention don't do it the way you are trying to do.
Also the documentation says connect and writeNdefMessage
May cause RF activity and may block. Must not be called from the main application thread.
and you are calling these from the main (UI) thread.
Your button just needs to setup the action that "when Tag comes in to range, immediately write text"
e.g. some thing like
private String text;
#Override
public void onNewIntent(Intent intent) {
super.onNewIntent(intent);
String action = intent.getAction();
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {
tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
if (tag != null) {
if(text.isEmpty()) {
// Nothing to write so read
String serialId = Utility.bytesToHex(tag.getId());
Log.d("[WriteCard]", "Serial Number: " + serialId);
Toast.makeText(this, serialId, Toast.LENGTH_SHORT).show();
} else {
// Have some text to write
try {
write("type/1", text, tag);
} catch(Exception e) {
Log.d("[WriteCard]", e.toString());
Toast.makeText(this, e.toString(), Toast.LENGTH_SHORT).show();
}
// Reset the write trigger
text = "";
}
}
}
// When the write Button is clicked
public void onClick(View view) {
text = spinner_location.toString();
}
Also you really need to check that your Tag is a Formatted Ndef Tag before your try and write to it.
e.g. something like
private void write(String mimeType, String text, Tag tag) throws IOException, FormatException {
NdefRecord[] records = {createRecord(mimeType, text)};
NdefMessage message = new NdefMessage(records);
Ndef ndef = Ndef.get(tag);
if(ndef != null) {
// It's an already formatted Ndef Tag
ndef.connect();
ndef.writeNdefMessage(message);
ndef.close();
} else {
// Try and format at write
.... "get(tag)" for Ndef formattable type and check not null
}
}
The final point is using the old enableForegroundDispatch is unreliable, so use the Newer and better enableReaderMode and onTagDiscovered API instead.
This also solves the calling connect etc on the wrong thread as onTagDiscovered is automatically in it's own thread.
Also enableReaderMode when you disable the "Platform" sounds it does not prompt the user to remove the Tag from range before you have had a chance to write to it (You can play your own sound after a successful write)
See https://stackoverflow.com/a/64921434/2373819 for an example of enableReaderMode

Unable to find working solution with Intent.ACTION_SEND_MULTIPLE for multiple images to be attached to an email

So here's the situation - I'm developing an Unreal plugin with native android features.
Intention for single image works perfectly, but now, when I'm trying to add multiple image attachments using ACTION_SEND_MULTIPLE it's not starting activity.
No errors, execution stops on .startActivity(), wrapping with try-catch doesn't return any exceptions, Unreal passes images array without any issue.
I feel like it's not building intent properly, but after 2 days of searching and countless hours of trials and errors I feel like it's time to give up and seek for advise here :)
Here's the java part of the code I'm suspecting isn't working:
public static void sendEMail(Activity activity, String subject, String[] extraImagePaths,
String[] recipients, String[] cc, String[] bcc,
boolean withChooser, String chooserTitle) {
Intent intent = createEMailIntent(subject, recipients, cc, bcc);
ArrayList<Uri> paths = new ArrayList<Uri>();
if (extraImagePaths.length > 0) {
for (String extraImagePath : extraImagePaths) {
File fileIn = new File(extraImagePath);
Uri arrayPath = Uri.fromFile(fileIn);
paths.add(arrayPath);
}
}
intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, paths);
try {
launchShareIntent(activity, withChooser, chooserTitle, intent);
} catch (Exception e) {
Log.d("AndroidLOG:", e.getMessage());
}
}
private static Intent createEMailIntent(String subject, String[] recipients, String[] cc, String[] bcc) {
return new Intent(Intent.ACTION_SEND_MULTIPLE)
.setData(Uri.parse("mailto:"))
.setType("image/*")
.putExtra(Intent.EXTRA_SUBJECT, subject)
.putExtra(Intent.EXTRA_EMAIL, recipients)
.putExtra(Intent.EXTRA_CC, cc)
.putExtra(Intent.EXTRA_BCC, bcc);
}
private static void launchShareIntent(Activity activity, boolean withChooser, String chooserTitle, Intent intent) {
if (withChooser) {
Intent chooserIntent = Intent.createChooser(intent, chooserTitle);
activity.startActivity(chooserIntent);
} else {
activity.startActivity(intent);
}
}
tried removing all of the extras, except images, but that didn't solve the problem.
Help would be much appreciated!
After more digging through SO found similar post, changed .fromFile() to FileProvider and it worked like a charm.
Snippet:
for (String extraImagePath : extraImagePaths) {
Uri arrayPath = FileProvider.getUriForFile(activity, getAuthority(activity), new File(extraImagePath));
paths.add(arrayPath);
}
P.S. Credit goes to CommonsWare!

Is there a way to specify which words in the training phrase are fulfilling slots in Dialogflow through java sdk

I would like to create an intent using the Dialogflow java-sdk. The problem is I am am able to create training phrases and slots but I am not able to alocate the specific word to the training phrase like we do in the dialogflow console.
I have checked and Dialogflow also does not do it by itself.
Below I have wrotten the code I am currently using and the functions I have used. This may not help but may help in providing info into the current method I am using .
Is there any function in the dialogflow java api that will help me to achive this.
public OutputResponseDTO createIntent(CreateIntentInputDTO createIntentInputDTO)
{
// Instantiates a client
try (IntentsClient intentsClient = IntentsClient.create()) {
// Set the project agent name using the projectID (my-project-id)
ProjectAgentName parent = ProjectAgentName.of(createIntentInputDTO.getProjectId());
//first check if intent already exists
for (Intent intent : intentsClient.listIntents(parent).iterateAll()) {
//logger.error(intent.getDisplayName()+"Inside delete!!!!!!"+createIntentInputDTO.getIntentName());
if (intent.getDisplayName().equals(createIntentInputDTO.getDisplayName())) {
logger.error("Inside delete!!!!!!");
deleteIntent(createIntentInputDTO.getIntentName(),createIntentInputDTO.getProjectId());
}
}
List<String> trainingPhrasesIP=new ArrayList<String>();
for(int l=0;l<createIntentInputDTO.getTrainingPhrasesParts().size();l++)
{
trainingPhrasesIP.add(createIntentInputDTO.getTrainingPhrasesParts().get(l).getPhraseName());
}
// Build the trainingPhrases from the trainingPhrasesParts
List<TrainingPhrase> trainingPhrases = new ArrayList<>();
for (String trainingPhrase : trainingPhrasesIP) {
trainingPhrases.add(
TrainingPhrase.newBuilder().addParts(
Part.newBuilder().setText(trainingPhrase).build())
.build());
}
// Build the message texts for the agent's response
Message messages = Message.newBuilder()
.setText(
Text.newBuilder()
.addAllText(createIntentInputDTO.getMessageTexts()).build()
).build();
List<Parameter> parameters=new ArrayList<Intent.Parameter>();
for(int j=0;j<createIntentInputDTO.getSlotsInputDTOs().size();j++)
{
//String firstFourChars = createIntentInputDTO.getSlotsInputDTOs().get(j).getEntityDisplayName().substring(0, 5);
//System.out.println(firstFourChars);
String paraNameWithoutAtTwo;
String paraNameWithoutAtOne;
String paraNameWithoutAtAndWithDollar;
String paraNameWithAt;
try
{
paraNameWithoutAtOne=createIntentInputDTO.getSlotsInputDTOs().get(j).getEntityDisplayName().replace("#sys.", "");
paraNameWithoutAtTwo=paraNameWithoutAtOne.replace("#", "");
}
catch(Exception e)
{
paraNameWithoutAtTwo=createIntentInputDTO.getSlotsInputDTOs().get(j).getEntityDisplayName();
logger.info("Something happended when removing stuff");
}
paraNameWithoutAtAndWithDollar="$"+paraNameWithoutAtTwo;
paraNameWithAt="#"+paraNameWithoutAtTwo;
paraNameWithoutAt=createIntentInputDTO.getSlotsInputDTOs().get(j).getEntityDisplayName();
Parameter parameter=Parameter.newBuilder()
.setValue(createIntentInputDTO.getSlotsInputDTOs().get(j).getValue())
.setDisplayName(paraNameWithoutAtTwo)
.setValue(paraNameWithoutAtAndWithDollar)
.setEntityTypeDisplayName(createIntentInputDTO.getSlotsInputDTOs().get(j).getEntityDisplayName())
.build();
parameters.add(parameter);
}
// Build the intent
Intent intent = Intent.newBuilder()
.setDisplayName(createIntentInputDTO.getDisplayName())
.addMessages(messages)
// .addParameters(p)
.addAllParameters(parameters)
.addAllTrainingPhrases(trainingPhrases)
.build();
// Performs the create intent request
Intent response = intentsClient.createIntent(parent, intent);
// System.out.format("Intent created: %s\n", response);
try
{
IntentMasterCollection intentMasterCollection=new IntentMasterCollection();
intentMasterCollection.setName(createIntentInputDTO.getDisplayName());
intentActionMaster.save(intentMasterCollection);
}
catch(Exception e)
{
logger.error("Error adding in DB intent master");
}
try
{
//we gonna put the data again!(Training phrases only)
String[] splitName = response.getName().split("/");
// intentIds.add(splitName[splitName.length - 1]);
//finally setting all the values
updateIntent(splitName[splitName.length - 1]);
}
catch(Exception e)
{
logger.error("Error in writing to intent");
}
return new OutputResponseDTO(true, message.getStatusCode("success.message.createIntent.id"),
message.get("success.message.createIntent"), null, null,requestBean.getTraceId());
}
catch(Exception e)
{
logger.error("Error Creating Intent:"+e.getMessage());
return new OutputResponseDTO(false, message.getStatusCode("error.message.generalError.id"),
message.get("error.message.generalError"), null, e.getMessage(),requestBean.getTraceId());
}
}
I think the problem you're having is related to Parts definition.
Every training phrase is split into parts, and for each part, you can define if it is just text or if it contains an entity:
Part part1 = Part.newBuilder().setText("I want to cancel a card ended in ").build();
Part part2 = Part.newBuilder().setText("5123").setEntityType("#cardNumber").setAlias("cardNumber")
.setUserDefined(true).build();
List<Part> parts = new ArrayList<Part>();
parts.add(part1);
parts.add(part2);
Then you build the training phrase:
TrainingPhrase tp = TrainingPhrase.newBuilder().setType(Type.EXAMPLE).addAllParts(parts).build();

Understand SharedPreferences Android

In android I want to make a basic login and registration application. I am following this tutorial. The application works properly and runs. I am just trying to understand the code now and after many google searches I can not understand some of the code and was wondering if somebody could help me understand it.
Below I have posted the method I do not understand and in comments highlighted what I do not understand - any clarification is much appreciated, I have also commented the code to what I believe the code does, if any of it is incorrect please tell me, you can also view all of the code on the tutorial website.
I am mainly confused about how the sharedpreferences works I have followed his tutorial on sharedpreferences too I understand that but do not understand this. Thank you and sorry if the problem is very basic
private void checkLogin(final String email, final String password) {
// Tag used to cancel the request
String tag_string_req = "req_login";
// Dialog stating trying to login
pDialog.setMessage("Logging in ...");
showDialog();
// Send the request over to the database to check details
StringRequest strReq = new StringRequest(Method.POST,
AppConfig.URL_LOGIN, new Response.Listener<String>() {
// Do this once you get a response
#Override
public void onResponse(String response) {
Log.d(loginName, "Login Response: " + response.toString());
hideDialog();
// Break the response up into individual things and store in variables
try {
JSONObject jObj = new JSONObject(response);
boolean error = jObj.getBoolean("error");
// Check for error node in json
if (!error) {
// I DO NOT UNDERSTAND THIS!!! how does this bit work?
// it sets the shared preferences login to true correct?
// but how does it set it true to only this particular user?
// Because it doesnt store the email and password along with it
// and sets its tag "isLoggedIn" and then saves it to the shared
// preferences
session.setLogin(true);
// Now store the user in SQLite
String uid = jObj.getString("uid");
JSONObject user = jObj.getJSONObject("user");
String name = user.getString("name");
String email = user.getString("email");
String created_at = user
.getString("created_at");
//I DO NOT UNDERSTAND THIS!!! Why do you need to do this & does this
//affect the MySQL DB at all?
db.addUser(name, email, uid, created_at);
// I DO NOT UNDERSTAND THIS!!! Why do you need to write LoginActivity.this
// do you not just write MainActivity?
Intent intent = new Intent(LoginActivity.this,
MainActivity.class);
startActivity(intent);
finish();
} else {
// Error in login. Get the error message
String errorMsg = jObj.getString("error_msg");
Toast.makeText(getApplicationContext(),
errorMsg, Toast.LENGTH_LONG).show();
}
} catch (JSONException e) {
// JSON error
e.printStackTrace();
Toast.makeText(getApplicationContext(), "Json error: " + e.getMessage(), Toast.LENGTH_LONG).show();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e(loginName, "Login Error: " + error.getMessage());
Toast.makeText(getApplicationContext(),
error.getMessage(), Toast.LENGTH_LONG).show();
hideDialog();
}
}) {
/***************************************************************/
//I DO NOT UNDERSTAND THIS WHOLE METHOD WHY DO YOU DO THIS?!!!
/***************************************************************/
#Override
protected Map<String, String> getParams() {
// Posting parameters to login url
Map<String, String> params = new HashMap<String, String>();
params.put("email", email);
params.put("password", password);
return params;
}
};
// FINALLY I ALSO DO NOT UNDERSTAND WHY YOU DO THIS! AND WHAT DOES IT DO
AppController.getInstance().addToRequestQueue(strReq, tag_string_req);
}
This adds a user to an SQL database:
db.addUser(name, email, uid, created_at);
There should be a class somewhere that defines the actual function, which then creates the query that actually interacts with the database.
The intent changes the activity (what is rendered on the screen and what logic is handled):
LoginActivity.this: the context in the current class - this can be simplified to just this, but it's a bit of syntactic sugar in Java that attempts to clarify which this is being referred to.
MainActivity.class: the target activity
Intent intent = new Intent(LoginActivity.this,
MainActivity.class);
The difference between two activities can be explained with the content of a game. The menu is "LoginActivity.this" and "MainActivity.class" is the actual game content
As for shared preferences, the usage is pretty straight-forward:
To obtain shared preferences, use the following method In your
activity:
SharedPreferences prefs = this.getSharedPreferences(
"com.example.app", Context.MODE_PRIVATE);
To read preferences:
String dateTimeKey = "com.example.app.datetime";
// use a default value using new Date()
long l = prefs.getLong(dateTimeKey, new Date().getTime());
To edit and save preferences
Date dt = getSomeDate();
prefs.edit().putLong(dateTimeKey, dt.getTime()).apply();
(Source, posted by naikus)
The internal mechanics aren't something you need to worry about - the thing you really need to know is that it's able to save your data in a way you can use that doesn't involve directly accessing files (which has become a maze since Android 10).
EDIT:
Based on what I saw at the tutorial, the entire thing is to check if the login information entered exists in the database. The getParams() method defines what goes into the form data

Categories

Resources