I'm very new to writing unit tests in Android.
I have a singleton class as follows
public enum DownloadController {
INSTANCE;
private AsyncTask<?, ?, ?> mRunningTask;
/*
* #param LoginListener
* Request for getting full name of an user.
* */
public void getTrackName(DownloadListener listener){
if(mRunningTask != null) mRunningTask.cancel(true);
mListener = listener;
mRunningTask = new DownloadTask();
try {
mRunningTask.execute();
}catch (Exception e){
e.getLocalizedMessage();
}
}
//Task which gets us the full name of an user
public class DownloadTask extends AsyncTask<Void, Void, String> {
#Override
public String doInBackground(Void... params) {
String trackName;
try {
trackName = getTrackName();
} catch (VolleyError | AuthException volleyError) {
trackName = "error"
}
return trackName;
}
#Override
public void onPostExecute(String name) {
if (mListener != null) {
mListener.onNameObtained(name);
}
}
}
}
For this I have a Test class as follows
#RunWith(PowerMockRunner.class)
#PrepareForTest({DownloadController.class})
#Config(constants = BuildConfig.class, emulateSdk = 19, manifest="src/main/AndroidManifest.xml")
public class DownloadControllerTest {
DownloadController mSubject;
String mTrackName;
#Before
public void setUp() {
mSubject = DownloadController.INSTANCE;
}
#Test
public void getTrackName_test() throws InterruptedException, AuthException, VolleyError {
// execute
final DownloadCallback callback = new DownloadCallback();
mSubject.getTrackName(callback);
callback.blockForResult();
// verify
assertThat(callback.mTrackName, is("Track1"));
}
private class DownloadCallback implements DownloadListener {
CountDownLatch mLatch = new CountDownLatch(1);
String mFullname;
#Override
public void onNameObtained(String fullName) {
mFullname = fullName;
mLatch.countDown();
}
public void blockForResult() throws InterruptedException {
mLatch.await();
}
}
}
Here mSubject.getTrackName(callback); calls the method getTrackName() in DownloadManager.java but new DownloadTask().execute(); is not invoking doInBackground() method in asynTask. This leads test case is in infinite loop.
I think you have to call in your test Robolectric.flushBackgroundThreadScheduler() to execute your asynctask
Related
Please tell me why my program ends immediately after launch. It's a Java Telegram Bot running on my home PC. I created the project using Maven.
MainClass
public class MainClass extends TelegramWebhookBot {
BootConfig cfg = new BootConfig();
public static void main(String[] args) {
ApiContextInitializer.init();
TelegramBotsApi telegramBotsApi = new TelegramBotsApi();
try {
telegramBotsApi.registerBot(new MainClass());
} catch (TelegramApiException ex) {
ex.printStackTrace();
}
}
#Override
public BotApiMethod onWebhookUpdateReceived(Update update) {
if (update.hasMessage() && update.getMessage().hasText()) {
SendMessage sendMessage = new SendMessage();
sendMessage.setChatId(update.getMessage().getChatId().toString());
sendMessage.setText("Well, all information looks like noise until you break the code.");
return sendMessage;
}
return null;
}
#Override
public String getBotUsername() {
return cfg.WEBHOOK_USER;
}
#Override
public String getBotToken() {
return cfg.WEBHOOK_TOKEN;
}
#Override
public String getBotPath() {
return cfg.WEBHOOK_USER;
}
}
BootConfig class:
public class BootConfig {
public static final String WEBHOOK_TOKEN = "SECRET";
public static final String WEBHOOK_USER = "archopobbkbot";
Console output:
Process finished with exit code 0
I have a function searchForTrips() which sends an API request and fetch some response in following way.
private void searchForTrips(){
int departurePortId = PORT_ID_LIST.get(departurePort);
int returnPortId = PORT_ID_LIST.get(returnPort);
int pax= Integer.parseInt(noOfPassengers);
String departureDatePARSED = DEPARTURE_DATE_VALUES.get(departureDate);
String returnDatePARSED = RETURN_DATE_VALUES.get(departureDate);
Call<TripSearchResponse> call = apiService.searchAvailableTrips(TripType,departurePortId,returnPortId,departureDatePARSED,returnDatePARSED,pax);
call.enqueue(new Callback<TripSearchResponse>() {
#Override
public void onResponse(Call<TripSearchResponse> call, Response<TripSearchResponse> response) {
int statusCode = response.code();
switch(statusCode){
case 200:
default:
Snackbar.make(findViewById(android.R.id.content),"Error loading data. Network Error.", Snackbar.LENGTH_LONG).show();
break;
}
}
#Override
public void onFailure(Call<TripSearchResponse> call, Throwable t) {
Log.i(TAG, t.getMessage());
Snackbar.make(findViewById(android.R.id.content),"Error loading data. Network Error.", Snackbar.LENGTH_LONG).show();
}
});
}
The purpose is to make this callback function reusable so I can call it from several activities and get requested data as I need. What is the best way to implement this?
try this way, its dynamic way and easy to use:
Create Retforit Interface:
public interface ApiEndpointInterface {
#Headers("Content-Type: application/json")
#POST(Constants.SERVICE_SEARCH_TRIP)
Call<JsonObject> searchForTrip(#Body TripRequest objTripRequest);
}
Create Retrofit Class:
public class AppEndPoint {
private static Retrofit objRetrofit;
public static ApiEndpointInterface getClient() {
if (objRetrofit == null){
objRetrofit = new Retrofit.Builder()
.baseUrl(Constants.SERVER_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return objRetrofit.create(ApiEndpointInterface.class);
}
}
Create this helper Classes/Interfaces to hold web service callback:
public enum ResponseState {
SUCCESS,
FAILURE,
NO_CONNECTION
}
public enum RequestType {
SEARCH_FOR_TRIP // add name for each web service
}
public class Response {
public ResponseState state;
public boolean hasError;
public RequestType requestType;
public JsonObject result;
}
public interface RestRequestInterface {
void Response(Response response);
Context getContext();
}
public class ResponseHolder { used to hold the Json response could be changed as your response
#SerializedName("is_successful")
#Expose
private boolean isSuccessful;
#SerializedName("error_message")
#Expose
private String errorMessage;
public boolean isSuccessful() {
return isSuccessful;
}
public void setSuccessful(boolean successful) {
isSuccessful = successful;
}
public String getErrorMessage() {
return errorMessage;
}
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
}
public class AppClient {
private static ApiEndpointInterface objApiEndpointInterface;
private static Response objResponse;
private static Call<JsonObject> objCall;
// implement new method like below for each new web service
public static void searchForTrip(TripRequest objTripRequest, RestRequestInterface objRestRequestInterface) {
objResponse = new Response();
objResponse.state = ResponseState.FAILURE;
objResponse.hasError = true;
objResponse.requestType = RequestType.SEARCH_FOR_TRIP; // set type of the service from helper interface
objApiEndpointInterface = AppEndPoint.getClient();
objCall = objApiEndpointInterface.searchForTrip(objTripRequest);
handleCallBack(objRestRequestInterface);
}
private static void handleCallBack(final RestRequestInterface objRestRequestInterface) {
objCall.enqueue(new Callback<JsonObject>() {
#Override
public void onResponse(Call<JsonObject> call, retrofit2.Response<JsonObject> response) {
try {
ResponseHolder objResponseHolder = new Gson().fromJson(response.body(), ResponseHolder.class);
if (objResponseHolder.isSuccessful()) {
objResponse.state = ResponseState.SUCCESS;
objResponse.hasError = false;
objResponse.result = response.body();
} else {
objResponse.errorMessage = objResponseHolder.getErrorMessage();
}
objRestRequestInterface.Response(objResponse);
} catch (Exception objException) {
objResponse.errorMessage = objRestRequestInterface.getContext().getString(R.string.server_error);
objRestRequestInterface.Response(objResponse);
}
}
#Override
public void onFailure(Call<JsonObject> call, Throwable objThrowable) {
String errorMessage = "";
if (objThrowable instanceof IOException) {
errorMessage = objRestRequestInterface.getContext().getString(R.string.no_connection_error);
} else {
errorMessage = objRestRequestInterface.getContext().getString(R.string.server_error);
}
objResponse.errorMessage = errorMessage;
objRestRequestInterface.Response(objResponse);
}
});
}
}
then go to your activity of fragment and make the call like this:
public class MainActivity extends AppCompatActivity implements RestRequestInterface {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// initialize ids
// prepare to call web service
// 1.Initialize your object to be sent over web service
TripRequest objTripRequest = new TripRequest();
objTripRequest.id = 1;
// 2.Show loader
// 3.Make the call
AppClient.searchForTrip(objTripRequest, this);
}
#Override
public void Response(Response response) {
// hide loader
try {
if (response.state == ResponseState.SUCCESS && !response.hasError) {
// check the type of web service
if (response.requestType == RequestType.SEARCH_FOR_TRIP) {
// acces the return here from response.result
}
} else {
String errorMsg = response.hasError ? response.errorMessage : getString(R.string.no_connection_error);
// show the error to the user
}
} catch (Exception objException) {
// show the error to the user
}
}
#Override
public Context getContext() {
// do not forgit set the context here
// if fragment replace with getAcitvity();
return this;
}
}
I am using the amazonaws S3 for uploading the media file getting the following error like below:-
E/UploadTask: Failed to upload: 15 due to Forbidden (Service: Amazon S3; Status Code: 403; Error Code: 403 Forbidden; Request ID: null)
E/Exeception: com.amazonaws.services.s3.model.AmazonS3Exception: Forbidden (Service: Amazon S3; Status Code: 403; Error Code: 403 Forbidden; Request ID: null), S3 Extended Request ID: null
E/percentage: 100 15
E/statechange: FAILED
I have used the following code for it , please check it once.
CognitoCachingCredentialsProvider credentialsProvider = new CognitoCachingCredentialsProvider(
context, NetworkTask.BASE_AWS_KEY, Regions.US_EAST_1);// Region
AmazonS3Client s3 = new AmazonS3Client(credentialsProvider);
s3.setRegion(Region.getRegion(Regions.US_EAST_1));
transferUtility = new TransferUtility(s3, context);
TransferObserver transferObserver = transferUtility.upload(
"MY-BUCKET-NAME" /* The bucket to upload to */
, fileUploadName, /* The key for the uploaded object */
fileToUpload /* The file where the data to upload exists */
);
transferObserver.setTransferListener(new TransferListener() {
#Override
public void onStateChanged(int id, TransferState state) {
Log.e("statechange", state + "");
if (String.valueOf(state).equalsIgnoreCase("COMPLETED")) {
fileUploadInterface.getUploadFileUrl(String.valueOf(s3.getUrl("zargow.vcard.image", fileUploadName)), service_id);
}
}
#Override
public void onProgressChanged(int id, long bytesCurrent, long bytesTotal) {
int percentage = (int) (bytesCurrent / bytesTotal * 100);
Log.e("percentage", percentage + "" + " " + id);
}
#Override
public void onError(int id, Exception ex) {
Log.e("Exeception", ex.toString());
}
});
4 out of 5 times i am getting above error and one time getting the success response.
I have used the following gradle for it,please check it once
compile('com.amazonaws:aws-android-sdk-s3:2.2.13') {
exclude module: 'gson'
}
I have visited the following site before posting the question but did not get any expected result.Please check the links
1. First link
2. Second link
3. Third link
4. Forth link
5. Fifth link
Please check it once, and let me know what did i wrong on the code. Please help me to short out from this problem
Ok well this took me a ton of time to get right, but I'm going to share it with you ;). Below is a CognitoHelper class I wrote to manage using the credentials needed for Authentication as well as S3 information. I don't know your full app or what you are using, so I'm just giving you the full thing.
import com.amazonaws.mobileconnectors.cognitoidentityprovider.CognitoDevice;
import com.amazonaws.mobileconnectors.cognitoidentityprovider.CognitoUserAttributes;
import com.amazonaws.mobileconnectors.cognitoidentityprovider.CognitoUserCodeDeliveryDetails;
import com.amazonaws.mobileconnectors.cognitoidentityprovider.CognitoUserDetails;
import com.amazonaws.mobileconnectors.cognitoidentityprovider.CognitoUserPool;
import com.amazonaws.mobileconnectors.cognitoidentityprovider.CognitoUserSession;
import com.amazonaws.mobileconnectors.cognitoidentityprovider.continuations.AuthenticationContinuation;
import com.amazonaws.mobileconnectors.cognitoidentityprovider.continuations.AuthenticationDetails;
import com.amazonaws.mobileconnectors.cognitoidentityprovider.continuations.ChallengeContinuation;
import com.amazonaws.mobileconnectors.cognitoidentityprovider.continuations.ForgotPasswordContinuation;
import com.amazonaws.mobileconnectors.cognitoidentityprovider.continuations.MultiFactorAuthenticationContinuation;
import com.amazonaws.mobileconnectors.cognitoidentityprovider.handlers.AuthenticationHandler;
import com.amazonaws.mobileconnectors.cognitoidentityprovider.handlers.ForgotPasswordHandler;
import com.amazonaws.mobileconnectors.cognitoidentityprovider.handlers.GenericHandler;
import com.amazonaws.mobileconnectors.cognitoidentityprovider.handlers.GetDetailsHandler;
import com.amazonaws.mobileconnectors.cognitoidentityprovider.handlers.UpdateAttributesHandler;
import com.amazonaws.mobileconnectors.cognitoidentityprovider.handlers.VerificationHandler;
import com.amazonaws.regions.Regions;
import java.util.List;
import java.util.Locale;
/**
* Created by App Studio 35 on 7/27/17.
*/
public class CognitoManager {
/*///////////////////////////////////////////////////////////////
// CONSTANTS
*////////////////////////////////////////////////////////////////
public static class S3BucketInfo {
public static final String DEV_BUCKET_NAME = "<YOUR-PHOTOS-STAGING-BUCKET>";
public static final String PRD_BUCKET_NAME = "<YOUR-PHOTOS-PROD-BUCKET>";
}
public static class CognitoProviderInfo {
public static final Regions DEV_REGION = Regions.US_EAST_1;
public static final Regions PRD_REGION = Regions.US_EAST_1;
}
public static class S3ClientInfo {
public static final String PRD_CLIENT_ACCESS_KEY = "<YOUR-CLIENT-ACCESS-KEY>";
public static final String PRD_CLIENT_SECRET_KEY = "<YOUR-CLIENT-SECRET-KEY>";
}
public static class CognitoUserPoolInfo {
public static final String DEV_USER_POOL_ID = "us-east-1_<YOUR-LETTERS>"; //DON'T USE EAST IF YOU ARE NOT EAST
public static final String DEV_APP_PROVIDER_CLIENT_ID = "<YOUR-APP-STAGE-PROVIDER-CLIENT-ID-FOR-ANDROID>";
public static final String DEV_APP_PROVIDER_CLIENT_SECRET = "<YOUR-APP-STAGE-PROVIDER-CLIENT-SECRET-FOR-ANDROID-PROVIDER>";
public static final String PRD_USER_POOL_ID = "us-east-1_<YOUR LETTERS>"; //DON'T USE EAST IF YOU ARE NOT EAST
public static final String PRD_APP_PROVIDER_CLIENT_ID = "<YOUR-APP-PROD-PROVIDER-CLIENT-ID-FOR-ANDROID>";
public static final String PRD_APP_PROVIDER_CLIENT_SECRET = "<YOUR-APP-PROD-PROVIDER-CLIENT-ID-FOR-ANDROID>";
}
/*///////////////////////////////////////////////////////////////
// MEMBERS
*////////////////////////////////////////////////////////////////
private static final String TAG = Globals.SEARCH_STRING + CognitoManager.class.getSimpleName();
private static CognitoManager mInstance;
private static CognitoUserPool mUserPool;
private static String mUser;
private static boolean mIsEmailVerified;
private static boolean mIsPhoneVerified;
private static CognitoUserSession mCurrentUserSession;
/*///////////////////////////////////////////////////////////////
// PROPERTIES
*////////////////////////////////////////////////////////////////
public static String getUserPoolID(){
switch (AMEnvironment.getCurrentEnvironment()){
case DEV:
case QA:
case STG:
return CognitoUserPoolInfo.DEV_USER_POOL_ID;
case PRD:
default:
return CognitoUserPoolInfo.PRD_USER_POOL_ID;
}
}
public static String getClientID(){
switch (AMEnvironment.getCurrentEnvironment()){
case DEV:
case QA:
case STG:
return CognitoUserPoolInfo.DEV_APP_PROVIDER_CLIENT_ID;
case PRD:
default:
return CognitoUserPoolInfo.PRD_APP_PROVIDER_CLIENT_ID;
}
}
public static String getClientSecret(){
switch (AMEnvironment.getCurrentEnvironment()){
case DEV:
case QA:
case STG:
return CognitoUserPoolInfo.DEV_APP_PROVIDER_CLIENT_SECRET;
case PRD:
default:
return CognitoUserPoolInfo.PRD_APP_PROVIDER_CLIENT_SECRET;
}
}
public static String getS3ClientID(){
switch (AMEnvironment.getCurrentEnvironment()){
case DEV:
case QA:
case STG:
case PRD:
default:
return S3ClientInfo.PRD_CLIENT_ACCESS_KEY;
}
}
public static String getS3ClientSecret(){
switch (AMEnvironment.getCurrentEnvironment()){
case DEV:
case QA:
case STG:
case PRD:
default:
return S3ClientInfo.PRD_CLIENT_SECRET_KEY;
}
}
public static String getS3BucketName(){
switch (AMEnvironment.getCurrentEnvironment()){
case DEV:
case QA:
case STG:
return S3BucketInfo.DEV_BUCKET_NAME;
case PRD:
default:
return S3BucketInfo.PRD_BUCKET_NAME;
}
}
public static Regions getCognitoRegion(){
switch (AMEnvironment.getCurrentEnvironment()){
case DEV:
case QA:
case STG:
return CognitoProviderInfo.DEV_REGION;
case PRD:
default:
return CognitoProviderInfo.PRD_REGION;
}
}
public static void setUser(String user){
mUser = user;
}
public static String getUser(){
return mUser;
}
public static CognitoUserPool getUserPool(){
return mUserPool;
}
public static CognitoUserSession getCurrentUserSession(){
return mCurrentUserSession;
}
public static void setCurrentUserSession(CognitoUserSession session){
mCurrentUserSession = session;
}
/*///////////////////////////////////////////////////////////////
// INIT
*////////////////////////////////////////////////////////////////
public static void init(Context context) {
if (mInstance != null && mUserPool != null) {
return;
}
if (mInstance == null) {
mInstance = new CognitoManager();
}
if (mUserPool == null) {
// Create a user pool with default ClientConfiguration
mUserPool = new CognitoUserPool(context, getUserPoolID(), getClientID(), getClientSecret(), getCognitoRegion());
}
}
/*///////////////////////////////////////////////////////////////
// EXTERNAL METHODS
*////////////////////////////////////////////////////////////////
public static void signInUser(final String user, final String password, final AuthenticationHandler authenticationHandler){
setUser(user);
getUserPool().getUser(user).getSessionInBackground(new AuthenticationHandler() {
#Override
public void onSuccess(final CognitoUserSession userSession, final CognitoDevice newDevice) {
setCurrentUserSession(userSession);
rememberTrustedDevice(newDevice);
getUserDetails(new GetDetailsHandler() {
#Override
public void onSuccess(CognitoUserDetails cognitoUserDetails) {
try{
mIsEmailVerified = Boolean.parseBoolean(cognitoUserDetails.getAttributes().getAttributes().get(Globals.CUSTOM_USER_ATTRIBUTES.IS_EMAIL_VALIDATED_ATTRIBUTE));//"email_verified" is the string
//mIsPhoneVerified = Boolean.parseBoolean(cognitoUserDetails.getAttributes().getAttributes().get(Globals.CUSTOM_USER_ATTRIBUTES.IS_EMAIL_VALIDATED_ATTRIBUTE));
}catch (Exception ex){
}
authenticationHandler.onSuccess(userSession, newDevice);
}
#Override
public void onFailure(Exception exception) {
authenticationHandler.onSuccess(userSession, newDevice);
}
});
}
#Override
public void getAuthenticationDetails(AuthenticationContinuation authenticationContinuation, String UserId) {
Locale.setDefault(Locale.US);
AuthenticationDetails authenticationDetails = new AuthenticationDetails(user, password, null);
authenticationContinuation.setAuthenticationDetails(authenticationDetails);
authenticationContinuation.continueTask();
authenticationHandler.getAuthenticationDetails(authenticationContinuation, UserId);
}
#Override
public void getMFACode(MultiFactorAuthenticationContinuation continuation) {
authenticationHandler.getMFACode(continuation);
}
#Override
public void authenticationChallenge(ChallengeContinuation continuation) {
authenticationHandler.authenticationChallenge(continuation);
//TODO implement "new_password_required" or "phone_needs_verified" or "email_needs_verified" instead of passing back lazily use correct callbacks of phone or password etc.. for cleanliness
}
#Override
public void onFailure(Exception exception) {
authenticationHandler.onFailure(exception);
}
});
}
public static void signOutCurrentUser(){
if(getUserPool().getCurrentUser() != null) {
getUserPool().getCurrentUser().signOut();
}
}
public static void rememberTrustedDevice(CognitoDevice newDevice){
if(newDevice != null) {
newDevice.rememberThisDeviceInBackground(new GenericHandler() {
#Override
public void onSuccess() {
//not really sure if we need to do anything with this info or not just yet
}
#Override
public void onFailure(Exception exception) {
//Faled to save device
}
});
}
}
public static void refreshToken(final GenericHandler genericHandler){ //called from background thread to keep session alive
if(getUserPool() == null || getUserPool().getCurrentUser() == null || getUserPool().getCurrentUser().getUserId() == null){
genericHandler.onFailure(new Exception("Invalid User Token"));
}else{
getUserPool().getCurrentUser().getSessionInBackground(new AuthenticationHandler() {
#Override
public void onSuccess(CognitoUserSession userSession, CognitoDevice newDevice) {
setCurrentUserSession(userSession);
rememberTrustedDevice(newDevice);
getUserDetails(new GetDetailsHandler() {
#Override
public void onSuccess(CognitoUserDetails cognitoUserDetails) {
try{
mIsEmailVerified = Boolean.parseBoolean(cognitoUserDetails.getAttributes().getAttributes().get(Globals.CUSTOM_USER_ATTRIBUTES.IS_EMAIL_VALIDATED_ATTRIBUTE));
//mIsPhoneVerified = Boolean.parseBoolean(cognitoUserDetails.getAttributes().getAttributes().get(Globals.CUSTOM_USER_ATTRIBUTES.IS_PHONE_VALIDATED_ATTRIBUTE)); //not used in my current app
}catch (Exception ex){
}
genericHandler.onSuccess();
}
#Override
public void onFailure(Exception exception) {
genericHandler.onSuccess();
}
});
}
#Override
public void getAuthenticationDetails(AuthenticationContinuation authenticationContinuation, String UserId) {
genericHandler.onFailure(new Exception("Invalid User Token"));
}
#Override
public void getMFACode(MultiFactorAuthenticationContinuation continuation) {
genericHandler.onFailure(new Exception("Invalid User Token"));
}
#Override
public void authenticationChallenge(ChallengeContinuation continuation) {
genericHandler.onFailure(new Exception("Invalid User Token"));
}
#Override
public void onFailure(Exception exception) {
genericHandler.onFailure(new Exception("Invalid User Token"));
}
});
}
}
/**
* Used to update cached booleans for isEmailVerified or isPhoneVerified
*/
public static void phoneOrEmailChanged(){
if(getUserPool().getCurrentUser() == null){
return;
}
getUserDetails(new GetDetailsHandler() {
#Override
public void onSuccess(CognitoUserDetails cognitoUserDetails) {
try{
mIsEmailVerified = Boolean.parseBoolean(cognitoUserDetails.getAttributes().getAttributes().get(Globals.CUSTOM_USER_ATTRIBUTES.IS_EMAIL_VALIDATED_ATTRIBUTE));
//mIsPhoneVerified = Boolean.parseBoolean(cognitoUserDetails.getAttributes().getAttributes().get(Globals.CUSTOM_USER_ATTRIBUTES.IS_PHONE_VALIDATED_ATTRIBUTE)); //"phone_number" is string, but not used in my current app
}catch (Exception ex){
}
}
#Override
public void onFailure(Exception exception) {
}
});
}
public static boolean isPhoneVerified(){
return true; //for now we are not verifying phone
//return mIsPhoneVerified;
}
public static boolean isEmailVerified(){
return mIsEmailVerified;
}
public static void getUserDetails(GetDetailsHandler handler){
getUserPool().getCurrentUser().getDetailsInBackground(handler);
}
public static void updatePhoneNumber(String phone, final GenericHandler handler){
CognitoUserAttributes userAttributes = new CognitoUserAttributes();
userAttributes.addAttribute(Globals.CUSTOM_USER_ATTRIBUTES.PHONE_ATTRIBUTE, PhoneNumberHelper.getStrippedNumberWithCountryCode(phone));
CognitoManager.getUserPool().getUser(CognitoManager.getUserPool().getCurrentUser().getUserId()).updateAttributesInBackground(userAttributes, new UpdateAttributesHandler() {
#Override
public void onSuccess(List<CognitoUserCodeDeliveryDetails> attributesVerificationList) {
handler.onSuccess();
}
#Override
public void onFailure(Exception exception) {
handler.onFailure(exception);
}
});
}
public static void updateEmail(String email, final GenericHandler handler){
CognitoUserAttributes userAttributes = new CognitoUserAttributes();
userAttributes.addAttribute(Globals.CUSTOM_USER_ATTRIBUTES.EMAIL_ATTRIBUTE, email);
CognitoManager.getUserPool().getUser(CognitoManager.getUserPool().getCurrentUser().getUserId()).updateAttributesInBackground(userAttributes, new UpdateAttributesHandler() {
#Override
public void onSuccess(List<CognitoUserCodeDeliveryDetails> attributesVerificationList) {
handler.onSuccess();
}
#Override
public void onFailure(Exception exception) {
handler.onFailure(exception);
}
});
}
public static void updatePassword(String oldPassword, String newPassword, final GenericHandler handler){
getUserPool().getUser().changePasswordInBackground(oldPassword, newPassword, new GenericHandler() {
#Override
public void onSuccess() {
handler.onSuccess();
}
#Override
public void onFailure(Exception exception) {
handler.onFailure(exception);
}
});
}
public static void forgotPassword(String email, final ForgotPasswordHandler handler){
getUserPool().getUser(email).forgotPasswordInBackground(new ForgotPasswordHandler() {
#Override
public void onSuccess() {
handler.onSuccess();
}
#Override
public void getResetCode(ForgotPasswordContinuation continuation) {
handler.getResetCode(continuation);
}
#Override
public void onFailure(Exception exception) {
handler.onFailure(exception);
}
});
}
public static void sendVerificationEmail(final VerificationHandler handler){
getUserPool().getCurrentUser().getAttributeVerificationCodeInBackground(Globals.CUSTOM_USER_ATTRIBUTES.PHONE_ATTRIBUTE, new VerificationHandler() {
#Override
public void onSuccess(CognitoUserCodeDeliveryDetails verificationCodeDeliveryMedium) {
handler.onSuccess(verificationCodeDeliveryMedium);
}
#Override
public void onFailure(Exception exception) {
handler.onFailure(exception);
}
});
}
public static void sendVerificationText(final VerificationHandler handler){
getUserPool().getCurrentUser().getAttributeVerificationCodeInBackground(Globals.CUSTOM_USER_ATTRIBUTES.PHONE_ATTRIBUTE, new VerificationHandler() {
#Override
public void onSuccess(CognitoUserCodeDeliveryDetails verificationCodeDeliveryMedium) {
handler.onSuccess(verificationCodeDeliveryMedium);
}
#Override
public void onFailure(Exception exception) {
handler.onFailure(exception);
}
});
}
public static void verifyAttributesInBackground(String attribute, String code, final GenericHandler handler){
CognitoManager.getUserPool().getCurrentUser().verifyAttributeInBackground(attribute, code, new GenericHandler() {
#Override
public void onSuccess() {
handler.onSuccess();
}
#Override
public void onFailure(Exception exception) {
handler.onFailure(exception);
}
});
}
}
Next up how to use the S3 piece of it:
private void uploadImageToS3(String filePath){
final File newImageFile = new File(filePath);
showProgressDialog(TAG, getString(R.string.loading_please_wait));
//For auth route
BasicAWSCredentials credentials = new BasicAWSCredentials(CognitoManager.getS3ClientID(), CognitoManager.getS3ClientSecret());
AmazonS3Client s3 = new AmazonS3Client(credentials);
TransferUtility transferUtility = new TransferUtility(s3, this);
TransferObserver observer = transferUtility.upload(CognitoManager.getS3BucketName(), newImageFile.getName(), newImageFile);
observer.setTransferListener(new TransferListener() {
#Override
public void onStateChanged(int id, TransferState state) {
if(state.compareTo(TransferState.COMPLETED) == 0){
String imgURLOfUploadComplete = "https://s3.amazonaws.com/" + CognitoManager.getS3BucketName() + "/" + newImageFile.getName();
hideProgressDialog(TAG);
Intent intent = new Intent();
intent.putExtra(Globals.INTENT_KEYS.KEY_IMAGE_URL, imgURLOfUploadComplete);
setResult(Activity.RESULT_OK, intent);
if(newImageFile.exists()){
newImageFile.delete();
}
finish();
}
}
#Override
public void onProgressChanged(int id, long bytesCurrent, long bytesTotal) {
if(bytesTotal != 0) {
//For viewing progress
int percentage = (int) (bytesCurrent / bytesTotal * 100);
}
}
#Override
public void onError(int id, Exception ex) {
A35Log.e(TAG, getString(R.string.error_uploading_s3_part1) + id + getString(R.string.error_uploading_s3_part2) + ex.getMessage());
hideProgressDialog(TAG);
showDialogMessage(getString(error), getString(R.string.error_failed_create_image_alert_id) + error);
}
});
}
and that's it. Now you have a fully functioning example of Cognito and S3, you just have to put in your keys and make sure you setup your Android Provider for your app in S3 if you are using that piece, but if you are just using the S3 piece with id and secret you probably don't need the CognitoHelper stuff, just use your secret and id and bucket names for your environment and be done. I used the same security group and id/secret for prd and stage just separated by buckets, but you can do whatever you want with that.
I am using a global variables "GlobalVariables" in a separated class and I am try to use it in the following code but it is always gives me the error :
The method getApplication() is undefined for the type UploadPicture
I tried the following but still have error:
((GlobalVariables) this.getApplication()).set_FileUploading(false);
The qustion was already asked here but unfortunatlly all the answors didn't work with me and gave me same error! any suggestion please?
public class UploadPicture extends AsyncTask<Void, Long, Boolean> {
private DropboxAPI<?> mApi;
private String mPath;
private File mFile;
private long mFileLen;
private UploadRequest mRequest;
private Context mContext;
private String mErrorMsg;
private File outFiles;
public UploadPicture(Context context, DropboxAPI<?> api, String dropboxPath, File file) {
mContext = context.getApplicationContext();
mFileLen = file.length();
mApi = api;
mPath = dropboxPath;
mFile = file;
}
#Override
protected Boolean doInBackground(Void... params) {
try {
FileInputStream fis = new FileInputStream(mFile);
String path = mPath + outFiles.getName();
mRequest = mApi.putFileOverwriteRequest(path, fis, mFile.length(),
new ProgressListener() {
#Override
public long progressInterval() {
return 500;
}
#Override
public void onProgress(long bytes, long total) {
//publishProgress(bytes);
}
}
);
if (mRequest != null) {
mRequest.upload();
((GlobalVariables) UploadPicture.this.getApplication()).set_FileUploading(false);
return true;
}
} catch (DropboxUnlinkedException e) {
// This session wasn't authenticated properly or user unlinked
mErrorMsg = "This app wasn't authenticated properly.";
} catch (DropboxFileSizeException e) {
// File size too big to upload via the API
mErrorMsg = "This file is too big to upload";
} catch (DropboxPartialFileException e) {
// We canceled the operation
mErrorMsg = "Upload canceled";
} catch (DropboxServerException e) {
// Server-side exception. These are examples of what could happen,
// but we don't do anything special with them here.
if (e.error == DropboxServerException._401_UNAUTHORIZED) {
// Unauthorized, so we should unlink them. You may want to
// automatically log the user out in this case.
} else if (e.error == DropboxServerException._403_FORBIDDEN) {
// Not allowed to access this
} else if (e.error == DropboxServerException._404_NOT_FOUND) {
// path not found (or if it was the thumbnail, can't be
// thumbnailed)
} else if (e.error == DropboxServerException._507_INSUFFICIENT_STORAGE) {
// user is over quota
} else {
// Something else
}
// This gets the Dropbox error, translated into the user's language
mErrorMsg = e.body.userError;
if (mErrorMsg == null) {
mErrorMsg = e.body.error;
}
} catch (DropboxIOException e) {
// Happens all the time, probably want to retry automatically.
mErrorMsg = "Network error. Try again.";
} catch (DropboxParseException e) {
// Probably due to Dropbox server restarting, should retry
mErrorMsg = "Dropbox error. Try again.";
} catch (DropboxException e) {
// Unknown error
mErrorMsg = "Unknown error. Try again.";
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return false;
}
}
Edit: I am adding now my "VariableGlobales" calss:
public class GlobalVariables extends Application {
private Boolean _IsIOIORunning=false;
private Boolean _FileUploading=false;
public Boolean get_IsIOIORunning()
{
return _IsIOIORunning;
}
public void set_IsIOIORunning(Boolean _IsIOIORunning)
{
this._IsIOIORunning = _IsIOIORunning;
}
public Boolean get_FileUploading()
{
return _FileUploading;
}
public void set_FileUploading(Boolean _FileUploading)
{
this._FileUploading = _FileUploading;
}
It's normal UploadPicture doesn't extend GlobalVariables but it extend AsyncTask.
That it's my "GlobalVariables "
public class AppInfo extends Application {
private static Context context;
private static String user;
public void onCreate(){
super.onCreate();
AppInfo.context = getApplicationContext();
user = null;
}
public static Context getAppContext() {return AppInfo.context;}
public static String getUser() {return user;}
public static void setUser(String user) {AppInfo.user = user;}
}
And I call it everywhere like that:
AppInfo.getUser();
Edit:
GlobalVariables should use static method and variables:
public class GlobalVariables extends Application {
private static Boolean _IsIOIORunning=false;
private static Boolean _FileUploading=false;
public static Boolean get_IsIOIORunning() {
return _IsIOIORunning;
}
public static void set_IsIOIORunning(Boolean _IsIOIORunning) {
GlobalVariables._IsIOIORunning = _IsIOIORunning;
}
public static Boolean get_FileUploading(){
return _FileUploading;
}
public static void set_FileUploading(Boolean _FileUploading){
GlobalVariables._FileUploading = _FileUploading;
}
}
Here is my demo:
PoolableObjectFactoryImpl.java
public class PoolableObjectFactoryImpl implements PoolableObjectFactory<Result> {
private static Logger logger = Logger.getLogger("BackgroundLog");
#Override
public void activateObject(Result obj) throws Exception {
logger.info("==activate result.==");
obj.setResult(-999);
}
#Override
public void destroyObject(Result obj) throws Exception {
logger.info("==destroy result.==");
obj = null;
}
#Override
public Result makeObject() throws Exception {
logger.info("==make result.==");
Result result = new Result();
return result;
}
#Override
public void passivateObject(Result obj) throws Exception {
logger.info("==passivate result.==");
obj.setResult(-999);
}
#Override
public boolean validateObject(Result obj) {
/*if(obj.getResult() == -999){
logger.info("==validate result true.==");
return true;
}else{
logger.info("==validate result false.==");
return false;
}*/
logger.info("==validate result true.==");
return true;
}
}
ThreadPool.java
public class ThreadPool extends GenericObjectPool {
private static Logger logger = Logger.getLogger("BackgroundLog");
private static ThreadPool pool = null;
private Map<String, String> map = getConfig();
private ThreadPool() {
this.setFactory(new PoolableObjectFactoryImpl());
this.setMaxActive(Integer.parseInt(map.get("maxActive")));
this.setWhenExhaustedAction(Byte.valueOf(map.get("whenExhaustedAction")));
this.setMaxWait(Long.parseLong(map.get("maxWait")));
this.setMaxIdle(Integer.parseInt(map.get("maxIdle")));
this.setTestOnBorrow(Boolean.valueOf(map.get("testOnBorrow")));
this.setTestOnReturn(Boolean.valueOf(map.get("testOnReturn")));
this.setTimeBetweenEvictionRunsMillis(Long.parseLong(map.get("timeBetweenEvictionRunsMillis")));
this.setNumTestsPerEvictionRun(Integer.parseInt(map.get("numTestsPerEvictionRun")));
this.setMinEvictableIdleTimeMillis(Long.parseLong(map.get("minEvictableIdleTimeMillis")));
this.setTestWhileIdle(Boolean.valueOf(map.get("testWhileIdle")));
}
public static ThreadPool getInstance() {
if (pool == null) {
synchronized (ThreadPool.class) {
if (pool == null) {
logger.info("thread pool is initialized.");
pool = new ThreadPool();
}
}
}
return pool;
}
/**
*
* <p>Title: getConfig</p>
* <p>Description: get pool configuration</p>
* #return
*/
public Map<String, String> getConfig() {
Map<String, String> map = new HashMap<String, String>();
Properties props = new Properties();
try {
InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("pool.properties");
props.load(in);
Enumeration en = props.propertyNames();
while (en.hasMoreElements()) {
String key = (String) en.nextElement();
map.put(key, props.getProperty(key));
}
in.close();
} catch (Throwable t) {
logger.error(t.getMessage(), t);
}
return map;
}
}
Result.java
public class Result {
private int result;
public Result(){
}
public int getResult(){
return this.result;
}
public void setResult(int result){
this.result = result;
}
}
Test.java
public class Test implements Runnable {
private static Logger logger = Logger.getLogger("BackgroundLog");
private String name = null;
public Test(String name){
this.name = name;
}
public String getName(){
return this.name;
}
public void setName(String name){
this.name = name;
}
#Override
public void run() {
ThreadPool pool = ThreadPool.getInstance();
for(int i=0;i<1000;i++){
try {
Result result = (Result)pool.borrowObject();
logger.info("numActive: "+ pool.getNumActive()+"\t"+"numIdle: "+pool.getNumIdle());
logger.info("thread "+getName()+" "+i+" borrow object from pool "+result.getResult()+".");
result.setResult(0);
pool.returnObject(result);
logger.info("return object to pool.");
Thread.sleep(100);
} catch (Exception e) {
logger.info("thread "+getName()+" "+i);
e.printStackTrace();
}
}
}
public static void main(String[] args) {
for(int i=0;i<50;i++){
Thread t = new Thread(new Test("t"+i));
t.start();
}
}
}
Next is the configuration properties:
Next is the threads view from Jprofiler when it has 4 threads:
After Test.java is running a few minutes,some threads keep beling blocked,only one is still running but does not print any log.I don't really understand thread thing.
can anyone explain why? how to avoid threads being blocked?
Consider posting logs of an execution cycle.
Did you try commenting Thread.sleep line, because sleep will hold onto the lock it has acquired till the thread is in sleep mode.
Try replacing "Thread.sleep(100);" with:
try {
synchronized (this) {
this.wait(200);
}
} catch (InterruptedException e) {
}