Fails to save file (image) in some devices - android

In my application I'll download an Image from a url and write it into an external storage. It works on 2 out of 3 devices I've tested and failed on 3rd. The first 2 are LG and Lenovo devices (unrooted) and the 3rd one is a Lenovo (rooted). Now when I save the file using below code everything works fine on first 2 devices but throws an:
IOException: open failed: EINVAL (Invalid argument)
while creating the file. I don't have any illegal character in my file name as it is shown below.
InputStream in = connection.getInputStream();
newPath = path + "/" + fileNameMobile;
File outFile = new File(newPath);
if(!outFile.exists()) {
outFile.createNewFile(); // fails here
}
OutputStream out = new FileOutputStream(outFile);
ImageHandler.copyFile(in, out);
out.flush();
out.close();
in.close();
and newPath is
/storage/sdcard0/com.rahil.ecat/_5577d1b953e54351a4a7132252c11304.jpg
I can't find exactly why it fails on 1 device and works on the other 2 devices. Anyone has any idea? Thanks in advance
EDIT: Here's how I get the fileNameMoblie:
String fileNameMobile = _url.substring(_url.lastIndexOf('/') + 1);
and get the path and pass it to function as below:
File sdCardRoot = Environment.getExternalStorageDirectory();
File yourDir = new File(sdCardRoot, _Context.getPackageName());
and here's the result of outFile.getAbsolutePath():
/storage/sdcard0/com.rahil.ecat/_5577d1b953e54351a4a7132252c11304.jpg
EDIT 2: Here's the complete code:
Class ImageTask
public class ImageTask extends AsyncTask<Void, String, Void> {
private Context _Context;
private String _token;
private ImageView _imageView;
private ProgressBar _pbar;
private String _url;
private HttpRequestHandler _hrh;
private ImageType _type;
private RoundedImageView _rImageView;
public ImageTask(Context context, String token, ImageView imageView, RoundedImageView rImageView, ImageType type) {
this._Context = context;
_token = token;
_imageView = imageView;
_type = type;
_rImageView = rImageView;
}
#Override
protected Void doInBackground(Void... voids) {
if(!_token.isEmpty())
{
File sdCardRoot = Environment.getExternalStorageDirectory();
File yourDir = new File(sdCardRoot, _Context.getPackageName());
boolean found = false;
String[] tokenParts = _token.split("\\.");
String realToken = _token;
if(tokenParts.length == 2)
{
realToken = tokenParts[0];
}
for (File f : yourDir.listFiles()) {
if (f.isFile()) {
String name = f.getName();
if(name.contains(realToken))
{
found = true;
if(Util.isMobile(name))
{
publishProgress(yourDir.getPath() + '/' + name, "NULL");
}
else
{
if(Util.hasActiveInternetConnection(_Context)) {
getUrl();
if(!_url.isEmpty()) {
_hrh = new HttpRequestHandler(_url, _Context);
String fileName = _hrh.downloadImage(yourDir.getPath(), _token, true);
if (!fileName.isEmpty()) {
if(fileName.contains("-mob")) {
f.delete();
}
publishProgress(fileName, "NULL");
} else {
publishProgress("", "DEFAULT");
}
}else {
publishProgress("", "DEFAULT");
}
}
else
{
publishProgress("", "DEFAULT");
}
}
}
}
}
if(!found)
{
if(Util.hasActiveInternetConnection(_Context))
{
getUrl();
if(!_url.isEmpty()) {
_hrh = new HttpRequestHandler(_url, _Context);
String fileName = _hrh.downloadImage(yourDir.getPath(), _token, false);
if (!fileName.isEmpty()) {
publishProgress(fileName, "NULL");
} else {
publishProgress("", "DEFAULT");
}
}else {
publishProgress("", "DEFAULT");
}
}
else
{
publishProgress("", "DEFAULT");
}
}
}
else
{
loadDefaultImage();
}
return null;
}
#Override
protected void onProgressUpdate(String... values) {
if(values[1].equals("DEFAULT"))
{
loadDefaultImage();
}
else
{
loadImage(values[0]);
}
}
#TargetApi(Build.VERSION_CODES.JELLY_BEAN)
private void loadImage(String path)
{
try {
Bitmap image = BitmapFactory.decodeFile(path);
if (image != null) {
if(_imageView != null) {
StreamDrawable sd = null;
if(_type == ImageType.BLUR)
{
sd = new StreamDrawable(image, 10, 10);
_imageView.setBackground(sd);
}
else if(_type == ImageType.NO_EFFECT)
{
_imageView.setImageBitmap(image);
}
}
else if(_rImageView != null) {
_rImageView.setImageBitmap(image);
}
}
}
catch(Exception ex)
{
loadDefaultImage();
}
}
private void getUrl()
{
WebService ws = new WebService(_Context);
_url = ws.getImageUrlForScreenTypeAndToken(
_token,
Util.getScreenType(_Context).name());
}
private void loadDefaultImage()
{
if(_imageView != null) {
_imageView.setBackgroundResource(R.drawable.noimage);
}
else if(_rImageView != null) {
_rImageView.setBackgroundResource(R.drawable.noimage);
}
}
}
Class HttpRequestHandler
public class HttpRequestHandler {
private String _url;
private Context _Context;
private ProgressDialog _dialog;
public HttpRequestHandler(String url, Context context) {
_url = url;
_Context = context;
}
public String init_post(List<NameValuePair> nameValuePairs) {
String data = null ;
BufferedReader in = null;
try {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
HttpParams params = new BasicHttpParams();
params.setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
HttpConnectionParams.setConnectionTimeout(params, 10000);
HttpConnectionParams.setSoTimeout(params, 5000);
HttpClient httpclient = new DefaultHttpClient(params);
HttpPost httppost = new HttpPost(_url);
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs, "UTF-8"));
HttpResponse response = httpclient.execute(httppost);
data = parser(response.getEntity());
} catch (Exception e) {
}
return data;
}
public String init() {
String data = null ;
BufferedReader in = null;
try {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
HttpParams params = new BasicHttpParams();
params.setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
HttpConnectionParams.setConnectionTimeout(params, 10000);
HttpConnectionParams.setSoTimeout(params, 5000);
HttpClient httpclient = new DefaultHttpClient(params);
HttpGet request = new HttpGet();
URI website = new URI(_url);
request.setURI(website);
HttpResponse response = httpclient.execute(request);
data = parser(response.getEntity());
} catch (Exception t) {
if(true)
{
String s = "asd";
}
}
return data;
}
private String parser(HttpEntity entity){
InputStream is = null;
String jsonParse = "";
try {
is = entity.getContent();
//BufferedReader reader = new BufferedReader(new InputStreamReader(is, "iso-8859-1"), 8);
BufferedReader reader = new BufferedReader(new InputStreamReader(is, "utf-8"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
jsonParse = sb.toString();
} catch (IOException e) {
e.printStackTrace();
}
return jsonParse;
}
public String downloadImage(String path, String token, boolean check) {
String newPath = "";
try {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
.permitAll().build();
StrictMode.setThreadPolicy(policy);
String fileNameMobile = _url.substring(_url.lastIndexOf('/') + 1);
if(check && token.equals(fileNameMobile))
{
return newPath;
}
URL urlConnection = new URL(_url);
URLConnection connection = urlConnection.openConnection();
InputStream in = connection.getInputStream();
newPath = path + "/" + fileNameMobile;
File outFile = new File(newPath);
OutputStream out = new FileOutputStream(outFile);
ImageHandler.copyFile(in, out);
out.flush();
out.close();
in.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return newPath;
}
}

This permission.
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />
This code.
InputStream in = connection.getInputStream();
String filepath = getFilesDir().toString() + "/MyCustomFolder/";
File imagesFolder = new File(filepath);
if(!imagesFolder.exists())
imagesFolder.mkdirs();
File outFile = new File(filepath + "FileName.jpg");
if(!outFile.exists()){
OutputStream out = new FileOutputStream(outFile);
ImageHandler.copyFile(in, out);
out.flush();
out.close();
in.close();
}else{
in.close();
}

Related

Upload of some file fails using HttpClient

I am trying to upload images as well as videos to my external server from the app. I Googled and found out HttpClient procedure is a good one, so I downloaded the library and execute the following code which normally works well for every file however for some videos, it does not upload the video.
public void executeMultipartPost(String uri) throws Exception {
try {
File file = new File(uri);
Uri imageUri = Uri.fromFile(file);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] data = readBytes(imageUri);
HttpClient httpClient = new DefaultHttpClient();
HttpPost postRequest = new HttpPost(
"http://example.com/ccs-business/upload.php");
ByteArrayBody bab = new ByteArrayBody(data, file.getName());
MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
reqEntity.addPart("uploaded_video", bab);
reqEntity.addPart("number", new StringBody("123456"));
postRequest.setEntity(reqEntity);
HttpResponse response = httpClient.execute(postRequest);
BufferedReader reader = new BufferedReader(new InputStreamReader(
response.getEntity().getContent(), "UTF-8"));
String sResponse;
StringBuilder s = new StringBuilder();
while ((sResponse = reader.readLine()) != null) {
s = s.append(sResponse);
}
Log.v("ONMESSAGE", "Response: " + s);
dialog.dismiss();
} catch (Exception e) {
// handle exception here
Log.e(e.getClass().getName(), e.getMessage());
dialog.dismiss();
}
}
public byte[] readBytes(Uri uri) throws IOException {
InputStream inputStream = getContentResolver().openInputStream(uri);
ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
int len = 0;
while ((len = inputStream.read(buffer)) != -1) {
byteBuffer.write(buffer, 0, len);
}
return byteBuffer.toByteArray();
}
My requirement is to upload up to 20mb file.
I Have tired Uploading files with below code attached and worked fine :
public class UploadService extends IntentService {
/**
* Utility method that creates the intent that starts the background
* file upload service.
*
* #param task object containing the upload request
* #throws IllegalArgumentException if one or more arguments passed are invalid
* #throws MalformedURLException if the server URL is not valid
*/
public static void startUpload(final UploadRequest task)
throws IllegalArgumentException, MalformedURLException {
if (task == null) {
throw new IllegalArgumentException("Can't pass an empty task!");
} else {
task.validate();
final Intent intent = new Intent(UploadService.class.getName());
intent.setAction(ACTION_UPLOAD);
intent.putExtra(PARAM_NOTIFICATION_CONFIG, task.getNotificationConfig());
intent.putExtra(PARAM_ID, task.getUploadId());
intent.putExtra(PARAM_URL, task.getServerUrl());
intent.putExtra(PARAM_METHOD, task.getMethod());
intent.putParcelableArrayListExtra(PARAM_FILES, task.getFilesToUpload());
intent.putParcelableArrayListExtra(PARAM_REQUEST_HEADERS, task.getHeaders());
intent.putParcelableArrayListExtra(PARAM_REQUEST_PARAMETERS, task.getParameters());
task.getContext().startService(intent);
}
}
public UploadService() {
super(SERVICE_NAME);
}
#Override
public void onCreate() {
super.onCreate();
notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notification = new NotificationCompat.Builder(this);
PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
}
#Override
protected void onHandleIntent(Intent intent) {
if (intent != null) {
final String action = intent.getAction();
if (ACTION_UPLOAD.equals(action)) {
notificationConfig = intent.getParcelableExtra(PARAM_NOTIFICATION_CONFIG);
final String uploadId = intent.getStringExtra(PARAM_ID);
final String url = intent.getStringExtra(PARAM_URL);
final String method = intent.getStringExtra(PARAM_METHOD);
final ArrayList<FileToUpload> files = intent.getParcelableArrayListExtra(PARAM_FILES);
final ArrayList<NameValue> headers = intent.getParcelableArrayListExtra(PARAM_REQUEST_HEADERS);
final ArrayList<NameValue> parameters = intent.getParcelableArrayListExtra(PARAM_REQUEST_PARAMETERS);
lastPublishedProgress = 0;
wakeLock.acquire();
try {
createNotification();
handleFileUpload(uploadId, url, method, files, headers, parameters);
} catch (Exception exception) {
broadcastError(uploadId, exception);
} finally {
wakeLock.release();
}
}
}
}
private void handleFileUpload(final String uploadId,
final String url,
final String method,
final ArrayList<FileToUpload> filesToUpload,
final ArrayList<NameValue> requestHeaders,
final ArrayList<NameValue> requestParameters)
throws IOException {
final String boundary = getBoundary();
final byte[] boundaryBytes = getBoundaryBytes(boundary);
HttpURLConnection conn = null;
OutputStream requestStream = null;
try {
conn = getMultipartHttpURLConnection(url, method, boundary);
setRequestHeaders(conn, requestHeaders);
requestStream = conn.getOutputStream();
setRequestParameters(requestStream, requestParameters, boundaryBytes);
uploadFiles(uploadId, requestStream, filesToUpload, boundaryBytes);
final byte[] trailer = getTrailerBytes(boundary);
requestStream.write(trailer, 0, trailer.length);
final int serverResponseCode = conn.getResponseCode();
final String serverResponseMessage = conn.getResponseMessage();
broadcastCompleted(uploadId, serverResponseCode, serverResponseMessage);
} finally {
closeOutputStream(requestStream);
closeConnection(conn);
}
}
private String getBoundary() {
final StringBuilder builder = new StringBuilder();
builder.append("---------------------------")
.append(System.currentTimeMillis());
return builder.toString();
}
private byte[] getBoundaryBytes(final String boundary)
throws UnsupportedEncodingException {
final StringBuilder builder = new StringBuilder();
builder.append(NEW_LINE)
.append(TWO_HYPHENS)
.append(boundary)
.append(NEW_LINE);
return builder.toString().getBytes("US-ASCII");
}
private byte[] getTrailerBytes(final String boundary)
throws UnsupportedEncodingException {
final StringBuilder builder = new StringBuilder();
builder.append(NEW_LINE)
.append(TWO_HYPHENS)
.append(boundary)
.append(TWO_HYPHENS)
.append(NEW_LINE);
return builder.toString().getBytes("US-ASCII");
}
private HttpURLConnection getMultipartHttpURLConnection(final String url,
final String method,
final String boundary)
throws IOException {
final HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setChunkedStreamingMode(0);
conn.setRequestMethod(method);
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("ENCTYPE", "multipart/form-data");
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
return conn;
}
private void setRequestHeaders(final HttpURLConnection conn,
final ArrayList<NameValue> requestHeaders) {
if (!requestHeaders.isEmpty()) {
for (final NameValue param : requestHeaders) {
conn.setRequestProperty(param.getName(), param.getValue());
}
}
}
private void setRequestParameters(final OutputStream requestStream,
final ArrayList<NameValue> requestParameters,
final byte[] boundaryBytes)
throws IOException, UnsupportedEncodingException {
if (!requestParameters.isEmpty()) {
for (final NameValue parameter : requestParameters) {
requestStream.write(boundaryBytes, 0, boundaryBytes.length);
byte[] formItemBytes = parameter.getBytes();
requestStream.write(formItemBytes, 0, formItemBytes.length);
}
}
}
private void uploadFiles(final String uploadId,
final OutputStream requestStream,
final ArrayList<FileToUpload> filesToUpload,
final byte[] boundaryBytes)
throws UnsupportedEncodingException,
IOException,
FileNotFoundException {
final long totalBytes = getTotalBytes(filesToUpload);
long uploadedBytes = 0;
for (FileToUpload file : filesToUpload) {
requestStream.write(boundaryBytes, 0, boundaryBytes.length);
byte[] headerBytes = file.getMultipartHeader();
requestStream.write(headerBytes, 0, headerBytes.length);
final InputStream stream = file.getStream();
byte[] buffer = new byte[BUFFER_SIZE];
long bytesRead;
try {
while ((bytesRead = stream.read(buffer, 0, buffer.length)) > 0) {
requestStream.write(buffer, 0, buffer.length);
uploadedBytes += bytesRead;
broadcastProgress(uploadId, uploadedBytes, totalBytes);
}
} finally {
closeInputStream(stream);
}
}
}
private long getTotalBytes(final ArrayList<FileToUpload> filesToUpload) {
long total = 0;
for (FileToUpload file : filesToUpload) {
total += file.length();
}
return total;
}
private void closeInputStream(final InputStream stream) {
if (stream != null) {
try {
stream.close();
} catch (Exception exc) { }
}
}
private void closeOutputStream(final OutputStream stream) {
if (stream != null) {
try {
stream.flush();
stream.close();
} catch (Exception exc) { }
}
}
private void closeConnection(final HttpURLConnection connection) {
if (connection != null) {
try {
connection.disconnect();
} catch (Exception exc) { }
}
}
private void broadcastProgress(final String uploadId, final long uploadedBytes, final long totalBytes) {
final int progress = (int) (uploadedBytes * 100 / totalBytes);
if (progress <= lastPublishedProgress) return;
lastPublishedProgress = progress;
updateNotificationProgress(progress);
final Intent intent = new Intent(BROADCAST_ACTION);
intent.putExtra(UPLOAD_ID, uploadId);
intent.putExtra(STATUS, STATUS_IN_PROGRESS);
intent.putExtra(PROGRESS, progress);
sendBroadcast(intent);
}
private void broadcastCompleted(final String uploadId, final int responseCode, final String responseMessage) {
final String filteredMessage;
if (responseMessage == null) {
filteredMessage = "";
} else {
filteredMessage = responseMessage;
}
if (responseCode >= 200 && responseCode <= 299)
updateNotificationCompleted();
else
updateNotificationError();
final Intent intent = new Intent(BROADCAST_ACTION);
intent.putExtra(UPLOAD_ID, uploadId);
intent.putExtra(STATUS, STATUS_COMPLETED);
intent.putExtra(SERVER_RESPONSE_CODE, responseCode);
intent.putExtra(SERVER_RESPONSE_MESSAGE, filteredMessage);
sendBroadcast(intent);
}
private void broadcastError(final String uploadId, final Exception exception) {
updateNotificationError();
final Intent intent = new Intent(BROADCAST_ACTION);
intent.setAction(BROADCAST_ACTION);
intent.putExtra(UPLOAD_ID, uploadId);
intent.putExtra(STATUS, STATUS_ERROR);
intent.putExtra(ERROR_EXCEPTION, exception);
sendBroadcast(intent);
}
private void createNotification() {
notification.setContentTitle(notificationConfig.getTitle())
.setContentText(notificationConfig.getMessage())
.setSmallIcon(notificationConfig.getIconResourceID())
.setProgress(100, 0, true)
.setOngoing(true);
startForeground(UPLOAD_NOTIFICATION_ID, notification.build());
}
private void updateNotificationProgress(final int progress) {
notification.setContentTitle(notificationConfig.getTitle())
.setContentText(notificationConfig.getMessage())
.setSmallIcon(notificationConfig.getIconResourceID())
.setProgress(100, progress, false)
.setOngoing(true);
startForeground(UPLOAD_NOTIFICATION_ID, notification.build());
}
private void updateNotificationCompleted() {
stopForeground(notificationConfig.isAutoClearOnSuccess());
if (!notificationConfig.isAutoClearOnSuccess()) {
notification.setContentTitle(notificationConfig.getTitle())
.setContentText(notificationConfig.getCompleted())
.setSmallIcon(notificationConfig.getIconResourceID())
.setProgress(0, 0, false)
.setOngoing(false);
notificationManager.notify(UPLOAD_NOTIFICATION_ID_DONE, notification.build());
}
}
private void updateNotificationError() {
stopForeground(false);
notification.setContentTitle(notificationConfig.getTitle())
.setContentText(notificationConfig.getError())
.setSmallIcon(notificationConfig.getIconResourceID())
.setProgress(0, 0, false)
.setOngoing(false);
notificationManager.notify(UPLOAD_NOTIFICATION_ID_DONE, notification.build());
}
}
For compelete Source code refer this

Write /Read String Array to File in Android, using internal or external storage whichever is available

I am downloading a json response array string from network and displaying a listview using this data.I want to store this response for first time in a file stored under internal/external storage, so i dont have to download the data again in future.
How can i store this response in a internal/external storage file and read it later when my application starts afresh again.And File should be created first time only and later when application is started again, a check to whether file exists or not should be in place.
Any examples /utility class where this has been done?
Here is my code...
The Problem with this code is...it always creates a new directory and a new file.
public class FileCache {
static File cacheDir;
static final String DIRECTORY_ADDRESS = "/Android/data/com.example.savefiletostoragedemo/.newDirectory";
static final String TAG="DEMO";
public static void createDirectory(Context context){
Log.i(TAG,"createDirectory() called...");
if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)){
cacheDir = new File(Environment.getExternalStorageDirectory(),DIRECTORY_ADDRESS);
Log.i(TAG,"cacheDir exists in ext storage?: "+cacheDir.exists());
}
else{
cacheDir=context.getCacheDir();
Log.i(TAG,"cacheDir exists in int storage?: "+cacheDir.exists());
}
if(!cacheDir.exists()){
cacheDir.mkdirs();
Log.i(TAG,"A New Directory is made[ "+cacheDir.getAbsolutePath());
}
else{
Log.i(TAG,"Cache Dir already exists[ "+cacheDir.getAbsolutePath());
}
}
public static File getFile(String filename){
//String filename=String.valueOf(url.hashCode());
File f = new File(cacheDir, filename);
return f;
}
public static void saveFile(String dataToWrite, File file){
try {
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream(file));
outputStreamWriter.write(dataToWrite);
outputStreamWriter.close();
} catch (FileNotFoundException e) {
} catch (IOException e) {
}
}
public static String readFromFile(File file){
try{
InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream(file));
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String receiveString = "";
StringBuilder stringBuilder = new StringBuilder();
while ( (receiveString = bufferedReader.readLine()) != null ) {
stringBuilder.append(receiveString);
}
bufferedReader.close();
inputStreamReader.close();
return stringBuilder.toString();
}
catch (FileNotFoundException e) {
} catch (IOException e) {
}
return null;
}
public static void clear(){
File[] files=cacheDir.listFiles();
if(files==null)
return;
for(File f:files)
f.delete();
}
}
I call createDirectory() in Application class
MainActivity.Java
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new DownloadUrsl().execute(null,null,null);
}
private class DownloadUrsl extends AsyncTask<String,String,String>{
#Override
protected String doInBackground(String... arg0) {
File f = getJson("LISTVIEWDATA");
//String jsonString =FileCache.readFromFile(f);
//Log.i("DEMO", "DATA Read from file is:[ "+jsonString+" ]")
return null;
}
private File getJson(String filename) {
File f = FileCache.getFile(filename);
if(f != null && f.isFile()) {
String jsonString =FileCache.readFromFile(f);
Log.i("DEMO", "DATA Read from file is:[ "+jsonString+" ]");
return f;
}
try {
Log.i("DEMO", "Starting data download...");
HttpClient httpclient = new DefaultHttpClient();
// make GET request to the given URL
URI uri = new URI("");
HttpResponse httpResponse = httpclient.execute(new HttpGet(uri));
String response =EntityUtils.toString(httpResponse.getEntity());
Log.i("DEMO", "DATA Received from net is:[ "+response+" ]");
JSONArray array=new JSONArray(response);
FileCache.saveFile(array.toString(), f);
return f;
} catch (Exception ex) {
return null;
}
}
}
Issues with this Code: This code always creates a new directory when application starts...And also creates a new file everytime the data is requested.I also tried isDirectory(), didnt work.
here is how i did it.. Thank you guys For Your Help..:)
public static void createDirectory(Context context){
Log.i(TAG,"createDirectory() called...");
if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)){
File dataDir = new File(new File(Environment.getExternalStorageDirectory(), "Android"), "data");
cacheDir = new File(new File(dataDir, context.getPackageName()), "cache");
Log.i(TAG,"cacheDir exists in ext storage?: "+cacheDir.isDirectory());
}
else{
cacheDir=context.getCacheDir();
Log.i(TAG,"cacheDir exists in int storage?: "+cacheDir.isDirectory());
}
if(!cacheDir.isDirectory()){
cacheDir.mkdirs();
Log.i(TAG,"A New Directory is made[ "+cacheDir.getAbsolutePath());
}
else{
Log.i(TAG,"Cache Dir already exists[ "+cacheDir.getAbsolutePath());
}
}
public static File getFile(String filename){
//String filename=String.valueOf(url.hashCode());
File f = new File(cacheDir, String.valueOf(filename.hashCode()));
return f;
}
public static void saveFile(String dataToWrite, File file){
try {
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream(file));
outputStreamWriter.write(dataToWrite);
outputStreamWriter.close();
} catch (FileNotFoundException e) {
} catch (IOException e) {
}
}
public static String readFromFile(File file){
try{
InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream(file));
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String receiveString = "";
StringBuilder stringBuilder = new StringBuilder();
while ( (receiveString = bufferedReader.readLine()) != null ) {
stringBuilder.append(receiveString);
}
bufferedReader.close();
inputStreamReader.close();
return stringBuilder.toString();
}
catch (FileNotFoundException e) {
} catch (IOException e) {
}
return null;
}
private static final String cacheDir = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/data/" + MyUtilClass.class.getPackage().getName();
public static void cacheResponse(String name, List<String> data) throws IOException {
File f = new File(cacheDir + "/" + name);
if (f.exists())
return;
Writer fw = new FileWriter(f);
for (String line : data) {
fw.write(line);
}
fw.close();
}

