I am trying to create note in a shared notebook which is already shared with me. The notebook is shared with me with priveleges to modify its contents (SharedNotebookPrivilegeLevel.MODIFY_NOTEBOOK_PLUS_ACTIVITY), and I can create notes in that notebook using Evernote web client. But when I trying to create a note using SDK I received an EDAMUserException(errorCode:PERMISSION_DENIED, parameter:authenticationToken). Below is my code
Note note = new Note();
note.setContent(EvernoteUtil.NOTE_PREFIX + content + EvernoteUtil.NOTE_SUFFIX);
note.setTitle(title);
EvernoteSession evernoteSession = EvernoteSession.getInstance();
List<LinkedNotebook> linkedNotebooks = evernoteSession
.getEvernoteClientFactory()
.getNoteStoreClient()
.listLinkedNotebooks();
LinkedNotebook current = null;
for (LinkedNotebook linkedNotebook : linkedNotebooks) {
if (linkedNotebook.getShareName().equals(notebookName)) {
current = linkedNotebook;
}
}
if (current == null)
throw new IllegalStateException();
THttpClient tHttpClient = new THttpClient(current.getNoteStoreUrl());
TBinaryProtocol tBinaryProtocol = new TBinaryProtocol(tHttpClient);
NoteStore.Client client = new NoteStore.Client(tBinaryProtocol, tBinaryProtocol);
AuthenticationResult authenticationResult = client.authenticateToSharedNotebook(current.getShareKey(),
evernoteSession.getAuthToken());
String shareToken = authenticationResult.getAuthenticationToken();
SharedNotebook sharedNotebook = client.getSharedNotebookByAuth(shareToken);
String sharedNotebookGuid = sharedNotebook.getNotebookGuid();
note.setGuid(sharedNotebookGuid);
Note createdNote = client.createNote(shareToken, note);
return createdNote;
I've used this article to create notes.
One mistake I found is that
note.setGuid(sharedNotebookGuid);
has to be
note.setNotebookGuid(sharedNotebookGuid);
Related
I am trying to add a 802.1x network programmatically in my Android app.
On an Android 8 device using addNetwork I see that the network is added with credentials but on Android 10 and above, when using addNetworkSuggestions, the credentials are not added.
I am new in this field so it is possible I am missing something vital.
WifiConfiguration wifiConf = new WifiConfiguration();
wifiConf.allowedAuthAlgorithms.clear();
wifiConf.allowedGroupCiphers.clear();
wifiConf.allowedKeyManagement.clear();
wifiConf.allowedPairwiseCiphers.clear();
wifiConf.allowedProtocols.clear();
wifiConf.SSID = TextUtil.convertToQuotedString(apSsid.toString());
wifiConf.enterpriseConfig = eapConfig.asWifiEnterpriseConfig();
wifiConf.enterpriseConfig.setIdentity(......);
wifiConf.enterpriseConfig.setPassword(......);
wifiConf.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.PEAP);
wifiConf.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.NONE);
wifiConf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
wifiConf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
wifiConfig.status = WifiConfiguration.Status.ENABLED;
wifiConfig.allowedKeyManagement.set(KeyMgmt.WPA_EAP);
wifiConfig.allowedKeyManagement.set(KeyMgmt.IEEE8021X);
wifiConf.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
wifiConf.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
wifiConf.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
wifiConf.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
if (apPass.length() == 64 && WeFiUtilExt.isHex(apPass)) {
// Goes unquoted as hex
wifiConf.preSharedKey = apPass;
}
else {
// Goes quoted as ASCII
wifiConf.preSharedKey = TextUtil.convertToQuotedString(apPass);
}
WifiNetworkSuggestion.Builder wpa2WifiNetworkSuggestionBuilder = new WifiNetworkSuggestion.Builder();
wpa2WifiNetworkSuggestionBuilder.setSsid(ssid).setIsAppInteractionRequired(true);
wpa2WifiNetworkSuggestionBuilder.setWpa2EnterpriseConfig(wifiEnterpriseConfig);
WifiNetworkSuggestion wpa2WifiNetworkSuggestion = wpa2WifiNetworkSuggestionBuilder.build();
WifiNetworkSuggestion.Builder wpa3WifiNetworkSuggestionBuilder = new WifiNetworkSuggestion.Builder();
wpa3WifiNetworkSuggestionBuilder.setSsid(ssid).setIsAppInteractionRequired(false);
wpa3WifiNetworkSuggestionBuilder.setWpa3EnterpriseConfig(wifiEnterpriseConfig);
WifiNetworkSuggestion wpa3WifiNetworkSuggestion = wpa3WifiNetworkSuggestionBuilder.build();
List<WifiNetworkSuggestion> wifiNetworkSuggestionList = new ArrayList<>();
wifiNetworkSuggestionList.add(wpa2WifiNetworkSuggestion);
wifiNetworkSuggestionList.add(wpa3WifiNetworkSuggestion);
int addStatus = m_wifiMngr.addNetworkSuggestions(wifiNetworkSuggestionList);
The return code is 0 implying that the add worked.
Will this not work in Android 10+?
So I have been working on a product (Android First and then iOS) for a long time that index faces of people using AWS Rekognition and when they are again scanned later, it identifies them.
It's working great when I index a face from an Android device and then try to search it with an Android device. But if I try to search it later on iOS app, it doesn't find it. Same is the result if I go other way round. Index with iOS, search with Android, not found.
The collection ID is same while indexing and searching on both devices. I couldn't figure out how is it possible that a face indexed by one OS type, same region, same collection, couldn't be found while on other device.
If anyone here could try and help me with the issue, please do. I'll be really thankful.
Update 1: I have called "listCollections" function on both iOS and android apps. Both of them are showing different list of collections. This is the issue. But I can't figure our why it is happening. The identity pool and region is same on both of them.
Here is my Android Code to access Rekognition:
mCredentialsProvider = new CognitoCachingCredentialsProvider(
mContext,
"us-east-2:xbxfxexf-x5x5-xax7-x9xf-x5x0xexfx1xb", // Identity pool ID
Regions.US_EAST_2 // Region
);
mUUID = UUID.randomUUID().toString().replace("-", "");
mAmazonS3Client = new AmazonS3Client(mCredentialsProvider);
mAmazonS3Client.setRegion(Region.getRegion(Regions.US_EAST_2));
mAmazonRekognitionClient = new AmazonRekognitionClient(mCredentialsProvider);
if(!mAmazonS3Client.doesBucketExist(mFacesBucket)) {
mAmazonS3Client.createBucket(mFacesBucket);
}
Log.i(TAG, "Uploading image to S3 Bucket");
mAmazonS3Client.putObject(mFacesBucket, getS3ObjectName(), new File(data[0].toString()));
Log.i(TAG, "Image Uploaded");
Image image = new Image();
try {
image.setBytes(ByteBuffer.wrap(Files.toByteArray(new File(data[0].toString()))));
} catch (IOException e) {
e.printStackTrace();
}
Log.i(TAG, "Indexing image");
IndexFacesRequest indexFacesRequest =new IndexFacesRequest()
.withCollectionId(mFacesCollection)
.withImage(image)
.withExternalImageId(mUUID)
.withDetectionAttributes("ALL");
mAmazonRekognitionClient.indexFaces(indexFacesRequest);
Here is my iOS code to access Rekognition:
func uploadToCollection(img: UIImage)
{
let myIdentityPoolId="us-east-2:xbxfxexf-x5x5-xax7-x9xf-x5x0xexfx1xb"
let credentialsProvider = AWSCognitoCredentialsProvider(regionType: .USEast2, identityPoolId: myIdentityPoolId)
//store photo in s3()
let configuration = AWSServiceConfiguration(region: .USEast2, credentialsProvider: credentialsProvider)
AWSServiceManager.default().defaultServiceConfiguration = configuration
rekognitionClient = AWSRekognition.default()
guard let request = AWSRekognitionIndexFacesRequest() else
{
puts("Unable to initialize AWSRekognitionindexFaceRequest.")
return
}
var go=false
request.collectionId = "i_faces" + self.firebaseID.lowercased() //here iosCollection will be replaced by firebase Current UserID
request.detectionAttributes = ["ALL", "DEFAULT"]
request.externalImageId = self.UUID //this should be mUUID, passed as parameter to this function
let sourceImage = img
let image = AWSRekognitionImage()
image!.bytes = sourceImage.jpegData(compressionQuality: 0.7)
request.image = image
self.rekognitionClient.indexFaces(request) { (response:AWSRekognitionIndexFacesResponse?, error:Error?) in
if error == nil
{
print("Upload to Collection Complete")
}
go=true
return
}
while(go==false){}
}
Create a collection and added images to the collection and create an index. I suspect few things in your setup and code.
1) The Identity Pool Id, AWS Region used across iOS and Android
2) The name of the collection used (pay attention to the delimiters used in the collection name)
Android:
CognitoCachingCredentialsProvider credentialsProvider = new CognitoCachingCredentialsProvider(appContext, "MyPoolID", Regions.US_EAST_1);
public void searchFacesByImage() {
Image source = new Image().withS3Object(new S3Object().withBucket("us-east-1-bucket").withName("ms.jpg"));
Image ms2 = new Image().withS3Object(new S3Object().withBucket("us-east-1-bucket").withName("ms-2.jpg"));
Image ms3 = new Image().withS3Object(new S3Object().withBucket("us-east-1-bucket").withName("ms-3.jpg"));
Image ms4 = new Image().withS3Object(new S3Object().withBucket("us-east-1-bucket").withName("ms-4.jpg"));
String collectionId = "MyCollectionID";
AmazonRekognitionClient client = new AmazonRekognitionClient(credentialsProvider);
try {
System.out.println("Creating collection: " + collectionId );
CreateCollectionRequest request = new CreateCollectionRequest().withCollectionId(collectionId);
CreateCollectionResult createCollectionResult = client.createCollection(request);
System.out.println("CollectionArn : " + createCollectionResult.getCollectionArn());
System.out.println("Status code : " + createCollectionResult.getStatusCode().toString());
} catch (Exception ex) {
ex.printStackTrace();
}
IndexFacesRequest indexFacesRequest = new IndexFacesRequest();
indexFacesRequest.setImage(source);
indexFacesRequest.setCollectionId(collectionId);
client.indexFaces(indexFacesRequest);
indexFacesRequest = new IndexFacesRequest();
indexFacesRequest.setImage(ms2);
indexFacesRequest.setCollectionId(collectionId);
client.indexFaces(indexFacesRequest);
indexFacesRequest = new IndexFacesRequest();
indexFacesRequest.setImage(ms4);
indexFacesRequest.setCollectionId(collectionId);
client.indexFaces(indexFacesRequest);
SearchFacesByImageRequest searchFacesByImageRequest = new SearchFacesByImageRequest();
searchFacesByImageRequest
.withCollectionId(collectionId)
.withImage(ms3)
.withFaceMatchThreshold(80F);
SearchFacesByImageResult searchFacesByImageResult =
client.searchFacesByImage(searchFacesByImageRequest);
List <FaceMatch> faceImageMatches = searchFacesByImageResult.getFaceMatches();
for (FaceMatch face: faceImageMatches) {
Log.d(TAG, face.toString());
}
}
iOS:
Create the Cognito Credentials Provider
AWSCognitoCredentialsProvider *credentialsProvider = [[AWSCognitoCredentialsProvider alloc] initWithRegionType:AWSRegionUSEast1 identityPoolId: #"MyPoolID"];
AWSServiceConfiguration *configuration = [[AWSServiceConfiguration alloc] initWithRegion:AWSRegionUSEast1 credentialsProvider:credentialsProvider];
[AWSServiceManager defaultServiceManager].defaultServiceConfiguration = configuration;
Use the same Identity Pool Id and Region (us-east-1).
func faceIndexNoFacesSearch() {
let rekognition = AWSRekognition.default()
let faceRequest = AWSRekognitionSearchFacesByImageRequest()
do {
let image = AWSRekognitionImage()
image?.s3Object = AWSRekognitionS3Object()
image?.s3Object?.bucket = "us-east-1-bucket"
image?.s3Object?.name = "ms-2.jpg"
faceRequest!.image = image
faceRequest!.collectionId = "MyCollectionID"
rekognition.searchFaces(byImage: faceRequest!).continueWith { (response) -> Any? in
XCTAssertNil(response.error)
XCTAssertNotNil(response.result)
if let result = response.result {
XCTAssertNotNil(result.faceMatches)
}
return nil
}.waitUntilFinished()
} catch {
print("exception")
}
}
Please post questions in the comment and we can discuss there.
Ok so the problem turned out to be much different and solution was rather very simple. I posted another question regarding the same problem when I found it was a bit different and I have posted an answer as well.
Here it is:
https://stackoverflow.com/a/53128777/4395264
If we update an activity after retrieving from stream, we are able to update
String feedId = "ef202000-3f6b-11e7-8080-800171e94936";
Feed feed = StreamUtils.getStreamClient().newFeed(Constants.FEED_SLUG, "feed_66_103");
NotificationActivityServiceImpl<MessageItem> userMessagesActivityService = feed.newNotificationActivityService(MessageItem.class);
FeedFilter filter = new FeedFilter.Builder().withIdGreaterThanEquals(feedId).withLimit(1).build();
StreamResponse<NotificationActivity<MessageItem>> userMessageItems = userMessagesActivityService.getActivities(filter, false, false);
if (userMessageItems != null && userMessageItems.getResults().size() != 0) {
for (NotificationActivity<MessageItem> messageItemNotificationActivity : userMessageItems.getResults()) {
for (MessageItem messageItem : messageItemNotificationActivity.getActivities()) {
messageItem.setMessage_status(MESSAGE_STATUS_READ);
userMessagesActivityService.updateActivities(Collections.singletonList(messageItem));
Log.d("Message json", new Gson().toJson(messageItem));
}
}
}
But, If we update it by constructing the activity, we are unable to update
Feed feed = StreamUtils.getStreamClient().newFeed(Constants.FEED_SLUG, "chat_66_103");
String messageJson = "{\"channel_id\":\"feed_66_103\",\"message\":{\"message_text\":\"Test message\"},\"message_status\":\"DELIVERED\",\"receivers\":[103],\"actor\":\"66\",\"foreignId\":\"66_103_1495511846405\",\"id\":\"ef202000-3f6b-11e7-8080-800171e94936\",\"object\":\"delivery_message\",\"time\":\"May 23, 2017 9:27:26 AM\",\"to\":[],\"verb\":\"delivery_message\"}";
MessageItem messageItem = new Gson().fromJson(messageJson, MessageItem.class);
messageItem.setMessage_status(MESSAGE_STATUS_READ);
NotificationActivityServiceImpl<MessageItem> userMessagesActivityService = feed.newNotificationActivityService(MessageItem.class);
userMessagesActivityService.updateActivities(Collections.singletonList(messageItem));
Log.d("Message json", new Gson().toJson(messageItem));
In the setMessage_status method, I'm changing values of variables object, verb, message_status
Here even the logs printing the same object. We don't know what we are missing.
We tried it from python client as well. Same issue there as well.
Updating activities is done using your foreign ID. Currently your payload is sending this value in a field called foreignId and our endpoint will be expecting foreign_id.
I am trying to load an object at run time from downloaded assetbundle in android local storage but no result is found. Though the assetbundle exists in local storage of my android device.
Please somebody help me to do so, following is the code which I have written:
public GameObject obj;
IEnumerable LoadObject()
{
AssetBundle bundle = AssetBundle.CreateFromFile(Application.persistentDataPath + "/androidassetbundle4");
yield return bundle;
AssetBundleRequest request = bundle.LoadAssetAsync("boat", typeof(GameObject));
yield return request;
obj = request.asset as GameObject;
obj.transform.position = new Vector3(0.08f, -2.345f, 297.54f);
obj.transform.Rotate(350.41f,400f,20f);
obj.transform.localScale = new Vector3(1.0518f, 0.998f, 1.1793f);
Instantiate(obj);
bundle.Unload(false);
}//end of Method LoadObject
CreateFromFile is deprecated. LoadFromFile and LoadFromFileAsync are the new functions to use. Not sure if that is the problem but the code below should do it.
IEnumerator LoadObject()
{
AssetBundleCreateRequest bundle = AssetBundle.LoadFromFileAsync(System.IO.Path.Combine(Application.streamingAssetsPath, "assetbundlename"));
yield return bundle;
AssetBundle myLoadedAssetBundle = bundle.assetBundle;
if (myLoadedAssetBundle == null)
{
Debug.Log("Failed to load AssetBundle!");
yield break;
}
AssetBundleRequest request = myLoadedAssetBundle.LoadAssetAsync<GameObject>("boat");
yield return request;
obj = request.asset as GameObject;
obj.transform.position = new Vector3(0.08f, -2.345f, 297.54f);
obj.transform.Rotate(350.41f, 400f, 20f);
obj.transform.localScale = new Vector3(1.0518f, 0.998f, 1.1793f);
Instantiate(obj);
myLoadedAssetBundle.Unload(false);
}
you can't access file in local storage via CreateFromFile or LoadFromFile in android,instead use LoadFromCacheOrDownload and in android this is the address of your StreamingAssets : "jar:file://" + Application.dataPath + "!/assets/"
as mentioned in unity docs : StreamingAssets
I am wondering how to adjust the standard user agent in my http requests. I am using the Volley library and I KNOW how to
set a new user agent
retrieve the default user agent as a string (e.g. "Dalvik/1.6.0 (Linux; U; Android 4.0.2; sdk Build/ICS_MR0") => System.getProperty("http.agent")
What I DON'T know is:
how to get the single elements this user agent is build of, so I can replace only the string "Dalvik/1.6.0" with a custom string.
Is that possible, or do I have to make a string replacement?
Thx
In order to set the user agent globally for all requests sent via volley, here is my solution:
When you are initializing the volley request queue, instead of using the convenient method Volley.newRequestQueue(Context);, use the following snippet:
private RequestQueue makeRequestQueue(Context context) {
DiskBasedCache cache = new DiskBasedCache(new File(context.getCacheDir(), DEFAULT_CACHE_DIR), DISK_CACHE_SIZE);
BasicNetwork network = new BasicNetwork(new MyHurlStack());
RequestQueue queue = new RequestQueue(cache, network);
queue.start();
return queue;
}
public static class MyHurlStack extends HurlStack {
#Override
public HttpResponse executeRequest(Request<?> request, Map<String, String> additionalHeaders) throws IOException, AuthFailureError {
if (additionalHeaders == null || Collections.emptyMap().equals(additionalHeaders) {
additionalHeaders = new HashMap<>();
}
additionalHeaders.put("User-Agent", "test_user_agent_in_volley");
return super.executeRequest(request, additionalHeaders);
}
}
This solution assumes you are targeting api level >= 9, so we use the HurlStack
The reason why this works is because in HurlStack.executeRequest(Request<?> request, Map<String, String> additionalHeaders) method, the stuff you add to the additionalHeaders would later be added to an HttpUrlConnection request property as in connection.addRequestProperty(headerName, map.get(headerName));
Yes,
Build.FINGERPRINT contains all the information you need,
https://developer.android.com/reference/android/os/Build.html
To get the individual parts, use the individual constant strings,
For detailed OS Version information use Build.VERSION
import android.util.Log;
import android.os.Bundle;
import android.os.Build;
public class MainActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i("Build","BOARD = "+Build.BOARD);
Log.i("Build","BOOTLOADER = "+Build.BOOTLOADER);
Log.i("Build","BRAND = "+Build.BRAND);
Log.i("Build","CPU_ABI = "+Build.CPU_ABI);
Log.i("Build","CPU_ABI2 = "+Build.CPU_ABI2);
Log.i("Build","DEVICE = "+Build.DEVICE);
Log.i("Build","DISPLAY = "+Build.DISPLAY);
Log.i("Build","FINGERPRINT = "+Build.FINGERPRINT);
Log.i("Build","HARDWARE = "+Build.HARDWARE);
Log.i("Build","HOST = "+Build.HOST);
Log.i("Build","ID = "+Build.ID);
Log.i("Build","MANUFACTURER = "+Build.MANUFACTURER);
Log.i("Build","MODEL = "+Build.MODEL);
Log.i("Build","PRODUCT = "+Build.PRODUCT);
Log.i("Build","RADIO = "+Build.RADIO);
Log.i("Build","SERIAL = "+Build.SERIAL);
Log.i("Build","TAGS = "+Build.TAGS);
Log.i("Build","TYPE = "+Build.TYPE);
Log.i("Build","USER = "+Build.USER);
Log.i("Build","BASE_OS = "+Build.VERSION.BASE_OS);
Log.i("Build","CODENAME = "+ Build.VERSION.CODENAME);
Log.i("Build","INCREMENTAL = "+ Build.VERSION.INCREMENTAL);
Log.i("Build","RELEASE = "+ Build.VERSION.RELEASE);
Log.i("Build","SDK = "+ Build.VERSION.SDK);
Log.i("Build","SECURITY_PATCH = "+ Build.VERSION.SECURITY_PATCH);
Log.i("$TAG#",Build.FINGERPRINT);
}
}
System.getProperty("http.agent") returns something like:
Dalvik/2.1.0 (Linux; U; Android 9; Android SDK built for x86 Build/PSR1.180720.075)
It's possible to build all the parts of this using a combination of android.os.Build and java.lang.System.getProperty().
This is an example of what's in android.os.Build running on an emulator:
Build.BOARD = "goldfish_x86"
Build.BOOTLOADER = "unknown"
Build.BRAND = "google"
Build.DEVICE = "generic_x86"
Build.DISPLAY = "sdk_gphone_x86-userdebug 9 PSR1.180720.075 5124027 dev-keys"
Build.FINGERPRINT = "google/sdk_gphone_x86/generic_x86:9/PSR1.180720.075/5124027:userdebug/dev-keys"
Build.HARDWARE = "ranchu"
Build.HOST = "abfarm904"
Build.ID = "PSR1.180720.075"
Build.MANUFACTURER = "Google"
Build.MODEL = "Android SDK built for x86"
Build.PRODUCT = "sdk_gphone_x86"
Build.SUPPORTED_32_BIT_ABIS = {"x86"}
Build.SUPPORTED_64_BIT_ABIS = {}
Build.SUPPORTED_ABIS = {"x86"}
Build.TAGS = "dev-keys"
Build.TIME = 1541887073000
Build.TYPE = "userdebug"
Build.USER = "android-build"
Build.UNKNOWN = "unknown"
Build.VERSION.BASE_OS = ""
Build.VERSION.CODENAME = "REL"
Build.VERSION.INCREMENTAL = "5124027"
Build.VERSION.PREVIEW_SDK_INT = 0
Build.VERSION.RELEASE = "9"
Build.VERSION.SDK_INT = 28
Build.VERSION.SECURITY_PATCH = "2018-09-05"
These properties are always provided by the Dalvik VM, according to Google's documentation:
file.separator = /
java.class.path = .
java.class.version = 50.0
java.compiler = Empty
java.ext.dirs = Empty
java.home = /system
java.io.tmpdir = /sdcard
java.library.path = /vendor/lib:/system/lib
java.vendor = The Android Project
java.vendor.url = http://www.android.com/
java.version = 0
java.specification.version = 0.9
java.specification.vendor = The Android Project
java.specification.name = Dalvik Core Library
java.vm.version = 1.2.0
java.vm.vendor = The Android Project
java.vm.name = Dalvik
java.vm.specification.version = 0.9
java.vm.specification.vendor = The Android Project
java.vm.specification.name = Dalvik Virtual Machine Specification
line.separator = \n
os.arch = armv7l
os.name = Linux
os.version = 2.6.32.9-g103d848
path.separator = :
user.dir = /
user.home = Empty
user.name = Empty
So, the default user agent appears to be composed of:
System.getProperty("java.vm.name") // Dalvik
System.getProperty("java.vm.version") // 2.1.0
System.getProperty("os.name") // Linux
"U" // not sure where to get this
"Android" // or this, probably safe to hard code though
Build.VERSION.RELEASE // 9
Build.MODEL // Android SDK built for x86
Build.ID // PSR1.180720.075