AmazonSQSClientBuilder and AWSStaticCredentialsProvider with the Android SDK - android

I am attempting to implement message sending from my Android app using AWS SQS. I have included aws-android-sdk-core-2.6.15 and aws-android-sdk-sqs-2.6.15 jar files. With just these, I am unable to resolve AmazonSQSClientBuilder (import com.amazonaws.services.sqs.AmazonSQSClientBuilder) and AWSStaticCredentialsProvider (import com.amazonaws.auth.AWSStaticCredentialsProvider).
These work if I include the aws-java-sdk-1.11.278 jar file. However, this causes the 'DuplicateFileException' when I try to build. If I include only this jar, then I get the 'GC overhead limit exceeded' error.
Is there a smaller package that will allow the import of these necessary classes?
Thanks!

The AWS SDK for Android does not follow the same pattern as AWS SDK for Java.
The applicable constructors can be found in these files depending on whether you want an async client or not:
https://github.com/aws/aws-sdk-android/blob/master/aws-android-sdk-sqs/src/main/java/com/amazonaws/services/sqs/AmazonSQSAsyncClient.java
https://github.com/aws/aws-sdk-android/blob/master/aws-android-sdk-sqs/src/main/java/com/amazonaws/services/sqs/AmazonSQSClient.java
One example:
AWSCredentialsProvider awsCredentialsProvider = // Choose one of many classes that implement this for instance, CognitoCachingCredentialsProvider
AmazonSQSClient client = new AmazonSQSClient(awsCredentialsProvider);

Related

Visual Studio can't find extension methods Splat.BitmapMixins.FromNative() and Splat.BitmapMixins.ToNative() in Android app

While upgrading a Xamarin app that leverages Splat's bitmap functionality we are getting errors around the use of the methods mentioned in the title:
'IBitmap' does not contain a definition for 'ToNative' and no accessible extension method 'ToNative' accepting a first argument of type 'IBitmap' could be found (are you missing a using directive or an assembly reference?)
In an effort to troubleshoot the problem we have created a new sample Android-only Xamarin app and referenced Splat and Splat.Drawing via NuGet. We then added calls to these methods and have reproduced the error:
public void Bar(IBitmap source)
{
Bitmap native = source.ToNative();
IBitmap bitmap = native.FromNative();
}
It seems as though the Andriod app may not be referencing the proper build of the Splat libraries. When I monitor paths containing %USERPROFILE%\.nuget\packages\splat in ProcMon I don't see any attempt by Visual Studio to open/read anything other than files in the .\netstandard2.0 directories during the build process.
When I open the netstandard2.0 libraries in DotPeek I can see that the class BitmapMixins is not included, but it is included in the monoandroid90 builds.
How do I get the reference to Splat in the Android project to pull in the proper build of Splat?
Example project can be found here: https://github.com/jctlp/SplatBitmap
The error caused by that you did not have the extension methods to assist with dealing with Bitmaps of ToNative and FromNative.
Please do not add reference by installing the Splat from NuGet directly. Add reference to the whole project of Splat would be okay.
Download the whole Splat project from the link below.
https://github.com/reactiveui/splat.git
I create a Xamarin.forms app named App1. And create a class Class2.cs in App1.Android. When I add reference to Splat from the project. It works well with ToNative and FromNative extension method.
Please note: Do not use the Bitmap, use Android.Graphics.Drawables.Drawable or var instead.
public void Bar(IBitmap source)
{
Android.Graphics.Drawables.Drawable native = source.ToNative();//var
IBitmap bitmap = native.FromNative();
}

How to add Jgit to your Android project?

