I had just now created a new API key after enabling Places API in the developer console.
Code for implementing Place picker API:
Places.initialize(getApplicationContext(), "#string/google_place_api");
List<com.google.android.libraries.places.api.model.Place.Field> placeFields = new ArrayList<>(Arrays.asList(com.google.android.libraries.places.api.model.Place.Field.values()));
List<TypeFilter> typeFilters = new ArrayList<>(Arrays.asList(TypeFilter.values()));
// Create a RectangularBounds object.
RectangularBounds bounds = RectangularBounds.newInstance(
new LatLng(-33.880490, 151.184363),
new LatLng(-33.858754, 151.229596));
Intent autocompleteIntent =
new Autocomplete.IntentBuilder(AutocompleteActivityMode.FULLSCREEN, placeFields)
.setLocationBias(bounds)
.setTypeFilter(typeFilters.get(0))
.build(getApplicationContext());
startActivityForResult(autocompleteIntent, 1001);
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1001) {
if (resultCode == RESULT_OK) {
Place place = Autocomplete.getPlaceFromIntent(data);
Toast.makeText(getApplicationContext(),place.getName()+ ", " + place.getId(), Toast.LENGTH_SHORT).show();
} else if (resultCode == AutocompleteActivity.RESULT_ERROR) {
// TODO: Handle the error.
Status status = Autocomplete.getStatusFromIntent(data);
Toast.makeText(getApplicationContext(), status.getStatusMessage(), Toast.LENGTH_SHORT).show();
} else if (resultCode == RESULT_CANCELED) {
Toast.makeText(getApplicationContext(), "Please select a location", Toast.LENGTH_SHORT).show();
}
}
}
The problem is that I keep getting a toast showing The provided API key is invalid whenever I try to search for a location. How is this possible? The API key I got is completely new.
Edit: This is the error that I keep getting in my Logcat
The Google Play services resources were not found. Check your project configuration to ensure that the resources are included.
2019-04-29 19:36:10.285 14975-14975/com.example.myapplication E/Places: Error while autocompleting: REQUEST_DENIED
You are incorrectly passing the API Key.
Replace this line:
Places.initialize(getApplicationContext(), "#string/google_place_api");
with:
Places.initialize(getApplicationContext(), getString(R.string.google_place_api));
Related
I have trying to implement Google Sign In on my app by following the guide.
https://developers.google.com/identity/sign-in/android/start-integrating#add_google_play_services
However, I keep getting error 10 everytime I go to try to log in and I know it means its a developer error but, I cant figure out what I am doing wrong. I implemented all the code, made sure I have the correct packages and updated Android Studio.
I tried different client ids from SHA1 hashes that came from multiple generated signed bundles and apks for my app. I tried the pre generated one that Google gives you for sign-in. Any ideas?
Intent for google sign in
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestEmail()
.requestIdToken(getString(R.string.server_client_id))
.build();
googleSignInClient = GoogleSignIn.getClient(getActivity(),gso);
Intent signInIntent = googleSignInClient.getSignInIntent();
startActivityForResult(signInIntent, 21);
OnActivityResult function
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
callbackManager.onActivityResult(requestCode, resultCode, data);
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == 21) {
Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
handleSignInResult(task);
}
else if (resultCode == RESULT_CANCELED)
{
Log.d("frag", "intent fired and something went wrong");
}
}
handleSignInResult function
private void handleSignInResult(Task<GoogleSignInAccount> completedTask) {
try {
GoogleSignInAccount account = completedTask.getResult(ApiException.class);
// Signed in successfully, show authenticated UI.
Log.d("frag", "Email of account is " + account.getEmail());
} catch (ApiException e) {
// The ApiException status code indicates the detailed failure reason.
// Please refer to the GoogleSignInStatusCodes class reference for more information.
Log.w("ytsignin", "signInResult:failed code=" + e.getStatusCode());
}
}
Check the SHA-1 code and package name in developer console. Most of the time it is what causes the error 10 which is 'DEVELOPER_ERROR'.
Check the SHA-1 in console against the one you get from Android Studio after running signingReport.
I am using FirebaseUI for Auth to handle authentication, What I want to do is to specify a certain activity to open if the user is signed-up (logged-in for the first time), Is there's a possible way to achieve this?
EDIT: Here's the FirebaseUi authentication used:
List<AuthUI.IdpConfig> providers = Arrays.asList(
new AuthUI.IdpConfig.Builder(AuthUI.EMAIL_PROVIDER).build(),
new AuthUI.IdpConfig.Builder(AuthUI.GOOGLE_PROVIDER).build());
startActivityForResult(
AuthUI.getInstance()
.createSignInIntentBuilder()
.setIsSmartLockEnabled(false)
.setAvailableProviders(providers)
.setTheme(R.style.LoginTheme)
.setLogo(R.drawable.ic_melomania_blue_light)
.build(),
RC_SIGN_IN);
The onActivityResult :
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RC_SIGN_IN) {
if (resultCode == RESULT_OK) {
// Sign-in succeeded, set up the UI
Toast.makeText(this, "Signed in!", Toast.LENGTH_SHORT).show();
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
} else if (resultCode == RESULT_CANCELED) {
// Sign in was canceled by the user, finish the activity
Toast.makeText(this, "Sign in canceled", Toast.LENGTH_SHORT).show();
finish();
}
}}
I'd recommend checking out the docs. Here's an example of how you would handle the response from your activity:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// RC_SIGN_IN is the request code you passed into startActivityForResult(...) when starting the sign in flow.
if (requestCode == RC_SIGN_IN) {
IdpResponse response = IdpResponse.fromResultIntent(data);
// Successfully signed in
if (resultCode == RESULT_OK) {
startActivity(SignedInActivity.createIntent(this, response)); // <--- This is what you are looking for!
finish();
} else {
// Sign in failed
if (response == null) {
// User pressed back button
showSnackbar(R.string.sign_in_cancelled);
return;
}
if (response.getError().getErrorCode() == ErrorCodes.NO_NETWORK) {
showSnackbar(R.string.no_internet_connection);
return;
}
showSnackbar(R.string.unknown_error);
Log.e(TAG, "Sign-in error: ", response.getError());
}
}
}
And to specifically check if this is a first time user, take a look at this example:
FirebaseUserMetadata metadata = auth.getCurrentUser().getMetadata();
if (metadata.getCreationTimestamp() == metadata.getLastSignInTimestamp()) {
// The user is new, show them a fancy intro screen!
} else {
// This is an existing user, show them a welcome back screen.
}
To go to a specific activity after the user sign up in Firebase, you can do this:
auth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(StudentSignUpActivity.this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
Toasty.info(getApplicationContext(), "creation of account was: " + task.isSuccessful(), Toast.LENGTH_SHORT).show();
if (task.isSuccessful()) {
startActivity(new Intent(CurrentActivity.this,ActivityYouWantToGoTo.class));
finish();
After the user enters the email and the password, then you can use the above method to authenticate the user and if it was successful it will redirect the user to the activity that you want, using this:
startActivity(new Intent(CurrentActivity.this,ActivityYouWantToGoTo.class));
the above activity names are just samples, you should change them depending on your activity name.
I logged in successfully and got the twitter access token and the twitter access secret using firebase-ui-auth [https://github.com/firebase/FirebaseUI-Android/blob/master/auth/README.md][1]:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RC_SIGN_IN && resultCode == RESULT_OK) {
IdpResponse response = IdpResponse.fromResultIntent(data);
//twitter access token
response.getIdpToken();
//twitter access token secret
response.getIdpSecret();
}
}
I want to post on user's behalf(to their accounts, not to mine) using these two tokens that I will save on shared preferences.
1) Are these two tokens enough to post to user's account?
2) How do I do to post something using these two tokens?. I can't seem to find the proper docs for my particular case, the twitter api handling for android is really poor.
I already solved it myself by using fabric and its TweetComposer class.....
first you need to initialize fabric on the bootstrap Class of your app
Fabric.with(this, new Twitter(authConfig));
then on the class you want to make the tweet you get the firebase instance to get the logged in user and then you set the twitter consumer key and secret that you got when you log in to firebase UI https://github.com/firebase/FirebaseUI-Android/blob/master/auth/README.md, for future reference to get the two tokens needed to tweet on user's behalf you can do it like the link specifies:
To retrieve the ID token that the IDP returned, you can extract an IdpResponse from the result Intent.
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
IdpResponse idpResponse = IdpResponse.fromResultIntent(data);
startActivity(new Intent(this, WelcomeBackActivity.class)
.putExtra("my_token", idpResponse.getIdpToken()));
}
}
Twitter also returns an AuthToken Secret which can be accessed with idpResponse.getIdpSecret().
and now you have everything you need:
mAuth = FirebaseAuth.getInstance();
if (mAuth.getCurrentUser() != null) {
// already signed in
twitter_consumer_key= preferences.getString("TWITTER_CONSUMER_KEY","");
twitter_consumer_secret= preferences.getString("TWITTER_CONSUMER_SECRET","");
TwitterAuthConfig authConfig = new TwitterAuthConfig(twitter_consumer_key, twitter_consumer_secret);
//setting up fabric
Fabric.with(this, new TwitterCore(authConfig), new TweetComposer());
}
and then let's say I want to tweet from a custom button onClick:
ImageButton tweetButton= (ImageButton) findViewById(R.id.tweet_button);
tweetButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
TweetComposer.Builder builder = new TweetComposer.Builder(mContext)
.text("just setting up my Fabric.");
builder.show();
}
});
the app will redirect you to the twitter app with the preseted message "just setting up my Fabric.". You can add pictures and videos too!
Hope that this helps someone in the future cause there is little info about fabric....
I'll just go straight to the problem. In UploadNotesActivity.java....
First, I pick a .pdf file using intent
chooseNotesBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Create intent to Open Image applications like Gallery, Google Photos
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");
// Start the Intent
startActivityForResult(intent, RESULT_LOAD_FILE);
}
});
and then, in `onActivityResult, I save the filePath of the picked file.
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RESULT_LOAD_FILE && resultCode == RESULT_OK && data != null) {
data.putExtra("filePath", data.getData().getPath());
choosenFile.setText(data.getStringExtra("filePath"));
} else {
Toast.makeText(this, "Error in choosing file",
Toast.LENGTH_LONG).show();
}
}
click Upload button to start upload the file
uploadNotesBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onUploadButtonClick();
}
});
the onUploadButtonClick()
private void onUploadButtonClick() {
final String serverUrlString = "http://XXXX/uploadNotes.php";
if (getIntent().getStringExtra("filePath").isEmpty()) {
Log.d(TAG, "filePath is null");
} else {
Log.d(TAG, getIntent().getStringExtra("filePath"));
}
final String fileToUploadPath = getIntent().getStringExtra("filePath");
final String paramNameString = "uploaded_file";
String fileName[] = fileToUploadPath.split("/");
final MultipartUploadRequest request =
new MultipartUploadRequest(this, UUID.randomUUID().toString(), serverUrlString);
request.addFileToUpload(fileToUploadPath, paramNameString,
fileName[fileName.length-1]+".pdf", ContentType.APPLICATION_OCTET_STREAM);
request.setNotificationConfig(R.drawable.ic_launcher,
getString(R.string.app_name),
getString(R.string.uploading),
getString(R.string.upload_success),
getString(R.string.upload_error),
false);
// if you comment the following line, the system default user-agent will be used
request.setCustomUserAgent("UploadServiceDemo/1.0");
// set the intent to perform when the user taps on the upload notification.
// currently tested only with intents that launches an activity
// if you comment this line, no action will be performed when the user taps
// on the notification
// request.setNotificationClickIntent(new Intent(this, MainActivity.class));
// set the maximum number of automatic upload retries on error
request.setMaxRetries(2);
try {
request.startUpload();
} catch (Exception exc) {
Toast toast = Toast.makeText(getApplicationContext(), "Malformed upload request. " + exc.getLocalizedMessage(), Toast.LENGTH_LONG);
toast.show();
}
}
But the problem is, it will throw null pointer exception, which I don't quite get the reason.
java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.isEmpty()' on a null object reference
at com.fyp.mycyberlaw.Lecturer.UploadNotesActivity.onUploadButtonClick(UploadNotesActivity.java:73)
at com.fyp.mycyberlaw.Lecturer.UploadNotesActivity.access$100(UploadNotesActivity.java:19)
at com.fyp.mycyberlaw.Lecturer.UploadNotesActivity$2.onClick(UploadNotesActivity.java:53)
line 73: if (getIntent().getStringExtra("filePath").isEmpty())
line 19: public class UploadNotesActivity extends Activity
line 53: onUploadButtonClick();
Seems like the filePath in line 73 is empty and the way I save filePath into bundle (?) is incorrect. How to get the filePath from onActivityResult? Here's the .java class, just in case. Thank you in advance. Really need your help.
An Intentobject is used to pass params between activities. Ones you receives the file path you must to keep it in your activity.
Create a filePathvariable inside your activity, set it on onActivityResult and read it on onUploadButtonClick.
Notice that must save variable value during the onSaveInstanceState callback and restore it in onCreate because every time you turn your phone the activity is destroyed and recreated. Check this for more information: Recreating an Activity
this is my first question on stack*overflow*!
I am using Eclipse with Android Development Tools. I have copied the code from GitHub - ZXing to scan a QR code using Barcode Scanner (many of you have seen this code before, I'm sure):
public void onClick(View v)
{
Intent intent = new Intent("com.google.zxing.client.android.SCAN");
intent.putExtra("SCAN_MODE", "QR_CODE_MODE");
startActivityForResult(intent,0);
}
I am able to get the Barcode Scanner started and it returns results in the onActivityResult() method.
public void onActivityResult(int requestCode, int resultCode, Intent intent)
{
if (requestCode == 0)
{
if (resultCode == RESULT_OK)
{
contents = intent.getStringExtra("SCAN_RESULT");
format = intent.getStringExtra("SCAN_RESULT_FORMAT");
// Handle successful scan
if(contents == "1")
{
contentsLat = contents;
}
else if(contents == "0")
{
contentsRow = contents;
}
else
{
Toast.makeText(getApplicationContext(), "Code Not Recognized\n"+contents+"\n1", Toast.LENGTH_LONG).show();
}
}
else if (resultCode == RESULT_CANCELED)
{
// Handle cancel
Toast.makeText(getApplicationContext(), "Unsuccessful Scan", Toast.LENGTH_SHORT).show();
}
}
}
However, the else statement is always executed...unless I explicitly equate contents to 1. Below is a link to the screenshot (I don't have embedded image privileges yet) of the else body being executed and the toast clearly indicates that contents=1. What have I done wrong? Did I miss something?
Thanks everybody.
Welcome to stackoverflow!
I have seen this is a very common issue in new Java programmmers :), for String comparison we must use the equals() method.
Change your code to:
// Handle successful scan
if(contents.equals("1")){
contentsLat = contents;
}
else if(contents.equals("0")){
contentsRow = contents;
}
More info:
Java comparison with == of two strings is false?
The equals() Method