Uploading image from Android to GCS - android

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.

Related

PDF printing view issue

I have tried in two ways,
1) Am creating a WebView and loading my pdf document, and my application is almost done with its part of the printing process. But in that am facing printing issue.
Its not with full A4 sheet view.Can anyone please help,The following code i have used,
public void createWebPagePrint(WebView webView) {
PrintManager printManager = (PrintManager) getSystemService(Context.PRINT_SERVICE);
PrintDocumentAdapter printAdapter = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
printAdapter = webView.createPrintDocumentAdapter();
String jobName = getString(R.string.app_name) + " Document";
PrintAttributes.Builder builder = null;
builder = new PrintAttributes.Builder();
builder.setMediaSize(PrintAttributes.MediaSize.ISO_A4);
PrintJob printJob = null;
printJob = printManager.print(jobName, printAdapter, builder.build());
if (printJob.isCompleted()) {
Toast.makeText(getApplicationContext(), "Print Complete", Toast.LENGTH_LONG).show();
} else if (printJob.isFailed()) {
Toast.makeText(getApplicationContext(), "Print Failed", Toast.LENGTH_LONG).show();
}
builder.setMediaSize(PrintAttributes.MediaSize.ISO_A4)
.setResolution(new PrintAttributes.Resolution("id", Context.PRINT_SERVICE, 1024, 720))
.setColorMode(PrintAttributes.COLOR_MODE_COLOR).
setMinMargins(PrintAttributes.Margins.NO_MARGINS).build();
}
}
Note:
https://developer.android.com/training/printing/html-docs.html
And some times while loading pdf its not displaying.
2) I have tried using with pdf view lib ,
compile 'com.github.barteksc:android-pdf-viewer:2.8.2'
But that time am getting better view compared to webview. The problem is only visible view is drawing on canvas.The print view is not clear.Its not readable.I have given the page count, So according to the page count its repeating the pages but print view is same as in first page.The following view am getting while printing.
This is my sample code,
code
If anyone know please help me.
The above procedure is very hard.Even am not getting solution for that.After that i come up with a solution and its working perfectly for me.
1) To view PDF file no need to load with webview or external pdf libraries.Just download the pdf file and view it with default pdf viewer.The below code i have used,
To download a file,
import android.app.Activity;
import android.util.Log;
import java.io.File;
import java.io.FileNotFoundException;
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 FileDownloader {
private static final int MEGABYTE = 1024 * 1024;
public static void downloadFile(String fileUrl, File directory, Activity activity){
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();
}
}
}
private class DownloadFile extends AsyncTask<String, Void, Void> {
#Override
protected Void doInBackground(String... strings) {
String fileUrl = strings[0];
String fileName = strings[1];
String extStorageDirectory = Environment.getExternalStorageDirectory().toString();
File folder = new File(extStorageDirectory, "Test");
folder.mkdir();
File pdfFile = new File(folder, fileName);
try {
pdfFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
FileDownloader.downloadFile(fileUrl, pdfFile,InventoryStockActivity.this);
return null;
}
}
public void download(String viewUrl) {
new DownloadFile().execute(viewUrl, "Test.pdf");
Log.d("Download complete", "----------");
}
To view a pdf file;
public void view() {
File pdfFile = new File(Environment.getExternalStorageDirectory() + "/Test/" + "Test.pdf");
Uri path = Uri.fromFile(pdfFile);
Intent pdfIntent = new Intent(Intent.ACTION_VIEW);
pdfIntent.setDataAndType(path, "application/pdf");
pdfIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
try {
startActivity(pdfIntent);
} catch (ActivityNotFoundException e) {
Toast.makeText(InventoryStockActivity.this, "No Application available to view PDF", Toast.LENGTH_SHORT).show();
}
}
In manifest,
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
And when its open default pdf viewer, there will be print menu.Just print from there.

Writing to a file, but file is empty when I read it in [duplicate]

I want to save a file to the internal storage by getting the text inputted from EditText. Then I want the same file to return the inputted text in String form and save it to another String which is to be used later.
Here's the code:
package com.omm.easybalancerecharge;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.telephony.TelephonyManager;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final EditText num = (EditText) findViewById(R.id.sNum);
Button ch = (Button) findViewById(R.id.rButton);
TelephonyManager operator = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
String opname = operator.getNetworkOperatorName();
TextView status = (TextView) findViewById(R.id.setStatus);
final EditText ID = (EditText) findViewById(R.id.IQID);
Button save = (Button) findViewById(R.id.sButton);
final String myID = ""; //When Reading The File Back, I Need To Store It In This String For Later Use
save.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
//Get Text From EditText "ID" And Save It To Internal Memory
}
});
if (opname.contentEquals("zain SA")) {
status.setText("Your Network Is: " + opname);
} else {
status.setText("No Network");
}
ch.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
//Read From The Saved File Here And Append It To String "myID"
String hash = Uri.encode("#");
Intent intent = new Intent(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:*141*" + /*Use The String With Data Retrieved Here*/ num.getText()
+ hash));
startActivity(intent);
}
});
}
I have included comments to help you further analyze my points as to where I want the operations to be done/variables to be used.
Hope this might be useful to you.
Write File:
private void writeToFile(String data,Context context) {
try {
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(context.openFileOutput("config.txt", Context.MODE_PRIVATE));
outputStreamWriter.write(data);
outputStreamWriter.close();
}
catch (IOException e) {
Log.e("Exception", "File write failed: " + e.toString());
}
}
Read File:
private String readFromFile(Context context) {
String ret = "";
try {
InputStream inputStream = context.openFileInput("config.txt");
if ( inputStream != null ) {
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String receiveString = "";
StringBuilder stringBuilder = new StringBuilder();
while ( (receiveString = bufferedReader.readLine()) != null ) {
stringBuilder.append("\n").append(receiveString);
}
inputStream.close();
ret = stringBuilder.toString();
}
}
catch (FileNotFoundException e) {
Log.e("login activity", "File not found: " + e.toString());
} catch (IOException e) {
Log.e("login activity", "Can not read file: " + e.toString());
}
return ret;
}
For those looking for a general strategy for reading and writing a string to file:
First, get a file object
You'll need the storage path. For the internal storage, use:
File path = context.getFilesDir();
For the external storage (SD card), use:
File path = context.getExternalFilesDir(null);
Then create your file object:
File file = new File(path, "my-file-name.txt");
Write a string to the file
FileOutputStream stream = new FileOutputStream(file);
try {
stream.write("text-to-write".getBytes());
} finally {
stream.close();
}
Or with Google Guava
String contents = Files.toString(file, StandardCharsets.UTF_8);
Read the file to a string
int length = (int) file.length();
byte[] bytes = new byte[length];
FileInputStream in = new FileInputStream(file);
try {
in.read(bytes);
} finally {
in.close();
}
String contents = new String(bytes);
Or if you are using Google Guava
String contents = Files.toString(file,"UTF-8");
For completeness I'll mention
String contents = new Scanner(file).useDelimiter("\\A").next();
which requires no libraries, but benchmarks 50% - 400% slower than the other options (in various tests on my Nexus 5).
Notes
For each of these strategies, you'll be asked to catch an IOException.
The default character encoding on Android is UTF-8.
If you are using external storage, you'll need to add to your manifest either:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
or
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Write permission implies read permission, so you don't need both.
public static void writeStringAsFile(final String fileContents, String fileName) {
Context context = App.instance.getApplicationContext();
try {
FileWriter out = new FileWriter(new File(context.getFilesDir(), fileName));
out.write(fileContents);
out.close();
} catch (IOException e) {
Logger.logError(TAG, e);
}
}
public static String readFileAsString(String fileName) {
Context context = App.instance.getApplicationContext();
StringBuilder stringBuilder = new StringBuilder();
String line;
BufferedReader in = null;
try {
in = new BufferedReader(new FileReader(new File(context.getFilesDir(), fileName)));
while ((line = in.readLine()) != null) stringBuilder.append(line);
} catch (FileNotFoundException e) {
Logger.logError(TAG, e);
} catch (IOException e) {
Logger.logError(TAG, e);
}
return stringBuilder.toString();
}
Just a a bit modifications on reading string from a file method for more performance
private String readFromFile(Context context, String fileName) {
if (context == null) {
return null;
}
String ret = "";
try {
InputStream inputStream = context.openFileInput(fileName);
if ( inputStream != null ) {
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
int size = inputStream.available();
char[] buffer = new char[size];
inputStreamReader.read(buffer);
inputStream.close();
ret = new String(buffer);
}
}catch (Exception e) {
e.printStackTrace();
}
return ret;
}
The Kotlin way by using builtin Extension function on File
Write: yourFile.writeText(textFromEditText)
Read: yourFile.readText()
check the below code.
Reading from a file in the filesystem.
FileInputStream fis = null;
try {
fis = context.openFileInput(fileName);
InputStreamReader isr = new InputStreamReader(fis);
// READ STRING OF UNKNOWN LENGTH
StringBuilder sb = new StringBuilder();
char[] inputBuffer = new char[2048];
int l;
// FILL BUFFER WITH DATA
while ((l = isr.read(inputBuffer)) != -1) {
sb.append(inputBuffer, 0, l);
}
// CONVERT BYTES TO STRING
String readString = sb.toString();
fis.close();
catch (Exception e) {
} finally {
if (fis != null) {
fis = null;
}
}
below code is to write the file in to internal filesystem.
FileOutputStream fos = null;
try {
fos = context.openFileOutput(fileName, Context.MODE_PRIVATE);
fos.write(stringdatatobestoredinfile.getBytes());
fos.flush();
fos.close();
} catch (Exception e) {
} finally {
if (fos != null) {
fos = null;
}
}
I think this will help you.
I'm a bit of a beginner and struggled getting this to work today.
Below is the class that I ended up with. It works but I was wondering how imperfect my solution is. Anyway, I was hoping some of you more experienced folk might be willing to have a look at my IO class and give me some tips. Cheers!
public class HighScore {
File data = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator);
File file = new File(data, "highscore.txt");
private int highScore = 0;
public int readHighScore() {
try {
BufferedReader br = new BufferedReader(new FileReader(file));
try {
highScore = Integer.parseInt(br.readLine());
br.close();
} catch (NumberFormatException | IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
try {
file.createNewFile();
} catch (IOException ioe) {
ioe.printStackTrace();
}
e.printStackTrace();
}
return highScore;
}
public void writeHighScore(int highestScore) {
try {
BufferedWriter bw = new BufferedWriter(new FileWriter(file));
bw.write(String.valueOf(highestScore));
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Kotlin
class FileReadWriteService {
private var context:Context? = ContextHolder.instance.appContext
fun writeFileOnInternalStorage(fileKey: String, sBody: String) {
val file = File(context?.filesDir, "files")
try {
if (!file.exists()) {
file.mkdir()
}
val fileToWrite = File(file, fileKey)
val writer = FileWriter(fileToWrite)
writer.append(sBody)
writer.flush()
writer.close()
} catch (e: Exception) {
Logger.e(classTag, e)
}
}
fun readFileOnInternalStorage(fileKey: String): String {
val file = File(context?.filesDir, "files")
var ret = ""
try {
if (!file.exists()) {
return ret
}
val fileToRead = File(file, fileKey)
val reader = FileReader(fileToRead)
ret = reader.readText()
reader.close()
} catch (e: Exception) {
Logger.e(classTag, e)
}
return ret
}
}
the first thing we need is the permissions in AndroidManifest.xml
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
so in an asyncTask Kotlin class, we treat the creation of the file
import android.os.AsyncTask
import android.os.Environment
import android.util.Log
import java.io.*
class WriteFile: AsyncTask<String, Int, String>() {
private val mFolder = "/MainFolder"
lateinit var folder: File
internal var writeThis = "string to cacheApp.txt"
internal var cacheApptxt = "cacheApp.txt"
override fun doInBackground(vararg writethis: String): String? {
val received = writethis[0]
if(received.isNotEmpty()){
writeThis = received
}
folder = File(Environment.getExternalStorageDirectory(),"$mFolder/")
if(!folder.exists()){
folder.mkdir()
val readME = File(folder, cacheApptxt)
val file = File(readME.path)
val out: BufferedWriter
try {
out = BufferedWriter(FileWriter(file, true), 1024)
out.write(writeThis)
out.newLine()
out.close()
Log.d("Output_Success", folder.path)
} catch (e: Exception) {
Log.d("Output_Exception", "$e")
}
}
return folder.path
}
override fun onPostExecute(result: String) {
super.onPostExecute(result)
if(result.isNotEmpty()){
//implement an interface or do something
Log.d("onPostExecuteSuccess", result)
}else{
Log.d("onPostExecuteFailure", result)
}
}
}
Of course if you are using Android above Api 23, you must handle the request to allow writing to device memory. Something like this
import android.Manifest
import android.content.Context
import android.content.pm.PackageManager
import android.os.Build
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
class ReadandWrite {
private val mREAD = 9
private val mWRITE = 10
private var readAndWrite: Boolean = false
fun readAndwriteStorage(ctx: Context, atividade: AppCompatActivity): Boolean {
if (Build.VERSION.SDK_INT < 23) {
readAndWrite = true
} else {
val mRead = ContextCompat.checkSelfPermission(ctx, Manifest.permission.READ_EXTERNAL_STORAGE)
val mWrite = ContextCompat.checkSelfPermission(ctx, Manifest.permission.WRITE_EXTERNAL_STORAGE)
if (mRead != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(atividade, arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), mREAD)
} else {
readAndWrite = true
}
if (mWrite != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(atividade, arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), mWRITE)
} else {
readAndWrite = true
}
}
return readAndWrite
}
}
then in an activity, execute the call.
var pathToFileCreated = ""
val anRW = ReadandWrite().readAndwriteStorage(this,this)
if(anRW){
pathToFileCreated = WriteFile().execute("onTaskComplete").get()
Log.d("pathToFileCreated",pathToFileCreated)
}
We can use this code to write String to a file
public static void writeTextToFile(final String filename, final String data) {
File file = new File(filename);
try {
FileOutputStream stream = new FileOutputStream(file);
stream.write(data.getBytes());
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Then in the Main code, we use this, for example
writeTextToFile(getExternalFilesDir("/").getAbsolutePath() + "/output.txt", "my-example-text");
After that, check the file at Android/data/<package-name>/files.
The easiest way to append to a text file in kotlin:
val directory = File(context.filesDir, "LogsToSendToNextMunich").apply {
mkdirs()
}
val file = File(directory,"Logs.txt")
file.appendText("You new text")
If you want to just write to the file:
yourFile.writeText("You new text")
writing anything to the files, using bytes:
FileOutputStream(file).use {
it.write("Some text for example".encodeToByteArray())
}

post image in Instagram

Question : In my app I need to post image in Instagram just like FB or Twitter.
What I have already done : Login and fetched photographs from the Instagram to my own app. But not getting any way for image posting in Instagram.
Yet it is not possible to post image in Instagram like FB or twitter.
But this is another way to achieve this using already installed Instagram and if not this will notify user to download app .
public void onClick(View v) {
Intent intent = getPackageManager().getLaunchIntentForPackage("com.instagram.android");
if (intent != null)
{
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.setPackage("com.instagram.android");
try {
shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse(MediaStore.Images.Media.insertImage(getContentResolver(), imagePath, "I am Happy", "Share happy !")));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
shareIntent.setType("image/jpeg");
startActivity(shareIntent);
}
else
{
// bring user to the market to download the app.
// or let them choose an app?
intent = new Intent(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setData(Uri.parse("market://details?id="+"com.instagram.android"));
startActivity(intent);
}
}
No, you can't. Quoted from Instagram API docs :
At this time, uploading via the API is not possible. We made a conscious choice not to add this for the following reasons:
Instagram is about your life on the go – we hope to encourage photos from within the app. However, in the future we may give whitelist access to individual apps on a case by case basis.
We want to fight spam & low quality photos. Once we allow uploading from other sources, it's harder to control what comes into the Instagram ecosystem. All this being said, we're working on ways to ensure users have a consistent and high-quality experience on our platform.
UPDATE: However, if you're working on iOS (though you tagged Android), there is a way to "send" a photo (in fact, it opens the image in Instagram) via Custom URL Scheme. See this.
Try this link :
You can use this class to upload image to instagram.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpCookie;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Date;
import java.util.List;
import java.util.Map;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.net.ssl.HttpsURLConnection;
import org.apache.commons.codec.binary.Hex;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
public class InstagramPostHelper {
private static InstagramPostHelper instance = null;
protected InstagramPostHelper() {}
public static InstagramPostHelper getInstance() {
if (instance == null) {
instance = new InstagramPostHelper();
}
return instance;
}
private String GenerateSignature(String value, String key)
{
String result = null;
try {
byte[] keyBytes = key.getBytes();
SecretKeySpec signingKey = new SecretKeySpec(keyBytes, "HmacSHA256");
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(signingKey);
byte[] rawHmac = mac.doFinal(value.getBytes());
byte[] hexBytes = new Hex().encode(rawHmac);
result = new String(hexBytes, "UTF-8");
}
catch (Exception e) {
}
return result;
}
private static final String COOKIES_HEADER = "Set-Cookie";
public static java.net.CookieManager msCookieManager = new java.net.CookieManager();
private HttpsURLConnection conn;
private static String TextUtilsJoin(CharSequence delimiter, List<HttpCookie> list) {
StringBuilder sb = new StringBuilder();
boolean firstTime = true;
for (Object token: list) {
if (token.toString().trim().length()<1) continue;
if (firstTime) {
firstTime = false;
} else {
sb.append(delimiter + " ");
}
sb.append(token);
}
return sb.toString();
}
private String GetJSONStringAndPostData(String jsonaddress,String postdata,String agent)
{
String sonuc = "";
try {
byte[] postDataBytes = postdata.toString().getBytes("UTF-8");
URL url = new URL(jsonaddress);
conn = (HttpsURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length));
conn.setRequestProperty("User-Agent", agent);
//Set Cookies
if(msCookieManager.getCookieStore().getCookies().size() > 0)
{
conn.setRequestProperty("Cookie", TextUtilsJoin(";", msCookieManager.getCookieStore().getCookies()));
}
conn.setDoOutput(true);
conn.getOutputStream().write(postDataBytes);
if (conn.getResponseCode() != 200) {
throw new RuntimeException("Failed : HTTP error code : "
+ conn.getResponseCode());
}
//Get Cookies
Map<String, List<String>> headerFields = conn.getHeaderFields();
List<String> cookiesHeader = headerFields.get(COOKIES_HEADER);
if(cookiesHeader != null)
{
for (String cookie : cookiesHeader)
{
msCookieManager.getCookieStore().add(null,HttpCookie.parse(cookie).get(0));
}
}
BufferedReader br = new BufferedReader(new InputStreamReader(
(conn.getInputStream())));
String output;
while ((output = br.readLine()) != null) {
sonuc += output;
}
conn.disconnect();
} catch (MalformedURLException e) {
return "";
} catch (IOException e) {
return "";
}
return sonuc;
}
public void SendImage(String Caption,byte[] ImageByteArray) throws UnsupportedEncodingException, ParseException
{
String Agent = "Instagram 6.21.2 Android (19/4.4.2; 480dpi; 1152x1920; Meizu; MX4; mx4; mt6595; en_US)";
String Guid = java.util.UUID.randomUUID().toString();
String DeviceId = "android-" + Guid;
String Data = "{\"device_id\":\"" + DeviceId + "\",\"guid\":\"" + Guid + "\",\"username\":\"MYUSERNAME\",\"password\":\"MYPASSWORD\",\"Content-Type\":\"application/x-www-form-urlencoded; charset=UTF-8\"}";
String Sig = GenerateSignature(Data, "25eace5393646842f0d0c3fb2ac7d3cfa15c052436ee86b5406a8433f54d24a5");
Data = "signed_body=" + Sig + "." + URLEncoder.encode(Data, "UTF-8") + "&ig_sig_key_version=4";
if (msCookieManager.getCookieStore()!= null)
{
msCookieManager.getCookieStore().removeAll();
}
//Login Request
String login = GetJSONStringAndPostData("https://instagram.com/api/v1/accounts/login/", Data,Agent);
JSONParser parser = new JSONParser();
Object obj = parser.parse(login);
JSONObject jsonObject = (JSONObject) obj;
if (((String) jsonObject.get("status")).equals("ok")) //Login SuccessFul
{
//Login Successful
System.out.println("Login Successful !");
//Post Image
String upload = "";
try {
final HttpMultipartHelper http = new HttpMultipartHelper(new URL("https://instagram.com/api/v1/media/upload/"));
http.addFormField("device_timestamp", Long.toString((new Date()).getTime()));
http.addFilePart("photo", ImageByteArray);
final byte[] bytes = http.finish();
upload = new String(bytes);
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(upload);
obj = parser.parse(upload);
jsonObject = (JSONObject) obj;
if (((String) jsonObject.get("status")).equals("ok")) //Login SuccessFul
{
String mediaID = (String) jsonObject.get("media_id");
Data = "{\"device_id\":\"" + DeviceId + "\",\"guid\":\"" + Guid + "\",\"media_id\":\"" + mediaID + "\",\"caption\":\"" + Caption + "\",\"device_timestamp\":\"" + Long.toString((new Date()).getTime()).substring(0,10) + "\",\"source_type\":\"5\",\"filter_type\":\"0\",\"extra\":\"{}\",\"Content-Type\":\"application/x-www-form-urlencoded; charset=UTF-8\"}";
Sig = GenerateSignature(Data, "25eace5393646842f0d0c3fb2ac7d3cfa15c052436ee86b5406a8433f54d24a5");
Data = "signed_body=" + Sig + "." + URLEncoder.encode(Data, "UTF-8") + "&ig_sig_key_version=6";
//Login Request
System.out.println(Data);
String result = GetJSONStringAndPostData("https://instagram.com/api/v1/media/configure/", Data,Agent);
System.out.println(result);
}
}
else //Login UnsuccessFul
{
System.out.println("Login Unsuccessful !" + login);
}
}
}
https://gist.github.com/ecdundar/d5b6bdcc2035448fc9cd
It seems we're now able to do it, for more you can check official docs here
Try this
public void ShareInsta() {
File dir = new File(Environment.getExternalStorageDirectory(), "FolderName");
File imgFile = new File(dir, "0.png");
Intent sendIntent = new Intent(Intent.ACTION_VIEW);
sendIntent.setType("image/*");
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + imgFile));
sendIntent.putExtra(Intent.EXTRA_TEXT, "<---MY TEXT--->.");
sendIntent.setPackage("com.instagram.android");
sendIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
try {
startActivity(Intent.createChooser(sendIntent, "Share images..."));
} catch (android.content.ActivityNotFoundException ex) {
Toast.makeText(SaveAndShareActivity.this, "Please Install Instagram", Toast.LENGTH_LONG).show();
}
}

Unable to download file created by my app on Google Drive, But can get the metadata of that file

I followed all the steps mentioned in google drive sdk. I created a sample application on my device(android, running jelly bean) and am able to upload a file on to drive. When trying to download the same file, I am able to get the meta data like fileID, fileTitle, fileDownloadURL etc but not able to download the content. I get 401 Unauthorized error.
My app AUTH SCOPE is AUTH_TOKEN_TYPE = "oauth2:https://www.googleapis.com/auth/drive.file";
I am doing the following to get the OAUTH Token:
AccountManager am = AccountManager.get(this);
Bundle options = new Bundle();
am.getAuthToken(
mAccount,
AUTH_TOKEN_TYPE,
options,
this,
new OnTokenAcquired(),
new Handler(){
#Override
public void handleMessage(Message msg) {
invadiateToken();
super.handleMessage(msg);
}
});
Based on the token this is how I build the Drive object
Drive buildService(final String AuthToken) {
HttpTransport httpTransport = new NetHttpTransport();
JacksonFactory jsonFactory = new JacksonFactory();
Drive.Builder b = new Drive.Builder(httpTransport, jsonFactory, null);
b.setJsonHttpRequestInitializer(new JsonHttpRequestInitializer() {
#Override
public void initialize(JsonHttpRequest request) throws IOException {
DriveRequest driveRequest = (DriveRequest) request;
driveRequest.setPrettyPrint(true);
driveRequest.setKey(API_KEY);
driveRequest.setOauthToken(AuthToken);
}
});
return b.build();
}
I am able to upload the file using the following code:
private void uploadLocalFileToDrive(Drive service) throws IOException{
// File's metadata.
String mimeType = "text/plain";
File body = new File();
body.setTitle("myText.txt");
body.setDescription("sample app by varun");
body.setMimeType("text/plain");
// File's content.
java.io.File fileContent = new java.io.File(mInternalFilePath);
FileContent mediaContent = new FileContent(mimeType, fileContent);
service.files().insert(body, mediaContent).execute();
}
While trying to download the same file uploaded by this app, I get a 401 unauthorized error at this line HttpResponse resp = service.getRequestFactory().buildGetRequest(url).execute() from the following code snippet
private void downloadFileFromDrive(Drive service) throws IOException {
Files.List request;
request = service.files().list();
do {
FileList files = request.execute();
for(File file:files.getItems()){
String fieldId = file.getId();
String title = file.getTitle();
Log.e("MS", "MSV:: Title-->"+title+" FieldID-->"+fieldId+" DownloadURL-->"+file.getDownloadUrl());
if (file.getDownloadUrl() != null && file.getDownloadUrl().length() > 0 ) {
GenericUrl url = new GenericUrl(file.getDownloadUrl());
HttpResponse resp = service.getRequestFactory().buildGetRequest(url).execute();
InputStream isd = resp.getContent();
Log.e("MS", "MSV:: FileOutPutStream--->"+getFilesDir().getAbsolutePath()+"/downloaded.txt");
} else {
Log.e("MS", "MSV:: downloadURL for this file is null");
}
}
request.setPageToken(files.getNextPageToken());
} while (request.getPageToken()!=null && request.getPageToken().length()>0);
}
Can anyone help me out and let me know what I am doing wrong???
This is a known issue that will be resolved with the release of the Google Play Services APIs.
Since your application is authorized for the https://www.googleapis.com/auth/drive.file scope, and the download endpoint doesn't support the ?key= query parameter, there is no way for our server to know which project is issuing the request (to make sure the app has authorization to read this file's content).
In the meantime, the only workaround I can recommend is using the broad scope: https://www.googleapis.com/auth/drive. Please use only that while developing your application and waiting for the Google Play Services to be released.
To learn more about how you will be able to use the new authorization APIs in Android, you might be interested in those 2 Google I/O talks: Building Android Applications that Use Web APIs and
Writing Efficient Drive Apps for Android
I have answered this question, and all related Drive on Android questions, over here:
Android Open and Save files to/from Google Drive SDK
In that answer, I posted code for a method that I used to download files from Google Drive (if the following code by itself isn't clear, have a look at the complete answer that I linked to.)
private java.io.File downloadGFileToJFolder(Drive drive, String token, File gFile, java.io.File jFolder) throws IOException {
if (gFile.getDownloadUrl() != null && gFile.getDownloadUrl().length() > 0 ) {
if (jFolder == null) {
jFolder = Environment.getExternalStorageDirectory();
jFolder.mkdirs();
}
try {
HttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet(gFile.getDownloadUrl());
get.setHeader("Authorization", "Bearer " + token);
HttpResponse response = client.execute(get);
InputStream inputStream = response.getEntity().getContent();
jFolder.mkdirs();
java.io.File jFile = new java.io.File(jFolder.getAbsolutePath() + "/" + getGFileName(gFile)); // getGFileName() is my own method... it just grabs originalFilename if it exists or title if it doesn't.
FileOutputStream fileStream = new FileOutputStream(jFile);
byte buffer[] = new byte[1024];
int length;
while ((length=inputStream.read(buffer))>0) {
fileStream.write(buffer, 0, length);
}
fileStream.close();
inputStream.close();
return jFile;
} catch (IOException e) {
// Handle IOExceptions here...
return null;
}
} else {
// Handle the case where the file on Google Drive has no length here.
return null;
}
}
I don't think we need any Access Token to download a file. I had the same problem, and this worked:
private class DownloadFile extends AsyncTask<Void, Long, Boolean> {
private com.google.api.services.drive.model.File driveFile;
private java.io.File file;
public DownloadFile(File driveFile) {
this.driveFile = driveFile;
}
#Override
protected Boolean doInBackground(Void... params) {
if (driveFile.getDownloadUrl() != null
&& driveFile.getDownloadUrl().length() > 0) {
try {
HttpResponse resp = mDriveService
.getRequestFactory()
.buildGetRequest(
new GenericUrl(driveFile.getDownloadUrl()))
.execute();
OutputStream os = new FileOutputStream(file);
CopyStream(resp.getContent(), os);
os.close();
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
}
} else {
return false;
}
}
#Override
protected void onPostExecute(Boolean result) {
//use the file
}
}
public static void CopyStream(InputStream is, OutputStream os) {
final int buffer_size = 1024;
try {
byte[] bytes = new byte[buffer_size];
for (;;) {
int count = is.read(bytes, 0, buffer_size);
if (count == -1)
break;
os.write(bytes, 0, count);
}
} catch (Exception ex) {
}
}

Can't write an Object. Read-only file system

I'm trying to save this Object, Inventory, to the internal storage. I have the saving and getting methods in the class itself. When I try and call the save method, I end up with the exception. I had the Exception message write to the Logcat, and here's what I got:
08-04 02:32:23.690: VERBOSE/alex(278): /test (Read-only file system)
The file /test is "Read-only file system", but I had allowed writing external storage in the Manifest file:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
Here's the Inventory class. The last two methods are the save and read methods.
package com.androidbook.inventoryproject;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import android.util.Log;
public class Inventory implements Serializable {
private static final long serialVersionUID = 1L;
int numIngred;;
Ingredient[] ingredients;
ArrayList ingred = new ArrayList<Ingredient>();
public Inventory() {
numIngred = 0;
ingredients = new Ingredient[numIngred];
}
public int getNumIngred() {
return numIngred;
}
public String getIngredientName(int n) {
return ((Ingredient)ingred.get(n)).getName();
}
public Ingredient[] getIngredients() {
return ingredients;
}
public Ingredient getIngredient(int n) {
return (Ingredient)ingred.get(n);
}
public void addIngredient(String iname) {
numIngred++;
ingred.add(new Ingredient(iname));
}
public boolean saveInventory( Inventory inv) {
File suspend_f = new File("test");
FileOutputStream fos = null;
ObjectOutputStream oos = null;
boolean keep = true;
try {
fos = new FileOutputStream(suspend_f);
oos = new ObjectOutputStream(fos);
oos.writeObject(inv);
}
catch (Exception e) {
keep = false;
Log.v("alex", "" + e.getMessage());
}
finally {
try {
if (oos != null) oos.close();
if (fos != null) fos.close();
if (keep == false) suspend_f.delete();
}
catch (Exception e) { /* do nothing */ }
}
return keep;
}
public Inventory getInventory() {
File suspend_f = new File("test");
Inventory inven = null;
FileInputStream fis = null;
ObjectInputStream ois = null;
try{
fis = new FileInputStream(suspend_f);
ois = new ObjectInputStream(fis);
inven = (Inventory)ois.readObject();
}
catch (Exception e) {
String mess = e.getMessage();
}
finally {
try {
if (fis != null)
fis.close();
if (ois != null)
ois.close();
}
catch (Exception e) { }
}
return inven;
}
}
WRITE_EXTERNAL_STORAGE lets you write to the SD card, not to the filesystem root. You should try this:
File suspend_f = new File(Environment.getExternalStorageDirectory(), "test");
This verifies that the file you are using goes into a writable external folder.
EDIT: there is a bunch of other work you should do to verify that the SD card is available and writable. Read the specs to see how to make your file access robust by checking availability.

Categories

Resources