I have been trying to add Jgit to my android project for to execute remote push commands. i have tried ajgit and many others and none of them support "remote push".
I have tried including Jgit from source as a module. to encounter "Lambda expressions not supported in Android". gave that up and downloaded the latest jar library from official jgit site and added it as an external library and came across with the error below. which i suppose is a external dependency issue.
Please advice how i can include Jgit or any other library that would allow me to do "remote pushes" in to my android studio project so i can move on to the better part of my project. (using Maven or else.. what i need is a fast solution because my work is kind of halted due to this setback)
thank you in advance.
the code i would like to execute:
try{
String httpUrl = "https://github.com/repo/branch";
String localPath = "/sdcard/Folder1/folder2";
Log.d("GIT","1");
Repository localRepo = new FileRepository(localPath);
Log.d("GIT","2");
Git git = new Git(localRepo);
Log.d("GIT","3");
// add remote repo:
RemoteAddCommand remoteAddCommand = git.remoteAdd();
remoteAddCommand.setName("origin");
remoteAddCommand.setUri(new URIish(httpUrl));
// you can add more settings here if needed
remoteAddCommand.call();
// push to remote:
PushCommand pushCommand = git.push();
pushCommand.setCredentialsProvider(new UsernamePasswordCredentialsProvider("username", "password"));
// you can add more settings here if needed
pushCommand.call();
}catch (Exception ex){
imessage += "/n"+ex.getMessage();
}
which returns error at line ,
Repository localRepo = new FileRepository(localPath);
E/AndroidRuntime: FATAL EXCEPTION: Thread-4
Process: com.crimson.studio.Ruby.Ui, PID: 3847
java.lang.BootstrapMethodError: Exception from call site #145 bootstrap method
at org.eclipse.jgit.util.SystemReader.getOsName(SystemReader.java:372)
at org.eclipse.jgit.util.SystemReader.isWindows(SystemReader.java:350)
at org.eclipse.jgit.util.SystemReader.setPlatformChecker(SystemReader.java:197)
at org.eclipse.jgit.util.SystemReader.init(SystemReader.java:187)
at org.eclipse.jgit.util.SystemReader.<clinit>(SystemReader.java:83)
at org.eclipse.jgit.util.SystemReader.getInstance(SystemReader.java:160)
at org.eclipse.jgit.util.FS$FSFactory.detect(FS.java:131)
at org.eclipse.jgit.util.FS.detect(FS.java:306)
at org.eclipse.jgit.util.FS.detect(FS.java:279)
at org.eclipse.jgit.util.FS.<clinit>(FS.java:269)
at org.eclipse.jgit.lib.BaseRepositoryBuilder.setupWorkTree(BaseRepositoryBuilder.java:657)
at org.eclipse.jgit.lib.BaseRepositoryBuilder.setup(BaseRepositoryBuilder.java:589)
at org.eclipse.jgit.internal.storage.file.FileRepository.<init>(FileRepository.java:151)
at org.eclipse.jgit.internal.storage.file.FileRepository.<init>(FileRepository.java:165)
at com.crimson.studio.Ruby.VulkanActivity.showAlert(VulkanActivity.java:58)
Caused by: java.lang.ClassCastException: Bootstrap method returned null
at org.eclipse.jgit.util.SystemReader.getOsName(SystemReader.java:372) 
at org.eclipse.jgit.util.SystemReader.isWindows(SystemReader.java:350) 
at org.eclipse.jgit.util.SystemReader.setPlatformChecker(SystemReader.java:197) 
at org.eclipse.jgit.util.SystemReader.init(SystemReader.java:187) 
at org.eclipse.jgit.util.SystemReader.<clinit>(SystemReader.java:83) 
at org.eclipse.jgit.util.SystemReader.getInstance(SystemReader.java:160) 
at org.eclipse.jgit.util.FS$FSFactory.detect(FS.java:131) 
at org.eclipse.jgit.util.FS.detect(FS.java:306) 
at org.eclipse.jgit.util.FS.detect(FS.java:279) 
at org.eclipse.jgit.util.FS.<clinit>(FS.java:269) 
at org.eclipse.jgit.lib.BaseRepositoryBuilder.setupWorkTree(BaseRepositoryBuilder.java:657) 
at org.eclipse.jgit.lib.BaseRepositoryBuilder.setup(BaseRepositoryBuilder.java:589) 
at org.eclipse.jgit.internal.storage.file.FileRepository.<init>(FileRepository.java:151) 
at org.eclipse.jgit.internal.storage.file.FileRepository.<init>(FileRepository.java:165) 
at com.crimson.studio.Ruby.VulkanActivity.showAlert(VulkanActivity.java:58)
It seems JGit is not built for being used on Android and thus causes some deeper problem during startup.
There are some existing Git Client Apps for Android, see e.g. https://www.hongkiat.com/blog/guide-to-using-git-on-android/ and https://livablesoftware.com/mobile-apps-git-github-android-iphone/, but these provide a separate application for using Git on Android and not a library to include in your project.
I did only find https://github.com/rtyley/agit which provides source-code for using Git on Android, although it is unmaintained for some time, but you still might be able to extract a way of using Git in your application from it.

Module with ContentProvider

