In my App Engine backend I have a method that gets an image from Google Cloud Storage
#ApiMethod(
name = "getProfileImage",
path = "image",
httpMethod = ApiMethod.HttpMethod.GET)
public Image getProfileImage(#Named("imageName")String imageName){
try{
HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
GoogleCredential credential = GoogleCredential.getApplicationDefault();
Storage.Builder storageBuilder = new Storage.Builder(httpTransport,new JacksonFactory(),credential);
Storage storage = storageBuilder.build();
Storage.Objects.Get getObject = storage.objects().get("mybucket", imageName);
ByteArrayOutputStream out = new ByteArrayOutputStream();
// If you're not in AppEngine, download the whole thing in one request, if possible.
getObject.getMediaHttpDownloader().setDirectDownloadEnabled(false);
getObject.executeMediaAndDownloadTo(out);
byte[] oldImageData = out.toByteArray();
out.close();
ImagesService imagesService = ImagesServiceFactory.getImagesService();
return ImagesServiceFactory.makeImage(oldImageData);
}catch(Exception e){
logger.info("Error getting image named "+imageName);
}
return null;
}
the issue I am having is how do I get the image data when I call that in my android app?
Since you cant return primitives from app engine I converted it to an Image so that I could call getImageData() in my app to get the byte[].
However the Image object returned to the app is not the same as the one in app engine so there is no getImageData().
How can I get the image data to my android app?
If I create an Object that had a byte[] variable in it then I set the byte[] variable with the string data and return that object from the method will that work?
Update
The image gets sent from the android app. (this code may or may not be correct, I have not debugged it yet)
#WorkerThread
public String startResumableSession(){
try{
File file = new File(mFilePath);
long fileSize = file.length();
file = null;
String sUrl = "https://www.googleapis.com/upload/storage/v1/b/lsimages/o?uploadType=resumable&name="+mImgName;
URL url = new URL(sUrl);
HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
urlConnection.setRequestProperty("Authorization","");
urlConnection.setRequestProperty("X-Upload-Content-Type","image/png");
urlConnection.setRequestProperty("X-Upload-Content-Length",String.valueOf(fileSize));
urlConnection.setRequestMethod("POST");
if(urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK){
return urlConnection.getHeaderField("Location");
}
}catch(Exception e){
e.printStackTrace();
}
return null;
}
private long sendNextChunk(String sUrl,File file,long skip){
int bytesRead, bytesAvailable, bufferSize;
byte[] buffer;
int maxBufferSize = 524287;
long totalBytesSent = 0;
try{
long fileSize = file.length();
FileInputStream fileInputStream = new FileInputStream(file);
skip = fileInputStream.skip(skip);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
totalBytesSent = skip + bufferSize;
buffer = new byte[bufferSize];
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
try {
while (bytesRead > 0) {
try {
URL url = new URL(sUrl);
HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
urlConnection.setDoInput(true);
urlConnection.setDoOutput(true);
urlConnection.setUseCaches(false);
urlConnection.setChunkedStreamingMode(524287);
urlConnection.setRequestMethod("POST");
urlConnection.setRequestProperty("Connection", "Keep-Alive");
urlConnection.setRequestProperty("Content-Type","image/png");
urlConnection.setRequestProperty("Content-Length",String.valueOf(bytesRead));
urlConnection.setRequestProperty("Content-Range", "bytes "+String.valueOf(skip)+"-"+String.valueOf(totalBytesSent)+"/"+String.valueOf(fileSize));
DataOutputStream outputStream = new DataOutputStream(urlConnection.getOutputStream());
outputStream.write(buffer, 0, bufferSize);
int code = urlConnection.getResponseCode();
if(code == 308){
String range = urlConnection.getHeaderField("Range");
return Integer.parseInt(range.split("-")[1]);
}else if(code == HttpURLConnection.HTTP_CREATED){
return -1;
}
outputStream.flush();
outputStream.close();
outputStream = null;
} catch (OutOfMemoryError e) {
e.printStackTrace();
// response = "outofmemoryerror";
// return response;
return -1;
}
fileInputStream.close();
}
} catch (Exception e) {
e.printStackTrace();
// response = "error";
// return response;
return -1;
}
}catch(Exception e){
e.printStackTrace();
}
return -1;
}
Edit 2:
Apparently its not clear to people that I am using Endpoints in my android app
What I ended up doing/finding out that you need to call execute() on the api call with endpoints and it returns the real data passed back from the API
example
The api call returns Image
public Image getProfileImage(#Named("id") long id, #Named("imageName")String imageName){
try{
ProfileRecord pr = get(id);
HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
GoogleCredential credential = GoogleCredential.getApplicationDefault();
Storage.Builder storageBuilder = new Storage.Builder(httpTransport,new JacksonFactory(),credential);
Storage storage = storageBuilder.build();
Storage.Objects.Get getObject = storage.objects().get("mybucket", imageName);
ByteArrayOutputStream out = new ByteArrayOutputStream();
// If you're not in AppEngine, download the whole thing in one request, if possible.
getObject.getMediaHttpDownloader().setDirectDownloadEnabled(false);
getObject.executeMediaAndDownloadTo(out);
byte[] oldImageData = out.toByteArray();
out.close();
return ImagesServiceFactory.makeImage(oldImageData);
}catch(Exception e){
logger.info("Error getting image named "+imageName);
}
return null;
}
then on the client side I would call it like this to get it
Image i = pr.profileImage(id,"name.jpg").execute();
byte[] data = i.decodeImageData();
You can use Google Cloud Endpoints for this:
Google Cloud Endpoints consists of tools, libraries and capabilities
that allow you to generate APIs and client libraries from an App
Engine application, referred to as an API backend, to simplify client
access to data from other applications. Endpoints makes it easier to
create a web backend for web clients and mobile clients such as
Android or Apple's iOS.
see https://cloud.google.com/appengine/docs/java/endpoints/
Related
I'm using an InjectCSS script to use an extra css file on a webview.
But the script takes the CSS file from the assets folder, I want the css file externally hosted.
private void injectCSS() {
try {
InputStream inputStream = getAssets().open("style.css");
byte[] buffer = new byte[inputStream.available()];
inputStream.read(buffer);
inputStream.close();
String encoded = Base64.encodeToString(buffer, Base64.NO_WRAP);
wv.loadUrl("javascript:(function() {" +
"var parent = document.getElementsByTagName('head').item(0);" +
"var style = document.createElement('style');" +
"style.type = 'text/css';" +
// Tell the browser to BASE64-decode the string into your script !!!
"style.innerHTML = window.atob('" + encoded + "');" +
"parent.appendChild(style)" +
"})();");
} catch (Exception e) {
e.printStackTrace();
}
}
I tried to change the inputstream to url but that didnt work.
InputStream inputSteam = new URL("http://www.website.com/folder/style.css").openStream();
If you need to use BASE64-encode, you need this
InputStream inputSteam = new URL("http://www.website.com/folder/style.css").openStream();
String encoded = new String(readBytes(inputStream), Base64.NO_WRAP);
// ...
public byte[] readBytes(InputStream inputStream) throws IOException {
// this dynamically extends to take the bytes you read
ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
// this is storage overwritten on each iteration with bytes
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
// we need to know how may bytes were read to write them to the byteBuffer
int len = 0;
while ((len = inputStream.read(buffer)) != -1) {
byteBuffer.write(buffer, 0, len);
}
// and then we can return your byte array.
return byteBuffer.toByteArray();
}
i'm trying to make a andoid application using youtube.
i'd like to upload a video using URL.
with my codes, i received 200 http status code and success message, but actually it doesn't.
how can i resolve it?
URL url = new URL(urlString);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setRequestMethod("PUT");
conn.setRequestProperty("Authorization", String.format("Bearer %s", access_token));
conn.setRequestProperty("Content-Type", "video/*");
conn.setRequestProperty("Content-Length", ContentLength);
File file = new File(path);
FileInputStream fis = new FileInputStream(file);
DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
int numberBytes = fis.available();
byte bytearray[] = new byte[numberBytes];
Log.e(" FileLength", String.valueOf(bytearray.length));
for(int i = 0; i < bytearray.length; i++)
dos.write(bytearray[i]);
dos.flush();
fis.close();
dos.close();
int responseCode = conn.getResponseCode();
if(responseCode == 200) {
Log.e("ResponseCode", String.valueOf(responseCode));
InputStream is = conn.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] byteBuffer = new byte[1024];
byte[] byteData = null;
int nLength = 0;
while((nLength = is.read(byteBuffer, 0, byteBuffer.length)) != -1) {
baos.write(byteBuffer, 0, nLength);
}
byteData = baos.toByteArray();
String response = new String(byteData);
Log.e("RESPONSE", response);
}
} catch(Exception e) {
e.printStackTrace();
}
Use this library project
The code is a reference implementation for an Android OS application that captures video, uploads it to YouTube,
Detailed Answer: uploading using above library project
I've made I simple function to write from URL to file. Everything works good until out.write(), I mean there's no exception, but it just doesn't write anything to file
Here's code
private boolean getText(String url, String name) throws IOException {
if(url!=null){
FileWriter fstream = new FileWriter(PATH+"/"+name+".txt");
BufferedWriter out = new BufferedWriter(fstream);
URL _url = new URL(url);
int code = ((HttpURLConnection) _url.openConnection()).getResponseCode();
if(code==200){
URLConnection urlConnection = _url.openConnection(); //
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
int bytesRead = 0;
byte[] buffer = new byte[1024];
while ((bytesRead = in.read(buffer)) != -1) {
String chunk = new String(buffer, 0, bytesRead);
out.write(chunk);
}
return true;
}
out.close();
}
return false;
}
Can someone tell me what's wrong please?
Try fstream.flush().
Also out.close() should be called before returning from a function.
I need to download a single image at time from the Internet and then save it on the SD card. How do I do it? I have made an attempt, but when I try to view that downloaded image, it shows the message, "No Preview Available". Please see my code below:
public class ImgDownloader {
private static final int IO_BUFFER_SIZE = 4 * 1024;
public static final byte[] downloadImage(String imgURL) {
byte[] data = null;
try {
Log.v("Down", "1");
InputStream in = null;
BufferedOutputStream out = null;
in = new BufferedInputStream(new URL(imgURL).openStream(), 8 * 1024);
Log.v("Down", "2");
final ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
out = new BufferedOutputStream(dataStream, IO_BUFFER_SIZE);
copy(in, out);
out.flush();
Log.v("Down", "3");
data = dataStream.toByteArray();
// bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
Log.v("Down", "4");
} catch (Exception ex) {
ex.printStackTrace();
// System.out.println("Exception in Image Downloader .."
// +ex.getMessage());
}
return data;
}
private static void copy(InputStream in, OutputStream out)
throws IOException {
byte[] b = new byte[IO_BUFFER_SIZE];
int read;
while ((read = in.read(b)) != -1) {
out.write(b, 0, read);
}
}
}
Note:
i have download the image from the SSL connection.
Any ideas? Thanks in advance.
You can try something like
try{
URL url = new URL(downloadUrl); //you can write here any link
File file = new File(absolutePath); //Something like ("/sdcard/file.mp3")
//Create parent directory if it doesn't exists
if(!new File(file.getParent()).exists())
{
System.out.println("Path is created " + new File(file.getParent()).mkdirs());
}
file = new File(absolutePath); //Something like ("/sdcard/file.mp3")
file.createNewFile();
/* Open a connection to that URL. */
URLConnection ucon = url.openConnection();
/*
* Define InputStreams to read from the URLConnection.
*/
InputStream is = ucon.getInputStream();
/*
* Read bytes to the Buffer until there is nothing more to read(-1).
*/
FileOutputStream fos = new FileOutputStream(file);
int size = 1024*1024;
byte[] buf = new byte[size];
int byteRead;
while (((byteRead = is.read(buf)) != -1)) {
fos.write(buf, 0, byteRead);
bytesDownloaded += byteRead;
}
/* Convert the Bytes read to a String. */
fos.close();
}catch(IOException io)
{
networkException = true;
continueRestore = false;
}
catch(Exception e)
{
continueRestore = false;
e.printStackTrace();
}
Make the appropriate changes according to your requirement. I use the same code for downloading files from internet and saving it to SDCard.
Hope it helps !!
How can I call a Webservice with a byte[] parameter? Tried using the namedvaluepairs, but they take strings only. I am not using the Ksoap2, we decided to use the HttpClient / HttpPost method.
Anyone have any ideas?
Here is my code:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// WORKS WITH JPEG FILE -- String existingFileName = "/sdcard/dcim/Camera/1225231027592.jpg";
String existingFileName = "/sdcard/dcim/0217175.jpg";
String mMyFilename = "0217175.jpg";
// /sdcard/Music/kryptonite.mp3"; //DOES NOT WORK WITH MP3 FILE
File uploadFile = new File(existingFileName);
FileInputStream fileInputStream = null;
try {
fileInputStream = new FileInputStream(uploadFile);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
String mTest;
String Method = null;
try
{
//********************************************************************
// Create the HttpClient and the HttpPost
// Note: Need to use HttpPost because of arguments/parameters
//********************************************************************
HttpClient client = new DefaultHttpClient();
HttpPost request = new HttpPost();
fileInputStream = new FileInputStream(uploadFile);
// create a buffer of maximum size
int bytesAvailable = fileInputStream.available();
int maxBufferSize = 1024;
int bufferSize = Math.min(bytesAvailable, maxBufferSize);
byte[] buffer = new byte[bufferSize];
// read file and write it into form...
int bytesRead = fileInputStream.read(buffer, 0, bufferSize);
//*************************************************************
//Add Value Pairs for Parameters to pass to the Webservice
//*************************************************************
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
//nameValuePairs.add(new BasicNameValuePair(buffer));
nameValuePairs.add(new BasicNameValuePair("filename", mMyFilename));
}
catch (MalformedURLException ex) {
// Log.e(Tag, "error: " + ex.getMessage(), ex);
}
catch (IOException ioe) {
String s = "";
//Log.e(Tag, "error: " + ioe.getMessage(), ioe);
}
}
}
The Web Service:
[WebMethod]
public void PutFile(byte[] buffer, string filename)
{
string serverpath;
//serverpath = #"\\63.237.52.201\UploadFiles\Incoming\";
serverpath = #"C:\Temp\";
//BinaryWriter binWriter = new BinaryWriter(File.Open(Server.MapPath(filename), FileMode.CreateNew, FileAccess.ReadWrite));
BinaryWriter binWriter = new BinaryWriter(File.Open(serverpath + filename, FileMode.CreateNew, FileAccess.ReadWrite));
binWriter.Write(buffer);
binWriter.Close();
}
You could convert it to a base64 representation and send the byte[] as an string. Then recover it at the server side. Just in case you don't find a better approach.