Using Azure Bing Search API in Android

I am trying to make an app which executes an image search and displays the image results in a grid. Since the Google Image Search API is deprecated and will no longer be available shortly, I am trying to use the Bing Search API.
However, I am getting the following error:
java.io.IOException: No authentication challenges found
at libcore.net.http.HttpURLConnectionImpl.getAuthorizationCredentials(HttpURLConnectionImpl.java:427)
at libcore.net.http.HttpURLConnectionImpl.processAuthHeader(HttpURLConnectionImpl.java:407)
at libcore.net.http.HttpURLConnectionImpl.processResponseHeaders(HttpURLConnectionImpl.java:356)
at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:292)
at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:168)
at libcore.net.http.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:271)
I am following the example in http://learn-it-stuff.blogspot.com/2012/09/using-bing-custom-search-inside-your.html. If anyone has experienced this issue, or can help me out, that would be much appreciated. Thanks!
Here is my code thus far:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
AsyncTask <Void, Void, Void> task = new AsyncTask <Void, Void, Void> () {
protected Void doInBackground(Void... args) {
// Uri uri = Uri.parse("https://www.google.com/search?tbm=isch&q=penguin");
// Intent intent = new Intent(Intent.ACTION_VIEW, uri);
// startActivity(intent);
/*-------------------------Bing search-------------------------*/
String searchText = "Hello World";
searchText = searchText.replace(" ", "%20");
String accountKey = "MY_APP_ID";
accountKey = accountKey.replace("+", "%2B");
byte[] accountKeyBytes = Base64.encodeBase64((accountKey + ":" + accountKey).getBytes());
String accountKeyEnc = new String(accountKeyBytes);
URL url;
try {
url = new URL(
"https://api.datamarket.azure.com/Bing/Search/v1/"
+ "Image?Query=%27" + searchText + "%27");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/json");
conn.setRequestProperty("Authorization", "Basic " + accountKeyEnc);
BufferedReader br = new BufferedReader(new InputStreamReader(
(conn.getInputStream())));
StringBuilder sb = new StringBuilder();
String output;
System.out.println("Output from Server .... \n");
while ((output = br.readLine()) != null) {
sb.append(output);
}
conn.disconnect();
System.out.println(sb);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
};
task.execute();
}
}
The following code worked for me:
public class SearchAsyncTask extends AsyncTask<Void, Void, Void> {
private final String TAG = getClass().getName();
private String mSearchStr;
private int mNumOfResults = 0;
private Callback mCallback;
private BingSearchResults mBingSearchResults;
private Error mError;
public SearchAsyncTask(String searchStr, int numOfResults, Callback callback) {
mSearchStr = searchStr;
mNumOfResults = numOfResults;
mCallback = callback;
}
#Override
protected Void doInBackground(Void... params) {
try {
String searchStr = URLEncoder.encode(mSearchStr);
String numOfResultsStr = mNumOfResults <= 0 ? "" : "&$top=" + mNumOfResults;
String bingUrl = "https://api.datamarket.azure.com/Bing/SearchWeb/v1/Web?Query=%27" + searchStr + "%27" + numOfResultsStr + "&$format=json";
String accountKey = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
byte[] accountKeyBytes = Base64.encodeBase64((accountKey + ":" + accountKey).getBytes());
String accountKeyEnc = new String(accountKeyBytes);
URL url = null;
url = new URL(bingUrl);
URLConnection urlConnection = url.openConnection();
urlConnection.setRequestProperty("Authorization", "Basic " + accountKeyEnc);
InputStream response = urlConnection.getInputStream();
String res = readStream(response);
Gson gson = (new GsonBuilder()).create();
mBingSearchResults = gson.fromJson(res, BingSearchResults.class);
Log.d(TAG, res);
//conn.disconnect();
} catch (Exception e) {
e.printStackTrace();
mError = new Error(e.getMessage(), e);
//Log.e(TAG, e.getMessage());
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
if (mCallback != null) {
mCallback.onComplete(mBingSearchResults, mError);
}
}
private String readStream(InputStream in) {
BufferedReader reader = null;
StringBuilder sb = new StringBuilder();
try {
reader = new BufferedReader(new InputStreamReader(in));
String line = "";
while ((line = reader.readLine()) != null) {
//System.out.println(line);
sb.append(line + "\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return sb.toString();
}
public interface Callback {
void onComplete(Object o, Error error);
}
}
To parse the result:
public class BingSearchResults {
public ResultsContent d;
public static class ResultsContent {
public Result[] results;
public String __next;
}
public static class Result {
public String ID;
public String Title;
public String Description;
public String DisplayUrl;
public String Url;
public Metadata __metadata;
}
public static class Metadata {
public String uri;
public String type;
}
public Result[] getResults(){
if (d == null)
return null;
return d.results;
}
public String getNextUrl(){
if (d == null)
return null;
return d.__next;
}
public boolean isEmpty(){
return (d == null || d.results == null || d.results.length == 0);
}
public int size(){
if (d == null || d.results == null)
return 0;
return d.results.length;
}
}
You also need to include the external jars commons-codec-1.9.jar and gson-2.2.4.jar
Little bit change occur in this code sometimes compilation bug of encoder generate problem byte[] accountKeyBytes = Base64.encodeBase64((accountKey + ":" + accountKey).getBytes());

How to insert one more item in a json existing structure with gson?

The code below generates correctly the first structure of the json file.
gson = new GsonBuilder().setPrettyPrinting().create();
AudDetHeader AudDetHeader = new AudDetHeader();
//ArrayList<OrderDetail> AudDetList = new ArrayList<OrderDetail>();
Map<String, AudDet> AudDetList = new HashMap<String, AudDet>();
AudDet AudDet = new AudDet();
AudDet.setLineId("1");
AudDet.setItemNumber("ABC");
AudDet.setQuantity(9);
AudDet.setPrice(10.00);
List<String> phones = new ArrayList<String>();
phones.add("24530001");
phones.add("24530002");
phones.add("24530003");
AudDet.setPhones(phones);
AudDetList.put("teste 2", AudDet);
AudDetHeader.setAudDetList(AudDetList);
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String jsonString = gson.toJson(AudDetHeader);
BufferedWriter bufferedWriter = null;
try {
File file = new File(Environment.getExternalStorageDirectory() + "/download/test/test.json");
if(!file.exists()){
file.createNewFile();
}
FileWriter fileWriter = new FileWriter(file);
bufferedWriter = new BufferedWriter(fileWriter);
bufferedWriter.write(jsonString);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (bufferedWriter != null){
bufferedWriter.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
The result of the code:
{
"Results": {
"teste 2": {
"itemNumber": "ABC",
"lineId": "1",
"phones": [
"24530001",
"24530002",
"24530003"
],
"price": 10.0,
"quantity": 9
}
}
}
I want to add a new item. My desire is to stay as the structure below.
{
"Results":{
"teste 2":{
"itemNumber":"ABC",
"lineId":"1",
"phones":[
"24530001",
"24530002",
"24530003"
],
"price":10.0,
"quantity":9
},
"teste 3":{
"itemNumber":"DEF",
"lineId":"2",
"phones":[
"30303030",
"40404040",
"505050"
],
"price":11.0,
"quantity":12
}
}
}
The AudDetHeader.class
public class AuditoriaDetalheHeader {
#SerializedName("Results")
private Map<String, AuditoriaDetalhe> AuditoriaDetalheList;
...
}
The AudDet.class
public class AuditoriaDetalhe {
String lineId = null;
String itemNumber = null;
int quantity = 0;
Double price = null;
List<String> phones = new ArrayList<String>();
...
}
Worked for me with this code!!!
Main class
private static File fileJson = new File(Environment.getExternalStorageDirectory() + "/download/test/test.json");
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.teste_criajson);
createJsonStructure();
Button btnSave = (Button)findViewById(R.id.btSave);
btnSalvar.setOnClickListener( new View.OnClickListener() {
public void onClick(View v) {
try {
String strFileJson = getStringFromFile(fileJson.toString());
JSONObject jsonObj = new JSONObject(strFileJson);
Gson gson = new Gson();
JsonParser jsonParser = new JsonParser();
String idAud = "10";
AudDet ad = new AudDet();
ad.setLineId("2");
ad.setItemNumber("DEF");
ad.setQuantity(22);
ad.setPrice(22.22);
List<String> phones = new ArrayList<String>();
phones.add("22");
phones.add("22");
phones.add("22");
ad.setPhones(phones);
String jsonStr = jsonParser.parse(gson.toJson(ad)).toString();
JSONObject JSONObject = new JSONObject(jsonStr);
jsonObj.getJSONObject("Results").put(idAud, JSONObject);
writeJsonFile(fileJson, jsonObj.toString());
} catch (Exception e1) {
e1.printStackTrace();
}
}
});
If do not exists json file, then i create with basic structure for insert the itens.
public static void createJsonStructure(){
if(!fileJson.exists()){
try {
fileJson.createNewFile();
String jsonString = "{\"Results\":{}}";
writeJsonFile(fileJson, jsonString);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Open the json file to get the string format, and prepare to insert a new item:
public static String getStringFromFile (String filePath) throws Exception {
File fl = new File(filePath);
FileInputStream fin = new FileInputStream(fl);
String ret = convertStreamToString(fin);
//Make sure you close all streams.
fin.close();
return ret;
}
public static String convertStreamToString(InputStream is) throws Exception {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line).append("\n");
}
return sb.toString();
}
Writes into the json file that already exists:
public static void writeJsonFile(File file, String json)
{
BufferedWriter bufferedWriter = null;
try {
if(!file.exists()){
file.createNewFile();
}
FileWriter fileWriter = new FileWriter(file);
bufferedWriter = new BufferedWriter(fileWriter);
bufferedWriter.write(json);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (bufferedWriter != null){
bufferedWriter.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}

Converting a J2ME URLCaller Class to Android equivalent

I got a Class from a friend for a URlCaller class for connecting to a webservice. My assumption was that all will work well, but it contains error below is the J2ME implementation
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package main;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;
public class URLCaller extends Thread{
private String url ;
private String action;
private URLEncoder urle;
private String res;
public URLCaller() {
}
public URLCaller(String action,String url) {
urle = new URLEncoder();
this.url = url;
this.action = action;
start();
}
//replace
void authenticate(String action,String url) {
HttpConnection connection = null;
InputStream is = null;
OutputStream os = null;
StringBuffer stringBuffer = new StringBuffer();
try {
connection = (HttpConnection)Connector.open(url);
connection.setRequestMethod(HttpConnection.GET);
connection.setRequestProperty("IF-Modified-Since","20 Jan 2001 16:19:14 GMT");
connection.setRequestProperty("User-Agent","Profile/MIDP-2.0 Confirguration/CLDC-1.0");
connection.setRequestProperty("Content-Language", "en-CA");
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
os = connection.openOutputStream();
is = connection.openDataInputStream();
int ch;
while ((ch = is.read()) != -1) {
stringBuffer.append((char) ch);
}
res = stringBuffer.toString() ;
System.out.println(res);
//textBox = new TextBox("Simple GET Test", stringBuffer.toString(), 1024, 0);
}
catch(Exception e ){
}
finally {
try{
if(is!= null) {
is.close();
}
if(os != null) {
os.close();
}
if(connection != null) {
connection.close();
}
//display.setCurrent(textBox);
}
catch(Exception e ){
}
}
}
void sendSMS(String action,String url) {
HttpConnection connection = null;
InputStream is = null;
OutputStream os = null;
StringBuffer stringBuffer = new StringBuffer();
//TextBox textBox = null;
try {
connection = (HttpConnection)Connector.open(url);
connection.setRequestMethod(HttpConnection.GET);
connection.setRequestProperty("IF-Modified-Since","20 Jan 2001 16:19:14 GMT");
connection.setRequestProperty("User-Agent","Profile/MIDP-2.0 Confirguration/CLDC-1.0");
connection.setRequestProperty("Content-Language", "en-CA");
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
os = connection.openOutputStream();
is = connection.openDataInputStream();
int ch;
while ((ch = is.read()) != -1) {
stringBuffer.append((char) ch);
}
res = stringBuffer.toString() ;
System.out.println(res);
//textBox = new TextBox("Simple GET Test", stringBuffer.toString(), 1024, 0);
}
catch(Exception e ){
}
finally {
try{
if(is!= null) {
is.close();
}
if(os != null) {
os.close();
}
if(connection != null) {
connection.close();
}
//display.setCurrent(textBox);
}
catch(Exception e ){
}
}
}
public void run(){
//http://message url?user=mu&password=my&from=Muyiwa&to=23475061254040&message=i+love+this.
System.out.println(Thread.currentThread().toString() + " is running...") ;
if (action.equals("login")){
System.out.println(action);
authenticate(action,url);
}
else if(action.equals("sendsms")) {
System.out.println(action);
sendSMS(action,url);
}
}
public void callURL(){
HttpConnection c = null;
InputStream is = null;
StringBuffer sb = new StringBuffer();
try{
System.out.println(url);
//url = (urle.encode(url,"UTF-8"));
//System.out.println(url);
c = (HttpConnection)Connector.open(url, Connector.READ_WRITE, true);
c.setRequestMethod(HttpConnection.POST); //default
is = c.openInputStream(); // transition to connected!
int ch = 0;
for(int ccnt=0; ccnt < 150; ccnt++) { // get the title.
ch = is.read();
if (ch == -1){
break;
}
sb.append((char)ch);
}
res = sb.toString();
}catch(Exception e){
e.printStackTrace();
}
}
public String getRes() {
return res;
}
public void setRes(String res) {
this.res = res;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public URLEncoder getUrle() {
return urle;
}
public void setUrle(URLEncoder urle) {
this.urle = urle;
}
}
Ps could someone convert this to an android implementation. Currently facing a deadline
In android there are classes, HttpClient and DefaultHttpClient. So you make a web request using these.
Same as your code make a HttpGet request, And also in Like your J2ME code, instead of Thread class you can use AsyncTask (You can also use Thread, Handler but Asynctask is better to use) to perform a web request in Non-UI thread.
Example:
private class DownloadWebPageTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
String response = "";
for (String url : urls) {
DefaultHttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
try {
HttpResponse execute = client.execute(httpGet);
InputStream content = execute.getEntity().getContent();
BufferedReader buffer = new BufferedReader(new InputStreamReader(content));
String s = "";
while ((s = buffer.readLine()) != null) {
response += s;
}
} catch (Exception e) {
e.printStackTrace();
}
}
return response;
}
#Override
protected void onPostExecute(String result) {
textView.setText(result);
}
}
Now from your Android activity code you have to just execute() this DownloadWebPageTask.
Like,
DownloadWebPageTask task = new DownloadWebPageTask();
task.execute(new String[] { url });
For more information look at this Tutorial

Categories

Resources