I'm ussing this library, the problem starts with:
Tray is based on a ContentProvider. A ContentProvider needs a unique
authority. When you use the same authority for multiple apps you will
be unable to install the app due to a authority conflict with the
error message:
Failure [INSTALL_FAILED_CONFLICTING_PROVIDER]
because i didn't read this before, i used this library to fix problems with multi thread SharedPreference, this project had to become in a module to use in multiple projects.
At the moment of installing every App with this Module, throws the Failure [INSTALL_FAILED_CONFLICTING_PROVIDER] exception.
Because authority is already used in the first installed app.
The questions are:
How can i skip installation of Module that is already installed? (Installing the rest of the app, so error will disapear)
else, How can i structure the projects? to be able to install multiple apps built with the Module that have the ContentProvider Library.
Fixed
For those that need something similar these are the steps to follow:
Step 1. I configured Tray Library in a Main Project "required for the rest of apps"
(the app that hosts database preferences)
Step 2. I extracted from repository the required classes to connect with the Tray ContentProvider, which are:
AbstractTrayPreference.java
ContentProviderStorage.java
ItemNotFoundException.java
Migration.java
OnTrayPreferenceChangeListener.java
PreferenceAccessor.java
Preferences.java
PreferenceStorage.java
SqliteHelper.java
TrayContract.java
TrayDBHelper.java
TrayException.java
TrayItem.java
TrayPreferences.java
TrayProviderHelper.java
TrayRuntimeException.java
TrayStorage.java
TrayUri.java
WrongTypeException.java
in a new package for the common Module.
Step 3. I hardcoded authority name via constant variable:
This must match with Main Project configuration:
// bild.gradle of Main Project
resValue "string", "tray__authority", "<your.app.package>.tray"
// TrayContract.java of Module
#NonNull
private static String getAuthority(#NonNull final Context context) {
return TextUtils.isEmpty(sTestAuthority) ?
AppConstant.TRAY_AUTHORITY: // <-- this one = <your.app.package>.tray
sTestAuthority;
}
Finally I can use the class normally:
// etc
import <your.app.package>.tray.TrayPreferences;
// etc
public class AppPreferencesManager extends TrayPreferences {
// etc
}
it worked :)

Generate Cloud Endpoint Client Library in Android Studio using Entity Class Design Pattern

