title: Upload a file to Amazon S3 via Android Studio
body: <p>I have created a sample application in order to test uploading a sample file to <code>Amazon S3</code> via Android Studio using the <code>AWS Mobile SDK</code> as described in the <a href="https://docs.aws.amazon.com/mobile/sdkforandroid/developerguide/setup.html" rel="nofollow noreferrer">official docs</a> from Amazon for interacting with AWS within Android Studio, but I am having issues with the file not being uploaded.</p>
  
  <p>For the purposes of this test I have captured an image from the Camera which is located in the <code>images</code> folder of the devices file browser, under the filename of <code>Test.jpg</code>. I can also access this file via <code>Device storage/DCIM/Camera/Test.jpg</code>.</p>
  
  <p>I've also followed the <a href="https://docs.aws.amazon.com/mobile/sdkforandroid/developerguide/s3transferutility.html" rel="nofollow noreferrer">official doc</a> from Amazon in order to develop the code in charge of uploading to S3. At this point I am simply trying to achieve this functionality with Unauth and S3FullAccess just for the initial tests.</p>
  
  <p><strong>Manifest</strong></p>
  
  <pre><code>&lt;uses-permission android:name="android.permission.INTERNET" /&gt;
  
  &lt;service
          android:name="com.amazonaws.mobileconnectors.s3.transferutility.TransferService"
          android:enabled="true" /&gt;
  </code></pre>
  
  <p><strong>import(s)</strong></p>
  
  <p><em>The imports I have in my MainActivity.java that are related to Amazon S3 usage are here.</em></p>
  
  <pre><code>import com.amazonaws.auth.CognitoCachingCredentialsProvider;
  import com.amazonaws.mobileconnectors.s3.transferutility.TransferListener;
  import com.amazonaws.mobileconnectors.s3.transferutility.TransferObserver;
  import com.amazonaws.mobileconnectors.s3.transferutility.TransferState;
  import com.amazonaws.mobileconnectors.s3.transferutility.TransferUtility;
  import com.amazonaws.regions.Region;
  import com.amazonaws.regions.Regions;
  import com.amazonaws.services.s3.AmazonS3;
  import com.amazonaws.services.s3.AmazonS3Client;
  </code></pre>
  
  <p><strong>Build.gradle</strong> (Module:app)</p>
  
  <pre><code>apply plugin: 'com.android.application'
  
  android {
      compileSdkVersion 25
      buildToolsVersion "25.0.2"
      defaultConfig {
          applicationId "com.example.devonryder.s3_testing"
          minSdkVersion 21
          targetSdkVersion 25
          versionCode 1
          versionName "1.0"
          testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
      }
      buildTypes {
          release {
              minifyEnabled false
              proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
          }
      }
  }
  
  dependencies {
      compile fileTree(dir: 'libs', include: ['*.jar'])
  
      // Dependencies for AWS and S3
      compile 'com.amazonaws:aws-android-sdk-core:2.2.+'
      compile 'com.amazonaws:aws-android-sdk-s3:2.2.+'
      compile 'com.amazonaws:aws-android-sdk-ddb:2.2.+'
  
      androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
          exclude group: 'com.android.support', module: 'support-annotations'
      })
  
      testCompile 'junit:junit:4.12'
  }
  </code></pre>
  
  <p><strong>MainActivity.java</strong></p>
  
  <pre><code>public class MainActivity extends Activity implements View.OnClickListener {
  
      // Get the File of the Test.jpg located in DCIM/Camera directory
      File fileToUpload = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getAbsolutePath() + "Camera/Test.jpg");
  
      AmazonS3 s3;
      TransferUtility transferUtility;
  
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
  
          // Get the button from the layout and set the onClickListener, passing the current context
          Button upload = (Button) findViewById(R.id.btnUploadFile);
          upload.setOnClickListener(this);
  
          // Callback method to call credentialsProvider method.
          credentialsProvider();
  
          // Callback method to call the setTransferUtility method
          setTransferUtility();
      }
  
      // Implement the OnClickListener callbacks
      public void onClick(View view) {
          if (view.getId() == R.id.btnUploadFile) {
              // For easy Debug
              Toast.makeText(getApplicationContext(), "Clicked btn", Toast.LENGTH_LONG).show();
  
              // Set the File to be uploaded to S3
              setFileToUpload();
          }
      }
  
      public void credentialsProvider(){
  
          // Initialize the Amazon Cognito credentials provider
          CognitoCachingCredentialsProvider credentialsProvider = new CognitoCachingCredentialsProvider(
                  getApplicationContext(),
                  "us-east-1:??????????????????????", // Identity Pool ID
                  Regions.US_EAST_1 // Region
          );
  
          // Pass the CognitoCachingCredentialsProvider instantiate the S3Client
          setAmazonS3Client(credentialsProvider);
      }
  
      /**
       *  Create a AmazonS3Client and pass the credentialsProvider.
       * @param credentialsProvider
       */
      public void setAmazonS3Client(CognitoCachingCredentialsProvider credentialsProvider){
  
          // Create an S3 client
          s3 = new AmazonS3Client(credentialsProvider);
  
          // Set the region of your S3 bucket
          s3.setRegion(Region.getRegion(Regions.US_EAST_1));
  
      }
  
      public void setTransferUtility() {
  
          transferUtility = new TransferUtility(s3, getApplicationContext());
      }
  
      /**
       * This method is used to upload the file to S3 by using TransferUtility class
       */
      public void setFileToUpload(){
  
          TransferObserver transferObserver = transferUtility.upload(
                  "validBuckitName", // The bucket to upload to
                  "test_photo",  // The key for the uploaded object
                  fileToUpload   // The file where the data to upload exists
          );
  
          transferObserverListener(transferObserver);
      }
  
      /**
       * This is listener method of the TransferObserver
       * An error will be displayed if there is problem uploading the file to S3.
       * @param transferObserver
       */
  
      public void transferObserverListener(TransferObserver transferObserver){
  
          transferObserver.setTransferListener(new TransferListener(){
  
              @Override
              public void onStateChanged(int id, TransferState state) {
                  Log.e("statechange: ", state + "");
              }
  
              @Override
              public void onProgressChanged(int id, long bytesCurrent, long bytesTotal) {
                  int percentage = (int) (bytesCurrent/bytesTotal * 100);
                  Log.e("percentage: ", percentage + "");
              }
  
              @Override
              public void onError(int id, Exception ex) {
                  Log.e("error: ", ex.getMessage());
              }
  
          });
      }
  }
  </code></pre>
  
  <p>I run the application and click the button, but I am not receiving any status in the console, or any errors that indicate why my file is not uploading to S3.</p>
  
  <p><strong>Update</strong></p>
  
  <p>I've found that I had an invalid filename when I was attempting to load the file from storage. The line has been changed to include the proper <code>/</code> after the <code>DCIM</code> path.</p>
  
  <pre><code>File fileToUpload = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getAbsolutePath() + "/Camera/Test.jpg");
  </code></pre>
  
  <p>However, this does not fix the root issue.</p>
  
  <p>I've enabled logging for the bucket now and after I try to upload there is an auto-generated file that is created in the bucket. In short, it seems to notify me that access to the bucket has been denied. This file seems to be XML.</p>
  
  <p>The following is a portion of the main  root node:</p>
  
  <pre><code>&lt;Code&gt;AccessDenied&lt;/Code&gt;
  &lt;Message&gt;Access Denied&lt;/Message&gt;
  </code></pre>