I have tried with the following code: (Previously it was working fine, Now I am testing its not working may be due to android 10 or some other error).
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.WindowManager;
public class AboutUs extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_about_us);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
new DownloadFile().execute("https://4.img-dpreview.com/files/p/E~TS590x0~articles/3925134721/0266554465.jpeg");
}
private class DownloadFile extends AsyncTask<String,Integer, String> {
private PowerManager.WakeLock mWakeLock;
#Override
protected String doInBackground(String... strings) {
String fileUrl = strings[0];
String extStorageDirectory = Environment.getExternalStorageDirectory().toString();
File folder = new File(extStorageDirectory, "MyFolder");
folder.mkdir();
File pdfFile = new File(folder, fileUrl);
try{
pdfFile.createNewFile();
}catch (IOException e){
e.printStackTrace();
}
FileDownloader.downloadFile(fileUrl, pdfFile);
return null;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
// take CPU lock to prevent CPU from going off if the user
// presses the power button during download
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
getClass().getName());
mWakeLock.acquire();
mProgressDialog.show();
}
#Override
protected void onProgressUpdate(Integer... progress) {
super.onProgressUpdate(progress);
// if we get here, length is known, now set indeterminate to false
mProgressDialog.setIndeterminate(false);
mProgressDialog.setMax(100);
mProgressDialog.setProgress(progress[0]);
}
#Override
protected void onPostExecute(String result) {
mWakeLock.release();
mProgressDialog.dismiss();
if (result != null)
Toast.makeText(context,"Download error: "+result, Toast.LENGTH_LONG).show();
else {
Toast.makeText(context, "File downloaded", Toast.LENGTH_SHORT).show();
activity.startActivity(activity.getIntent());
activity.finish();
}
}
}
public static class FileDownloader {
private static final int MEGABYTE = 1024 * 1024;
public static void downloadFile(String fileUrl, File directory){
try {
URL url = new URL(fileUrl);
HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(true);
urlConnection.connect();
InputStream inputStream = urlConnection.getInputStream();
FileOutputStream fileOutputStream = new FileOutputStream(directory);
int totalSize = urlConnection.getContentLength();
byte[] buffer = new byte[MEGABYTE];
int bufferLength = 0;
while((bufferLength = inputStream.read(buffer))>0 ){
fileOutputStream.write(buffer, 0, bufferLength);
}
fileOutputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
I have tried with the above code.
I have added WRITE_INTERNAL_STORAGE and also ask run time permission
There were major changes on how files can be accessed on Android 10
See https://developer.android.com/training/data-storage
You need to use MediaStore or Storage Access Framework (SAF), details https://developer.android.com/training/data-storage/shared for files outside of your App's private directories.
As you are storing photo then MediaStore would be the way to access pictures https://developer.android.com/training/data-storage/shared/media
Though as a quick fix is to temporarily opt out https://developer.android.com/training/data-storage/compatibility but this will only work until Android 11
Some better examples at https://proandroiddev.com/working-with-scoped-storage-8a7e7cafea3
Android 10 requered android:requestLegacyExternalStorage="true" in your AndroidManifest file
check this link
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.xxx.xxxx">
<application
android:requestLegacyExternalStorage="true">
</application>
</manifest>
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Environment;
import android.os.Handler;
import android.util.Log;
import android.widget.Toast;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
public class DownloadTask {
private static final String TAG = "Download Task";
private Context context;
private String downloadUrl = "", downloadFileName = "";
private ProgressDialog progressDialog;
public DownloadTask(Context context, String downloadUrl) {
this.context = context;
this.downloadUrl = downloadUrl;
downloadFileName = downloadUrl.substring(downloadUrl.lastIndexOf( '/' ),downloadUrl.length());//Create file name by picking download file name from URL
Log.e(TAG, downloadFileName);
//Start Downloading Task
new DownloadingTask().execute();
}
private class DownloadingTask extends AsyncTask<Void, Void, Void> {
File apkStorage = null;
File outputFile = null;
#Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog=new ProgressDialog(context);
progressDialog.setMessage("Downloading...");
progressDialog.show();
}
#Override
protected void onPostExecute(Void result) {
try {
if (outputFile != null) {
progressDialog.dismiss();
Toast.makeText(context, "Downloaded Successfully", Toast.LENGTH_SHORT).show();
} else {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
}
}, 3000);
Log.e(TAG, "Download Failed");
}
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "Download Failed" +e);
//Change button text if exception occurs
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
}
}, 3000);
Log.e(TAG, "Download Failed with Exception - " + e.getLocalizedMessage());
}
super.onPostExecute(result);
}
#Override
protected Void doInBackground(Void... arg0) {
try {
URL url = new URL(downloadUrl);//Create Download URl
HttpURLConnection c = (HttpURLConnection) url.openConnection();//Open Url Connection
c.setRequestMethod("GET");//Set Request Method to "GET" since we are grtting data
c.connect();//connect the URL Connection
//If Connection response is not OK then show Logs
if (c.getResponseCode() != HttpURLConnection.HTTP_OK) {
Log.e(TAG, "Server returned HTTP " + c.getResponseCode()
+ " " + c.getResponseMessage());
}
//Get File if SD card is present
/*if (new CheckForSDCard().isSDCardPresent()) {
apkStorage = new File(
Environment.getExternalStorageDirectory() + "/"
+ "NKDROID FILES");
} else
Toast.makeText(context, "Oops!! There is no SD Card.", Toast.LENGTH_SHORT).show();*/
//If File is not present create directory
if (!apkStorage.exists()) {
apkStorage.mkdir();
Log.e(TAG, "Directory Created.");
}
outputFile = new File(apkStorage, downloadFileName);//Create Output file in Main File
//Create New File if not present
if (!outputFile.exists()) {
outputFile.createNewFile();
Log.e(TAG, "File Created");
}
FileOutputStream fos = new FileOutputStream(outputFile);//Get OutputStream for NewFile Location
InputStream is = c.getInputStream();//Get InputStream for connection
byte[] buffer = new byte[1024];//Set buffer type
int len1 = 0;//init length
while ((len1 = is.read(buffer)) != -1) {
fos.write(buffer, 0, len1);//Write new file
}
//Close all connection after doing task
fos.close();
is.close();
} catch (Exception e) {
//Read exception if something went wrong
e.printStackTrace();
outputFile = null;
Log.e(TAG, "Download Error Exception " + e.getMessage());
}
return null;
}
}
}
I have done the following coding to download a file from a url... But when I run the app it stucks on the downloading screen... I am trying to download the file in the internal storage... I have tried every possible way to download the from ur;l... If anyone can suggests any changes int he above code or anyother code sequence I can use...
I don't know what's the problem with your code.. But you can use the following steps to solve your problem.... Just open your pdf url in android chrome... The code is mentioned below....
try {
Intent i = new Intent("android.intent.action.MAIN");
i.setComponent(ComponentName.unflattenFromString("com.android.chrome/com.android.chrome.Main"));
i.addCategory("android.intent.category.LAUNCHER");
i.setData(Uri.parse("your pdf url"));
startActivity(i);
}
catch(ActivityNotFoundException e) {
// Chrome is not installed
Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse("your pdf url"));
startActivity(i);
}
I'm using a very simple code to download an Image from my localhost : here it is :
package com.pep.www.imagedownloader;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnDownload = (Button) findViewById(R.id.btnDownload);
btnDownload.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
download();
}
});
thread.start();
}
});
}
public void download(){
int read = -1;
byte[] buffer = new byte[5*1024];
URL url = null;
HttpURLConnection ucon = null;
InputStream inputStream = null;
FileOutputStream fileOutputStream = null;
File file = null;
try {
url = new URL("http://192.168.1.128/image.jpg");
ucon = (HttpURLConnection) url.openConnection();
inputStream = ucon.getInputStream();
file = new File("mnt/sdcard/image.jpg");
fileOutputStream = new FileOutputStream(file);
while((read=inputStream.read(buffer))!=-1){
fileOutputStream.write(buffer,0,read);
Log.i("LOG","Downling : "+read);
}
Log.i("LOG","Downloaded");
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
While I've added this permission in manifest :
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
I still get this error :
java.io.FileNotFoundException: mnt/sdcard/image.jpg: open failed: EACCES (Permission denied)
EDIT :
when I change my file path to this :
file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsolutePath()+"/image.jpg ");
I still get this error :
java.io.FileNotFoundException: /storage/sdcard/Pictures/aylar.jpg : open failed: EACCES (Permission denied)
EDIT :
Instead of being so childish and giving downVotes , solve the problem !
Stackoverflow has become a place to play childish games :(
Firstly let me tell you one thing If you are using an emulator then the code will not work you need a real device.As we know we give permission to store image in external storage So You can use this method to save your image and then get back.
URL url = new URL ("file://some/path/anImage.png");
InputStream input = url.openStream();
try {
//The sdcard directory e.g. '/sdcard' can be used directly, or
//more safely abstracted with getExternalStorageDirectory()
File storagePath = Environment.getExternalStorageDirectory();
OutputStream output = new FileOutputStream (new File(storagePath,"myImage.png"));
try {
byte[] buffer = new byte[aReasonableSize];
int bytesRead = 0;
while ((bytesRead = input.read(buffer, 0, buffer.length)) >= 0) {
output.write(buffer, 0, bytesRead);
}
} finally {
output.close();
}
} finally {
input.close();
}
try to use this
if (android.os.Environment.getExternalStorageState().equals(
android.os.Environment.MEDIA_MOUNTED))
{
file =new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsolutePath()+"/image.jpg ");
if(!file.exists())
file.createNewFile();
}
replace
file = new File("mnt/sdcard/image.jpg");
with
file = new File("file:///sdcard/image.jpg");
its simple code any file like image,video,audio etc we can download it.
Button start;
//String HttpMyUrl="http://am.cdnmob.org/_/img/loader-small.gif";
String HttpMyUrl="http://ringtones.mob.org/ringtone/RIusrm-7xATkRQlLw1o89w/1424909358/fa1b23bb5e35c8aed96b1a5aba43df3d/stefano_gambarelli_feat_pochill-land_on_mars_v2.mp3";
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
start= (Button) findViewById(R.id.startBtn);
start.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(HttpMyUrl));
request.setTitle("File Download");
request.setDescription("File is being Downloaded...");
request.allowScanningByMediaScanner();
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
String fileName = URLUtil.guessFileName(HttpMyUrl,null, MimeTypeMap.getFileExtensionFromUrl(HttpMyUrl));
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS,fileName);
DownloadManager manager =(DownloadManager) getApplication().getSystemService(Context.DOWNLOAD_SERVICE);
manager.enqueue(request);
}
});
package com.lociiapp;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.util.Log;
import android.widget.ImageView;
import android.widget.Toast;
import com.androidquery.AQuery;
import com.example.imageslideshow.R;
public class recciverfullimageActivty extends Activity {
String reccvierid;
Context context;
ImageView recciverimage;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
Intent myintent = getIntent();
reccvierid = myintent.getStringExtra("reccvierid");
recciverimage = (ImageView) findViewById(R.id.recciverImage);
String myfinalpathare = reccvierid;
Toast.makeText(getApplicationContext(), reccvierid, 10000).show();
String imagepathe = "http://api.lociiapp.com/TransientStorage/"
+ myfinalpathare + ".jpg";
try {
saveImage(imagepathe);
Log.e("****************************", "Sucess");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void saveImage(String urlPath) throws Exception {
String fileName = "test.jpg";
File folder = new File("/sdcard/LociiImages/");
// have the object build the directory structure, if needed.
folder.mkdirs();
final File output = new File(folder, fileName);
if (output.exists()) {
output.delete();
}
InputStream stream = null;
FileOutputStream fos = null;
try {
URL url = new URL(urlPath);
stream = url.openConnection().getInputStream();
// InputStreamReader reader = new InputStreamReader(stream);
DataInputStream dis = new DataInputStream(url.openConnection()
.getInputStream());
byte[] fileData = new byte[url.openConnection().getContentLength()];
for (int x = 0; x < fileData.length; x++) { // fill byte array with
// bytes from the data
// input stream
fileData[x] = dis.readByte();
}
dis.close();
fos = new FileOutputStream(output.getPath());
fos.write(fileData);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
This is My code I am trying to save Image which is coming from server we have Image Url . when i Run this Code then Folder is creating in Sd card But image is not downloading on Save in Sd care please help and tell where i am doing wrong .
Your checklist should be as follows:
A. Make sure you have the right permissions:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
B. Move networking and file IO logic to non-UI thread:
new AsyncTask<Params, Progress, Result>() {
#Override protected Result doInBackground() {
saveImage(imagepathe);
}
#Override protected void onPostExecute(String result) {
// update UI here
}
}.execute(params);
C. Do not read one byte at the time. It is probably not the source of your problem but it
does make your solution much slower than it can be:
Instead of:
for(;;) {
fileData[x] = dis.readByte();
}
Do this:
URL u = new URL(url);
URLConnection connection = u.openConnection();
byte[] buffer = new byte[connection.getContentLength()];
stream.readFully(buffer); // <------------- read all at once
stream.close();
D. And , finally, consider using Picasso for the job:
Picasso.with(context)
.load(url)
.resize(50, 50)
.centerCrop()
.into(imageView)
Nowadays you just no not need to write that much code to get were you're going..
Try this..
Call like below instead of saveImage(imagepathe);
myAsyncTask myWebFetch = new myAsyncTask();
myWebFetch.execute();
and myAsyncTask.class
class myAsyncTask extends AsyncTask<Void, Void, Void> {
public ProgressDialog dialog;
myAsyncTask()
{
dialog = new ProgressDialog(webview.this);
dialog.setMessage("Loading image...");
dialog.setCancelable(true);
dialog.setIndeterminate(true);
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
dialog.dismiss();
}
#Override
protected void onPreExecute() {
super.onPreExecute();
dialog.show();
}
protected Void doInBackground(Void... arg0) {
try {
InputStream stream = null;
URL url = new URL("http://api.lociiapp.com/TransientStorage/286.jpg");
URLConnection connection = url.openConnection();
try {
HttpURLConnection httpConnection = (HttpURLConnection) connection;
httpConnection.setRequestMethod("GET");
httpConnection.connect();
File SDCardRoot = Environment.getExternalStorageDirectory();
File myDir = new File(SDCardRoot + "/LociiImages");
myDir.mkdirs();
File file = new File(myDir,"test.jpg");
FileOutputStream fileOutput = new FileOutputStream(file);
if (httpConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
stream = httpConnection.getInputStream();
}
byte[] buffer = new byte[1024];
int bufferLength = 0;
while ( (bufferLength = stream.read(buffer)) > 0 ) {
fileOutput.write(buffer, 0, bufferLength);
}
fileOutput.close();
} catch (Exception ex) {
ex.printStackTrace();
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
EDIT
String imagePath = Environment.getExternalStorageDirectory().toString() + "/LociiImages/test.jpg";
Bitmap bitmap = BitmapFactory.decodeFile(imagePath);
imageview.setImageBitmap(bitmap);
I am trying to upload an image from Android directly to Google cloud storage. But the API does not seem to work. They have some Java samples which are tied to the App engine. I don't see any sample which is proven to work on Android.
On Android, I tried using the json api to upload an image. I am able to upload an image object but it seems to be corrupt. Moreover generating the authentication token seems to be tricky too.
I am struck with this right now. Did anyone on this earth ever tried uploading an image/video from Android using Java client or Json API and succeeded? Can someone point me in the right direction please. It has been very disappointing experience with this Storage api from Google. Please share your experiences if someone did it.
Below is the code that I am trying from Android while trying to use the GCS's JSON API.
private static String uploadFile(RichMedia media) {
DefaultHttpClient client = new DefaultHttpClient();
Bitmap bitmap = BitmapUtils.getBitmap(media.getLocalUrl());
HttpPost post = new HttpPost(GCS_ROOT + media.getLocalUrl() + "_" + System.currentTimeMillis());
if(media.getType() == RichMedia.RichMediaType.PICTURE) {
post.setHeader("Content-Type", "image/jpeg");
} else {
post.setHeader("Content-Type", "video/mp4");
}
post.setHeader("Authorization", "AIzaSyCzdmCMwiMzl6LD7R2obF0xSgnnx5rEfeI");
//post.setHeader("Content-Length", String.valueOf(bitmap.getByteCount()));
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
byte[] byteArray = stream.toByteArray();
try {
post.setEntity(new StringEntity(new Gson().toJson(byteArray).toString()));
HttpResponse response = client.execute(post);
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
String eachLine = null;
StringBuilder builder = new StringBuilder();
while ((eachLine = reader.readLine()) != null) {
builder.append(eachLine);
}
L.d("response = " + builder.toString());
JSONObject object = new JSONObject(builder.toString());
String name = object.getString("name");
return name;
} catch (IOException e) {
L.print(e);
} catch (JSONException e) {
L.print(e);
}
return null;
}
I am running into two issues here.
The file which got uploaded to the server is corrupt. It is not the same image that I uploaded. It is currupt.
The authorization key expires very often. In my case, I am using the auth code generated by gsutil.
Since no one is answering this question, let me update the way I solved this problem. I ended up following this https://github.com/pliablematter/simple-cloud-storage project.
I could upload Pictures/Videos to GCS from my Android app.
Fixed for Android:
Android Studio config:
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile files('libs/android-support-v4.jar')
compile files('google-play-services.jar')
compile 'com.wu-man:android-oauth-client:0.0.3'
compile 'com.google.apis:google-api-services-storage:v1-rev17-1.19.0'
compile(group: 'com.google.api-client', name: 'google-api-client', version:'1.19.0'){
exclude(group: 'com.google.guava', module: 'guava-jdk5')
}
}
AndroidManifiest:
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission>
Main implementation:
new AsyncTask(){
#Override
protected Object doInBackground(Object[] params) {
try {
CloudStorage.uploadFile("bucket-xxx", "photo.jpg");
} catch (Exception e) {
if(DEBUG)Log.d(TAG, "Exception: "+e.getMessage());
e.printStackTrace();
}
return null;
}
}.execute();
CloudStorage Class:
import com.google.api.services.storage.Storage;
import com.google.api.services.storage.StorageScopes;
import com.google.api.services.storage.model.Bucket;
import com.google.api.services.storage.model.StorageObject;
public static void uploadFile(String bucketName, String filePath)throws Exception {
Storage storage = getStorage();
StorageObject object = new StorageObject();
object.setBucket(bucketName);
File sdcard = Environment.getExternalStorageDirectory();
File file = new File(sdcard,filePath);
InputStream stream = new FileInputStream(file);
try {
String contentType = URLConnection.guessContentTypeFromStream(stream);
InputStreamContent content = new InputStreamContent(contentType,stream);
Storage.Objects.Insert insert = storage.objects().insert(bucketName, null, content);
insert.setName(file.getName());
insert.execute();
} finally {
stream.close();
}
}
private static Storage getStorage() throws Exception {
if (storage == null) {
HttpTransport httpTransport = new NetHttpTransport();
JsonFactory jsonFactory = new JacksonFactory();
List<String> scopes = new ArrayList<String>();
scopes.add(StorageScopes.DEVSTORAGE_FULL_CONTROL);
Credential credential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(jsonFactory)
.setServiceAccountId(ACCOUNT_ID_PROPERTY) //Email
.setServiceAccountPrivateKeyFromP12File(getTempPkc12File())
.setServiceAccountScopes(scopes).build();
storage = new Storage.Builder(httpTransport, jsonFactory,
credential).setApplicationName(APPLICATION_NAME_PROPERTY)
.build();
}
return storage;
}
private static File getTempPkc12File() throws IOException {
// xxx.p12 export from google API console
InputStream pkc12Stream = AppData.getInstance().getAssets().open("xxx.p12");
File tempPkc12File = File.createTempFile("temp_pkc12_file", "p12");
OutputStream tempFileStream = new FileOutputStream(tempPkc12File);
int read = 0;
byte[] bytes = new byte[1024];
while ((read = pkc12Stream.read(bytes)) != -1) {
tempFileStream.write(bytes, 0, read);
}
return tempPkc12File;
}
This snippet of code works for me great for uploading files from Android directly to GCS.
File file = new File(Environment.getExternalStorageDirectory(), fileName);
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(url);
FileBody filebody = new FileBody(file,ContentType.create(mimeType), file.getName());
MultipartEntityBuilder multipartEntity = MultipartEntityBuilder.create();
multipartEntity.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
multipartEntity.addPart("file", filebody);
httppost.setEntity(multipartEntity.build());
System.out.println( "executing request " + httppost.getRequestLine( ) );
try {
HttpResponse response = httpclient.execute( httppost );
Log.i("response", response.getStatusLine().toString());
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
httpclient.getConnectionManager( ).shutdown( );
MultipartEntityBuilder class is not included into android standard libraries so you need to download httpclient and include into your project.
Hpsaturn's answer worked for me. He missed to answer a few points. How to get service account id and p12 file. For getting these 2, open console.developers.google.com and choose your project. Enable Cloud Storage API. You see a message to create credentials. Go to credentials in API manager and create credential by selecting Service account key and follow the details in image. You will get the service account id and p12 file from this screen.
Hpsaturn also missed to mention AppData, which is your custom Application class defined in manifest. For everyone's convenience, I am attaching the complete CloudStorage class here.
package com.abc.xyz.utils;
import android.net.Uri;
import android.os.Environment;
import android.util.Log;
import com.abc.xyz.app.AppController;
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.InputStreamContent;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.storage.Storage;
import com.google.api.services.storage.StorageScopes;
import com.google.api.services.storage.model.StorageObject;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;
/**
* Created by wjose on 8/20/2016.
*/
public class CloudStorage {
private static final String TAG = "CloudStorage";
public static void uploadFile(String bucketName, String name, Uri uri)throws Exception {
Storage storage = getStorage();
StorageObject object = new StorageObject();
object.setBucket(bucketName);
File sdcard = Environment.getExternalStorageDirectory();
//File file = new File(sdcard,filePath);
File file = new File(uri.getPath());
InputStream stream = new FileInputStream(file);
try {
String contentType = URLConnection.guessContentTypeFromStream(stream);
InputStreamContent content = new InputStreamContent(contentType,stream);
Storage.Objects.Insert insert = storage.objects().insert(bucketName, null, content);
insert.setName(name);
StorageObject obj = insert.execute();
Log.d(TAG, obj.getSelfLink());
} finally {
stream.close();
}
}
static Storage storage = null;
private static Storage getStorage() throws Exception {
if (storage == null) {
HttpTransport httpTransport = new NetHttpTransport();
JsonFactory jsonFactory = new JacksonFactory();
List<String> scopes = new ArrayList<String>();
scopes.add(StorageScopes.DEVSTORAGE_FULL_CONTROL);
Credential credential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(jsonFactory)
.setServiceAccountId("myuser-801#xxxyyyzzz.iam.gserviceaccount.com") //Email
.setServiceAccountPrivateKeyFromP12File(getTempPkc12File())
.setServiceAccountScopes(scopes).build();
storage = new Storage.Builder(httpTransport, jsonFactory,
credential).setApplicationName("MyApp")
.build();
}
return storage;
}
private static File getTempPkc12File() throws IOException {
// xxx.p12 export from google API console
InputStream pkc12Stream = MyApplication.getInstance().getAssets().open("xxxyyyzzz-0c80eed2e8aa.p12");
File tempPkc12File = File.createTempFile("temp_pkc12_file", "p12");
OutputStream tempFileStream = new FileOutputStream(tempPkc12File);
int read = 0;
byte[] bytes = new byte[1024];
while ((read = pkc12Stream.read(bytes)) != -1) {
tempFileStream.write(bytes, 0, read);
}
return tempPkc12File;
}
}
btb, I used only following dependency in the gradle.
compile 'com.google.apis:google-api-services-storage:+'
I have tried all the above answers and none of them worked for me straight out of the box.
Here is what i have done to make it working(only by editing from the above comments):
package Your page name;
import android.app.Activity;
import android.content.res.AssetManager;
import android.os.Environment;
import android.util.Log;
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.InputStreamContent;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.storage.Storage;
import com.google.api.services.storage.StorageScopes;
import com.google.api.services.storage.model.Bucket;
import com.google.api.services.storage.model.StorageObject;
import java.io.File;
import java.io.*;
import java.io.InputStream;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;
public class CloudStorage {
static Activity activity=null;
//http://stackoverflow.com/questions/18002293/uploading-image-from-android-to-gcs
static Storage storage=null;
public static void uploadFile(Activity activity2,String bucketName, String filePath)
{
activity=activity2;
try {
Storage storage = getStorage();
StorageObject object = new StorageObject();
object.setBucket(bucketName);
File sdcard = Environment.getExternalStorageDirectory();
File file = new File(filePath);
InputStream stream = new FileInputStream(file);
try {
Log.d("Alkamli","Test");
String contentType = URLConnection.guessContentTypeFromStream(stream);
InputStreamContent content = new InputStreamContent(contentType, stream);
Storage.Objects.Insert insert = storage.objects().insert(bucketName, null, content);
insert.setName(file.getName());
insert.execute();
} finally {
stream.close();
}
}catch(Exception e)
{
class Local {}; Log.d("Alkamli","Sub: "+Local.class.getEnclosingMethod().getName()+" Error code: "+e.getMessage());
e.printStackTrace();
}
}
private static Storage getStorage() {
try {
if (storage == null)
{
HttpTransport httpTransport = new NetHttpTransport();
JsonFactory jsonFactory = new JacksonFactory();
List<String> scopes = new ArrayList<String>();
scopes.add(StorageScopes.DEVSTORAGE_FULL_CONTROL);
Credential credential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(jsonFactory)
.setServiceAccountId("Service-Email-Address") //Email
.setServiceAccountPrivateKeyFromP12File(getTempPkc12File())
.setServiceAccountScopes(scopes).build();
storage = new Storage.Builder(httpTransport, jsonFactory,
credential)
.build();
}
return storage;
}catch(Exception e)
{
class Local {}; Log.d("Alkamli","Sub: "+Local.class.getEnclosingMethod().getName()+" Error code: "+e.getMessage());
}
Log.d("Alkamli","Storage object is null ");
return null;
}
private static File getTempPkc12File() {
try {
// xxx.p12 export from google API console
InputStream pkc12Stream = activity.getResources().getAssets().open("Service-key.p12");
File tempPkc12File = File.createTempFile("temp_pkc12_file", "p12");
OutputStream tempFileStream = new FileOutputStream(tempPkc12File);
int read = 0;
byte[] bytes = new byte[1024];
while ((read = pkc12Stream.read(bytes)) != -1) {
tempFileStream.write(bytes, 0, read);
}
return tempPkc12File;
}catch(Exception e)
{
class Local {}; Log.d("Alkamli","Sub: "+Local.class.getEnclosingMethod().getName()+" Error code: "+e.getMessage());
}
Log.d("Alkamli"," getTempPkc12File is null");
return null;
}
}
I only edited few lines to make it work for me and for the dependencies in gradle You will need only these three. (Keep in mind that if you use all google depenacnes that may damage your whole project. in my case some of android's functions wouldn't work anymore )
compile 'com.google.api-client:google-api-client:1.20.0'
compile 'com.google.oauth-client:google-oauth-client-jetty:1.20.0'
compile 'com.google.apis:google-api-services-storage:v1-rev17-1.19.0'
The full project for people needing it :
https://github.com/Fahad-alkamli/Chat-app
Not so Surprisingly, none of the solutions above worked for me. The REASON, well in all the above answers they're using the .P12 file, while I got a JSON file as an api key. There are these two different keys which I didn't know at first and I thought I was doing wrong and after one intense day of going through google docs, stackoverflow I was finally able to upload to the storage. None of the above answers show on how to do it for a JSON file and the code is tad bit simple so I'm posting this answers, hope this helps someone:
UploadFile.java
public class UploadFile {
public static Storage setCredentials(InputStream credentialFile) {
InputStream credentialsStream = null;;
Credentials credentials = null;
try {
credentialsStream = credentialFile;
credentials = GoogleCredentials.fromStream(credentialsStream);
} catch (IOException e) {
e.printStackTrace();
return null;
}
return StorageOptions.newBuilder()
.setProjectId("YOUR_PROJECT_ID").setCredentials(credentials)
.build().getService();
}
#RequiresApi(api = Build.VERSION_CODES.O)
public static String transmitImageFile(Storage storage, String srcFileName, String newName) {
File file = new File(srcFileName);
byte[] fileContent = null;
try {
fileContent = Files.readAllBytes(file.toPath());
} catch (IOException e) {
e.printStackTrace();
return null;
}
if (fileContent == null)
return null;
if (fileContent.length == 0)
return null;
BlobInfo.Builder newBuilder = Blob.newBuilder(BucketInfo.of("YOUR_BUCKET_NAME"), newName);
BlobInfo blobInfo = newBuilder.setContentType("image/png").build();
Blob blob = storage.create(blobInfo, fileContent);
String bucket = blob.getBucket();
String contentType = blob.getContentType();
Log.e("TAG", "transmitImageFile: "+contentType);
System.out.println("File " + srcFileName + " uploaded to bucket " + bucket + " as " + newName);
return newName;
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
private String currentPhotoPath;
private String imageName;
public static final int REQUEST_IMAGE_CAPTURE = 1;
private File photoFile = null;
private String[] permissions;
public static final int PERMISSION_REQ_CODE = 200;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textView= findViewById(R.id.textView);
permissions = new String[]{Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.READ_PHONE_STATE, Manifest.permission.ACCESS_COARSE_LOCATION};
PermissionsRequest();
textView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dispatchTakePictureIntent();
ReadFromAsset();
}
});
}
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
try {
photoFile = createImageFile();
} catch (Exception ex) {
ex.printStackTrace();
}
if (photoFile != null) {
Uri photoURI = FileProvider.getUriForFile(this, getPackageName(), photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
String fileName = "temp";
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(imageFileName, ".jpg");
// Save a file: path for use with ACTION_VIEW intents
currentPhotoPath = image.getAbsolutePath();
imageName = image.getName();
return image;
}
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try {
Storage storage = UploadFile.setCredentials(getAssets().open("GoogleMapDemo.json"));
UploadFile.transmitImageFile(storage, currentPhotoPath, "sampleImage.jpg");
} catch (IOException e) {
e.printStackTrace();
}
}
});
thread.start();
Log.e("TAG", "ImagePath: " + currentPhotoPath);
Log.e("TAG", "ImageName: " + imageName);
}
}
private void PermissionsRequest() {
if (ContextCompat.checkSelfPermission(getApplicationContext(), permissions[0]) != PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(getApplicationContext(), permissions[4]) != PackageManager.PERMISSION_GRANTED) {
AlertDialog.Builder builder1 = new AlertDialog.Builder(MainActivity.this);
builder1.setTitle("AAtten");
builder1.setMessage("Permissions");
builder1.setCancelable(false);
builder1.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
acceptPermissions();
}
});
builder1.setNegativeButton("SAIR", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
});
//Creating dialog box
AlertDialog alert1 = builder1.create();
alert1.show();
}
}
private void acceptPermissions() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(getApplicationContext(), permissions[0]) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(getApplicationContext(), permissions[1]) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(getApplicationContext(), permissions[2]) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(getApplicationContext(), permissions[3]) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(getApplicationContext(), permissions[4]) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(getApplicationContext(), permissions[5]) != PackageManager.PERMISSION_GRANTED)
requestPermissions(permissions, PERMISSION_REQ_CODE);
else {
if ((ContextCompat.checkSelfPermission(getApplicationContext(), permissions[0]) != PackageManager.PERMISSION_GRANTED) && (ContextCompat.checkSelfPermission(getApplicationContext(), permissions[1]) != PackageManager.PERMISSION_GRANTED) && (ContextCompat.checkSelfPermission(getApplicationContext(), permissions[2]) != PackageManager.PERMISSION_GRANTED) && (ContextCompat.checkSelfPermission(getApplicationContext(), permissions[3]) != PackageManager.PERMISSION_GRANTED) || ContextCompat.checkSelfPermission(getApplicationContext(), permissions[4]) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(getApplicationContext(), permissions[5]) != PackageManager.PERMISSION_GRANTED)
requestPermissions(permissions, PERMISSION_REQ_CODE);
}
}
}
private void ReadFromAsset(){
String string = "";
try {
//InputStream inputStream = new FileInputStream(String.valueOf(getAssets().open("key.p12")));
InputStream inputStream = getAssets().open("GoogleMapDemo.json");
int size = inputStream.available();
byte[] buffer = new byte[size];
inputStream.read(buffer);
string = new String(buffer);
} catch (IOException e) {
e.printStackTrace();
}
Log.e("TAG", "ReadFromAsset: "+string );
}
}
Now google on how to create a asset folder in the app and add the json key file in that folder. In onActivityResult class you'll pass the name of the json file.
And in UploadImage class give your projectID and bucketName in respective feilds. You can find the projectID in that json.file
Dependencies
android{
packagingOptions{
exclude 'META-INF/INDEX.LIST'
exclude 'META-INF/DEPENDENCIES'
}
}
implementation platform('com.google.cloud:libraries-bom:16.2.1')
implementation 'com.google.cloud:google-cloud-storage'
implementation 'com.google.cloud:google-cloud-core:1.94.0'
Maifest
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE">
<application
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.example.personalgooglestoragecheck"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths" />
</provider>
</application
file-path.xml
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-files-path
name="my_images"
path="/" />
<external-path
name="external"
path="." />
<cache-path
name="cache"
path="." />
<external-cache-path
name="external_cache"
path="." />
<files-path
name="files"
path="." />
</paths>
Hope this helps someone. Any questions feel free to ask.
EDIT 1:
Apparently Files.readAllBytes() is introduced in Java 7 and only works on Android api 26 or above. If you want to target lower versions use fileinputstream and remove all the #requireannotation tags.