While following the steps outlined here :
https://cloud.google.com/developers/articles/how-to-build-mobile-app-with-app-engine-backend-tutorial/
for creating a cloud endpoint, but using Android Studio instead of Eclipse, I am stuck at Step 9 of the Entity Class Design Pattern as described here :
https://cloud.google.com/developers/articles/how-to-build-mobile-app-with-app-engine-backend-tutorial/#ecdp
In Eclipse, there is a right-click-menu-option for "Generate Cloud Endpoint Client library" when you right-click on the app engine project. However, there is no equivalent option in Android Studio (v1.0.0)
Is this an omission on Google's part or am I missing something.
What is the best workaround for generating the cloud endpoint client library from within Android Studio.
Is there a way to do it from the command-line?
I did find the steps for gradle here :
https://cloud.google.com/appengine/docs/java/endpoints/endpoints_tool
and here :
https://cloud.google.com/appengine/docs/java/endpoints/consume_android
but these are much more time-consuming than the single-step process described in the original link for eclipse.
As stated above the libraries are auto-compiled for you, the other point to note that had me confused is where to get the Builder from.
Now as of Android Studio 1.0.1 the original Eclipse instructions are a little out of date for this as well, the "Builder" is no longer buried into the Endpoint class you make. Instead it is rolled into a separate API class to describe the Builder and associated code.
See: https://github.com/GoogleCloudPlatform/gradle-appengine-templates/tree/master/HelloEndpoints
Endpoint Usage from Android would now look like this:
/* OLD
MyEndpoint.Builder builder = ... */
MyApi.Builder builder = new MyApi.Builder(AndroidHttp.newCompatibleTransport(),
new AndroidJsonFactory(), null)
// options for running against local devappserver
// - 10.0.2.2 is localhost's IP address in Android emulator
// - turn off compression when running against local devappserver
.setRootUrl("http://10.0.2.2:8080/_ah/api/")
.setGoogleClientRequestInitializer(new GoogleClientRequestInitializer() {
#Override
public void initialize(AbstractGoogleClientRequest<?> abstractGoogleClientRequest) throws IOException {
abstractGoogleClientRequest.setDisableGZipContent(true);
}
});
We're working on updating that shopping kart sample to use Android Studio.
In the meantime the documentation for generating endpoints in AS can be found here https://cloud.google.com/tools/android-studio/
There is no 'Generate Cloud Endpoint Client Library' task anymore since it's not needed in the Android Studio workflow. Simply building the project will ensure that the client libraries are available to your android app.
Check out the docs for the appengine gradle plugin https://github.com/GoogleCloudPlatform/gradle-appengine-plugin if you want to be able to manually perform some of the endpoint client library steps from the command line using Gradle.
As Lucien Murray-Pitts explained, the Builder is not in the Endpoint class but in a auto-generated XXXXApi class.
Imagine your java bean is a class called Portfolio under package com.example.backend
You have to add the following import in the AsyncTask class:
import com.example.backend.portfolioApi.PortfolioApi;
and then you can do
PortfolioApi.Builder builder = new PortfolioApi.Builder(....

log4j support in Android

I am attempting to shoehorn an existing SDK onto an android device and one of the dependencies of said SDK is Apache log4j. I am able to load my test program onto the android emulator but when the log4j object "PropertySetter" is called the program fails with a verification exception. Is there a way to ameliorate this issue?
Actually using slf4j turned out a remarkably painless process for me, and it seems the common case, at least for libraries that use straightforward log4j features. You don't really need to swap slf4j in for log4j, only add two slf4j libraries to your project from http://www.slf4j.org/download.html:
-- the slf4j library for Android (currently slf4j-android-1.6.1-RC1.jar)
-- the log4j over slf4j (http://www.slf4j.org/legacy.html#log4j-over-slf4j) bridge.
The latter defines the core log4j classes used by typical implementations and bind them to the slf4j Android implementation. Once the libraries are added the code works.
I successfully got log4j working on android with a Socket Appender and Log4j Chainsaw. All code is located in this repository. Slf4j set up and working too. Be aware you have to configure it programmatically. You cannot use .properties or .xml files the parser wont work on android. Enjoy.
https://sourceforge.net/projects/log4j-android/
There is a new project, which enables log4j on android. Also using log4j over slf4j is possible. It also provides an appender for LogCat. See Logging in Android using Log4J.
The following example shows how to configure and use log4j in Android.
Configure the log4j system in Android
import org.apache.log4j.Level;
import android.os.Environment;
import de.mindpipe.android.logging.log4j.LogConfigurator;
/**
* Simply place a class like this in your Android applications classpath.
*/
public class ConfigureLog4J {
static {
final LogConfigurator logConfigurator = new LogConfigurator();
logConfigurator.setFileName(Environment.getExternalStorageDirectory() + "myapp.log");
logConfigurator.setRootLevel(Level.DEBUG);
// Set log level of a specific logger
logConfigurator.setLevel("org.apache", Level.ERROR);
logConfigurator.configure();
}
}
Logging in Android using log4j using slf4j API
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ExampleLog4JOverSLF4J {
private final Logger log = LoggerFactory.getLogger(ExampleLog4JOverSLF4J.class);
public void myMethod() {
log.info("This message should be seen in log file and logcat");
}
}
Logging in Android using log4j API
import org.apache.log4j.Logger;
public class ExampleLog4J {
private final Logger log = Logger.getLogger(LogConfiguratorTest.class);
public void myMethod() {
log.info("This message should be seen in log file and logcat");
}
}
I would recommend trying to swap in slf4j in place of log4j. It's not a painless switch but its likely to be easier than what you have. slf4j provides a common front-end for several loggers including log4j and there is an slf4j-android package.
No, Android's logging mechanism is not decent. It's very inadequate compared to what log4j can do for you.
The parser for log4j configuration files is not android safe.slf4j's android compatibility thing with log4j just overrides the log4j classes you will use and forces them to use android logcat style logging. You still don't get the full flexibility of log4j on android. I ported log4j on android in my project https://sourceforge.net/projects/log4j-android/ all you have to do is add the two jars in the binaries directory to you classpath. Then
static {
org.apache.log4j.Logger root = org.apache.log4j.Logger.getRootLogger();
final SocketAppender appender = new SocketAppender("192.168.1.4", 4445);
root.addAppender(appender);
}
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(MyClass.class);
static {
logger.info("Hello logger");
}
This will start sending out messages to the remote host you specified. You can then see this messages with Chainsaw http://logging.apache.org/log4j/docs/webstart/chainsaw/chainsawWebStart.jnlp. To make chainsaw work click the second check box on the dialog that pops up hit ok, start your app and a new tab should appear. Be aware your firewall might block it...
Check out this project for a complete implementation: http://code.google.com/p/log4j-android/

Categories

Resources