I'm having trouble with ML Kit Barcode Scanner. When I try to decode a sample QR code,
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.qr_code_sample);
FirebaseVisionImage image = FirebaseVisionImage.fromBitmap(bitmap);
FirebaseVisionBarcodeDetector detector = FirebaseVision.getInstance().getVisionBarcodeDetector();
Task<List<FirebaseVisionBarcode>> result = detector.detectInImage(image)
.addOnSuccessListener(new OnSuccessListener<List<FirebaseVisionBarcode>>() {
#Override
public void onSuccess(List<FirebaseVisionBarcode> barcodes) {
for (FirebaseVisionBarcode barcode:barcodes) {
Log.e("Log", "QR Code: "+barcode.getUrl().getUrl());
}
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.e("Log", "Decode QR Code failed");
}
});
The output is like this:
QR Code: ""
How to solve this problem?
According to the API Reference, the getUrl() is:
set iff getValueType() is TYPE_URL
So your barcode is probably not an URL/Bookmark, or ML Kit does not recognize it as such.
I recommend printing these 3 values:
#Override
public void onSuccess(List<FirebaseVisionBarcode> barcodes) {
for (FirebaseVisionBarcode barcode:barcodes) {
Log.e("Log", "QR Code: "+barcode.getDisplayValue()); //Returns barcode value in a user-friendly format.
Log.e("Log", "Raw Value: "+barcode.getRawValue());//Returns barcode value as it was encoded in the barcode.
Log.e("Log", "Code Type: "+barcode.getValueType()); //This will tell you the type of your barcode
}
}
You'll probably find your desired output in one of the first 2 lines. The third line tells you what type is the barcode you've scanned.
To extract title and url from barcode, you need to have Url Bookmark inside barcode, not just Url.
Raw Data of barcode that contains url bookmark would look something like this: MEBKM:TITLE:MyBookmark;URL:www.google.com;;
When you use ML KIT to scan barcode that consists of url only you get Raw Data like this: www.google.com
So to be able to extract title and url data from object of type FirebaseVisionBarcode.UrlBookmark you need to have those data inside that object.
Try to generate QR code here: https://www.montreallisting.ca/article/qr-code-quick-response-scan-mobile-android-iphone-blackberry/
and then use that picture to extract data you want and you will see as difference.
Related
I would like to read the original dynamic link domain and the shortened url value for example from:
https://APPID.app.goo.gl/XYZT
It is possible to create different domains for a dynamic link in firebase and I use these for identification purpose.
On iOS the dynamic link is handled in
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
//Get the original domain from url variable, but shortened path cannot be fetched as well on iOS -> if anybody knows how this is done, I appreciate any tips
}
and I can find the domain APPID.app.goo.gl but not the path afterwards
and on Android
FirebaseDynamicLinks.getInstance()
.getDynamicLink(getIntent())
.addOnFailureListener(this, new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
e.printStackTrace();
}
})
.addOnSuccessListener(this, new OnSuccessListener<PendingDynamicLinkData>() {
#Override
public void onSuccess(PendingDynamicLinkData pendingDynamicLinkData) {
// pendingDynamicLinkData.getLink(); //deep link but not dynamic link value
}
});
How can i get these values on Android (domain + path) and iOS(path) form the original link?
I am referring Google Places photo android api.
I am using below code in onBindViewHolder of RecyclerView Adapter.
Half the time it throws Illegal State exception. Please help.
final Task<PlacePhotoMetadataResponse> photoMetadataResponse = mGeoDataClient.getPlacePhotos(placeId);
photoMetadataResponse.addOnCompleteListener(new OnCompleteListener<PlacePhotoMetadataResponse>() {
#Override
public void onComplete(#NonNull Task<PlacePhotoMetadataResponse> task) {
// Get the list of photos.
PlacePhotoMetadataResponse photos = task.getResult();
// Get the PlacePhotoMetadataBuffer (metadata for all of the photos).
PlacePhotoMetadataBuffer photoMetadataBuffer = photos.getPhotoMetadata();
// Get the first photo in the list.
PlacePhotoMetadata photoMetadata = photoMetadataBuffer.get(0);
// Get the attribution text.
CharSequence attribution = photoMetadata.getAttributions();
// Get a full-size bitmap for the photo.
Task<PlacePhotoResponse> photoResponse = mGeoDataClient.getPhoto(photoMetadata);
photoResponse.addOnCompleteListener(new OnCompleteListener<PlacePhotoResponse>() {
#Override
public void onComplete(#NonNull Task<PlacePhotoResponse> task) {
PlacePhotoResponse photo = task.getResult();
Bitmap bitmap = photo.getBitmap();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
Glide.with(mContext)
.load(stream.toByteArray())
.asBitmap()
.error(R.drawable.cast_album_art_placeholder)
.centerCrop()
.thumbnail(.2f)
.into(holder.placeImage);
}
});
}
});
StackTrace :
E/UncaughtException: java.lang.IllegalStateException
at com.google.android.gms.common.internal.zzbp.zzbg(Unknown Source)
at com.google.android.gms.common.data.zzc.zzbu(Unknown Source)
at com.google.android.gms.common.data.zzc.<init>(Unknown Source)
at com.google.android.gms.location.places.internal.zzav.<init>(Unknown Source)
at com.google.android.gms.location.places.internal.zzar.<init>(Unknown Source)
at com.google.android.gms.location.places.PlacePhotoMetadataBuffer.get(Unknown Source)
Even if thi issues is almost one year old and since the given answer didn't solve my error, I'll share my solution:
// Get the first photo in the list.
if (photoMetadataBuffer.getCount() > 0) {
PlacePhotoMetadata photoMetadata = photoMetadataBuffer.get(0);
// continue with your code
}
This, because the photoMetadataBuffer isn't null.
But yes, the error happens only for places without pictures.
I am fairly certain that the issue is that your application is crashing due to the fact that you are attempting to retrieve a photo from a location that does not have a photo to display. You must do a null check before attempting to retrieve the first photo in your photoMetadataBuffer.get(0). This is a good example of how Google's documentation is somewhat incomplete from the example code that is provided. You should have something like the following:
// Get the first photo in the list.
if (photoMetadataBuffer != null) {
PlacePhotoMetadata photoMetadata = photoMetadataBuffer.get(0);
// continue with your code
}
If the photoMetadataBuffer is null, then there isn't a photo to be displayed and you can handle your application logic appropriately, such as loading a default image, giving feedback to the user, or not displaying the ImageView.
I am using the Salesforce SDK (4.1.x) in a native Android app. I use the RestClient.sendAsync method to post my form data to a custom object. That part is working fine. Now I need to upload and attach a photo that was taken by the mobile user. I see that RestClient has an uploadFile method. Is this the correct method? If so then how do I connect the uploaded file to the custom form data?
Ok. I figured this out. First, create the parent object (the main form data) using the following.
request = RestRequest.getRequestForCreate(apiVersion, objectType, fields);
client.sendAsync(restRequest, new RestClient.AsyncRequestCallback() {...
In the onSuccess method you will get the id of the new object from the response. There are plenty of examples that show how to get the JSON object and the id. Armed with this parentId we can now create the attachment. The code looks something like this.
private void postImageAsAttachment(String parentId, String title) {
Map<String, Object> fields = new HashMap<String, Object>();
fields.put("Name", title);
fields.put("ParentId", parentId);
fields.put("Body", ImageHelper.getBase64FromImage(mCurrentPhotoPath));
RestRequest request = null;
try {
request = RestRequest.getRequestForCreate(apiVersion, "Attachment", fields);
} catch (Exception ex) {
Log.d(TAG, "sendRequest: ", ex);
Toast.makeText(MainActivity.this, "The file upload failed: " + ex.toString(), Toast.LENGTH_LONG).show();
}
client.sendAsync(request, new RestClient.AsyncRequestCallback() {...
I'm using a simple class called ImageHelper that simply loads the image file, performs image compression (if necessary), and base64 encodes the image data. The result is that an "Attachment" object is created as a child of the parent object.
I hope this helps the next person.
I am using Ion library to upload image to web server.But when ever i try to set the parameters using setMultipartParamter i am getting null values.Why this is happening.
Code
Ion.with(getActivity()).load("http://.......").setMultipartParameter("IUser_ID", "126").setMultipartParameter("&User_ID", "amody#gmail.com").setMultipartParameter("&FileTitle", strFileTitle).setMultipartParameter("&DT", strDocumentType).setMultipartFile("", new File(strFilePath)).asString().setCallback(new FutureCallback<String>() {
#Override
public void onCompleted(Exception e, String result) {
Log.e("Upload file response", "" + result);
}
});
I chaecked the server, the file is uploaded properly but the paramters are not.
You are passing in parameter names like they're query strings.
.setMultipartParameter("&User_ID", "amody#gmail.com")
You don't need the ampersand. Your server is likely looking at the wrong keys.
I'm trying to get the profile images of my followers for use within a ListView as thumbnails.
These thumbnails are around 125x125, but the standard twitter4j call of User.getProfileImageURL(); returns much smaller size of 48x48 and is also recommended to not be used as the image source.
I've tried creating a ProfileImage object and supplying it as a parameter, User.getProfileImageURL(profile image object.Original),
But this code takes some time to simply retrieve the url, which when loading a list of thumbnails, is inefficient.
Any suggestions on how to go about this?
Edit
Twitter API v1 has been disabled, so my old answer is no longer valid. Refer to API v1.1, which I believe requires authentication.
If you know the screen name, the twitter api allows for you to fetch the profile image at 4 different resolutions;
https://api.twitter.com/1/users/profile_image?screen_name=Krylez&size=mini
https://api.twitter.com/1/users/profile_image?screen_name=Krylez&size=normal
https://api.twitter.com/1/users/profile_image?screen_name=Krylez&size=bigger
https://api.twitter.com/1/users/profile_image?screen_name=Krylez&size=original
The "bigger" image is 73x73, which is going to interpolate in your 125x125 container. If you're not okay with this, you can try to fetch the "original" photo, but this photo could be very large (slow) and it's not necessarily a square.
Whatever method you choose, make sure you're not fetching and/or decoding Bitmaps on the UI thread. The Android API documentation has excellent guidelines for the correct way to do this.
Also we can make use of the Twitter4j using:
mTwitter.getUserProfileImage();
From the official doc:
You can obtain a user’s most recent profile image from GET users/show. Within the user object, you’ll find the profile_image_url
and profile_image_url_https fields. These fields will contain the
resized “normal” variant of the user’s uploaded image. This “normal”
variant is typically 48x48px.
By modifying the URL, you can retrieve other variant sizings such as
“bigger”, “mini”, and “original”.
Following the code:
TwitterApiClient twitterApiClient = TwitterCore.getInstance().getApiClient();
twitterApiClient.getAccountService().verifyCredentials(false, false, new Callback<User>() {
#Override
public void success(Result<User> userResult) {
String name = userResult.data.name;
String email = userResult.data.email;
// _normal (48x48px) | _bigger (73x73px) | _mini (24x24px)
String photoUrlNormalSize = userResult.data.profileImageUrl;
String photoUrlBiggerSize = userResult.data.profileImageUrl.replace("_normal", "_bigger");
String photoUrlMiniSize = userResult.data.profileImageUrl.replace("_normal", "_mini");
String photoUrlOriginalSize = userResult.data.profileImageUrl.replace("_normal", "");
}
#Override
public void failure(TwitterException exc) {
Log.d("TwitterKit", "Verify Credentials Failure", exc);
}
});
For further information refer to Twitter API Documentation | Profile Images and Banners
To create a custom size pic, for example 90x90 you can use the createScaledBitmap() method.
private final int PROFILE_PIC_SIZE = 90;
Bitmap originalPic = null;
Bitmap resizedPic = null;
try {
InputStream in = new java.net.URL(photoUrlOriginalSize).openStream();
originalPic = BitmapFactory.decodeStream(in);
resizedPic = Bitmap.createScaledBitmap(originalPic, PROFILE_PIC_SIZE, PROFILE_PIC_SIZE, false);
} catch (Exception exc) {
Log.e("Error", exc.getMessage());
exc.printStackTrace();
}
You can use getOriginalProfileImageURL() for example. This is as large as it gets.
Smaller ones are getBiggerProfileImageURL() and getProfileImageURL().
These are the urls you retrieve:
http://pbs.twimg.com/profile_images/NUMBER/c62p-cAD_normal.jpeg
http://pbs.twimg.com/profile_images/NUMBER/c62p-cAD_bigger.jpeg
http://pbs.twimg.com/profile_images/NUMBER/c62p-cAD.jpeg