I attempt in my app to read images from sdcard folder. However, In tablet device the task done with no errors, it lists all images on folder in Gridview, BUT in Emulator, just empty Gridview list appear, although the folder and pictures exist on Emulator sdcard as you see in picture below?!
Class that used to create folder and read pictures:
Utils Code:
package com.example.imageslider.helper;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Locale;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.Point;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Environment;
import android.view.Display;
import android.view.WindowManager;
import android.widget.Toast;
import com.example.classes.DBItems;
import com.example.classes.ProjectEngine;
import com.example.diwansalesorder.MainScreen;
import com.example.diwansalesorder.R;
import com.example.imageslider.GridViewActivity;
public class Utils {
private final Context _context;
ArrayList<String> allData = new ArrayList<String>();
// Progress Dialog
private ProgressDialog pDialog;
ArrayList<String> filePaths;
File sdCard, directory;
File[] listFiles;
// constructor
public Utils(Context context) {
this._context = context;
}
/*
* Reading file paths from SDCard
*/
public ArrayList<String> getFilePaths() {
filePaths = new ArrayList<String>();
boolean success = true; // to check if directory created ot not
readAllItems();
sdCard = Environment.getExternalStorageDirectory();
directory = new File(sdCard.getAbsolutePath() + "/DiwanAppPictures");
if (!directory.exists()) {
success = directory.mkdirs();
}
if (success) {
// check for directory
if (directory.isDirectory()) {
// getting list of file paths
listFiles = directory.listFiles();
// Check for count
if (listFiles.length > 0) {
new LoadAllPictures().execute();
} else {
new LoadAllPictures2().execute();
}
} else {
AlertDialog.Builder alert = new AlertDialog.Builder(_context);
alert.setTitle("Error!");
alert.setMessage(AppConstant.PHOTO_ALBUM
+ " directory path is not valid! Please set the image directory name AppConstant.java class");
alert.setPositiveButton("OK", null);
alert.show();
}
} else {
Toast.makeText(_context,
" can't create " + AppConstant.PHOTO_ALBUM + " folder !!",
Toast.LENGTH_LONG).show();
Intent prevIntent = new Intent(_context, MainScreen.class);
_context.startActivity(prevIntent);
}
return filePaths;
}
/*
* Check supported file extensions
*
* #returns boolean
*/
private boolean IsSupportedFile(String filePath) {
String ext = filePath.substring((filePath.lastIndexOf(".") + 1),
filePath.length());
if (AppConstant.FILE_EXTN
.contains(ext.toLowerCase(Locale.getDefault())))
return true;
else
return false;
}
/*
* getting screen width
*/
#SuppressLint("NewApi")
public int getScreenWidth() {
int columnWidth;
WindowManager wm = (WindowManager) _context
.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
final Point point = new Point();
try {
display.getSize(point);
} catch (java.lang.NoSuchMethodError ignore) { // Older device
point.x = display.getWidth();
point.y = display.getHeight();
}
columnWidth = point.x;
return columnWidth;
}
// Function to read all items from data base
private void readAllItems() {
final DBItems dbI = new DBItems(_context);
try {
dbI.open();
Cursor allTitles = dbI.getAllAccounts();
allTitles.moveToFirst();
do {
String Item = allTitles.getString(1);
String Name = allTitles.getString(2);
String Cprice = allTitles.getString(3);
String Ccurr = allTitles.getString(4);
String Sprice = allTitles.getString(5);
String Scurr = allTitles.getString(6);
String Qnty = allTitles.getString(7);
String IncVat = allTitles.getString(8);
String StQnty = allTitles.getString(9);
String MinQnty = allTitles.getString(10);
String MaxQnty = allTitles.getString(11);
String Class = allTitles.getString(12);
String StkLoc = allTitles.getString(13);
String currQnty = allTitles.getString(14);
String VatDate = allTitles.getString(15);
String Ttime = allTitles.getString(16);
allData.add(Item + "!" + Name + "!" + Cprice + "!" + Ccurr
+ "!" + Sprice + "!" + Scurr + "!" + Qnty + "!"
+ IncVat + "!" + StQnty + "!" + MinQnty + "!" + MaxQnty
+ "!" + Class + "!" + StkLoc + "!" + currQnty + "!"
+ VatDate + "!" + Ttime + "");
} while (allTitles.moveToNext());
dbI.close();
} catch (Exception e) {
e.printStackTrace();
dbI.close();
}
}
/**
* Background Async Task to Load all product by making HTTP Request
* */
class LoadAllPictures2 extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Dialog
* */
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(_context);
pDialog.setMessage(ProjectEngine.fillDataMsg);
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
/**
* getting All products from url
* */
#Override
protected String doInBackground(String... args) {
// Load Image from res
try {
for (int i = 0; i < allData.size(); i++) {
OutputStream fOut = null;
File file = new File(directory,
allData.get(i).split("!")[0].toString() + ".jpeg");
if (file.exists())
file.delete();
file.createNewFile();
fOut = new FileOutputStream(file);
Drawable ditemp = _context.getResources().getDrawable(
R.drawable.nopicture);
Bitmap image = ((BitmapDrawable) ditemp).getBitmap();
image.compress(Bitmap.CompressFormat.JPEG, 100, fOut);
fOut.flush();
fOut.close();
}
} catch (Exception e) {
// Log.e("saveToExternalStorage()", e.getMessage());
}
return null;
}
/**
* After completing background task Dismiss the progress dialog
* **/
#Override
protected void onPostExecute(String file_url) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Intent prevIntent = new Intent(_context, GridViewActivity.class);
_context.startActivity(prevIntent);
pDialog.dismiss();
}
}
/**
* Background Async Task to Load all product by making HTTP Request
* */
class LoadAllPictures extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Dialog
* */
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(_context);
pDialog.setMessage(ProjectEngine.fillDataMsg);
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
/**
* getting All products from url
* */
#Override
protected String doInBackground(String... args) {
// loop through all files
for (int i = 0; i < listFiles.length; i++) {
// get file path
String filePath = listFiles[i].getAbsolutePath();
// check for supported file extension
if (IsSupportedFile(filePath)) {
// Add image path to array list
filePaths.add(filePath);
}
}
return null;
}
/**
* After completing background task Dismiss the progress dialog
* **/
#Override
protected void onPostExecute(String file_url) {
pDialog.dismiss();
}
}
}
please any help will be appropriated,
Most likely it's a problem with the path to the directory holding your pictures. Please compare the value returned by Environment.getExternalStorageDirectory() method on your phone with the one returned on the emulator. They may be different, thus you may need to move your images accordingly.
Related
I use broadcastreceiver of media folder android.hardware.action.NEW_PICTURE service to rename and move image using this code and it was running:
CameraReciver
package perim.ebrahimi.ir.perim;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
public class CameraReciver extends BroadcastReceiver {
private States states;
private SessionManager session;
private WriteService main;
#Override
public void onReceive(Context context, Intent intent) {
getStates(context);
if(states.getAPP()){
Cursor cursor = context.getContentResolver().query(intent.getData(), null, null, null, null);
cursor.moveToFirst();
if(cursor!=null){
String image_path = cursor.getString(cursor.getColumnIndex("_data"));
main = new WriteService();
main.writeFolder(image_path, states, context);
}
cursor.close();
} else abortBroadcast();
}
// OK
private void getStates(Context context){
session = new SessionManager(context.getApplicationContext());
states = new States();
states = session.getSession();
}
}
and here is WriteService:
package perim.ebrahimi.ir.perim;
import android.app.Activity;
import android.app.Application;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.widget.Toast;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class WriteService extends Activity {
private States states;
private Context context;
private static CalendarJalalian cal;
private static int day ;
private static int month ;
private static int year ;
private static int saat ;
private static int minut ;
private static int secnd ;
private int orientation = -1;
private static final int REQUEST_EXTERNAL_STORAGE = 100;
private static final int REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS=200;
private boolean mExternalStorageAvailable = false;
private boolean mExternalStorageWriteable = false;
// #Override
// protected void onCreate(Bundle savedInstanceState) {
// super.onCreate(savedInstanceState);
// //setContentView(R.layout.activity_main);
//
// // A simple check of whether runtime permissions need to be managed
// if (Build.VERSION.SDK_INT >= 23) {
// checkMultiplePermissions();
// }
// }
public void writeFolder(String image_path, States _states, Context _context){
states = _states;
context= _context;
cal = new CalendarJalalian();
long fileSize = new File(image_path).length();
Cursor mediaCursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
new String[] {MediaStore.Images.ImageColumns.ORIENTATION,
MediaStore.MediaColumns.SIZE },
MediaStore.MediaColumns.DATE_ADDED + ">=?",
new String[]{String.valueOf(cal.getTimeInMillis()/1000 - 1)},
MediaStore.MediaColumns.DATE_ADDED + " desc");
if (mediaCursor != null && mediaCursor.getCount() !=0 ) {
while(mediaCursor.moveToNext()){
long size = mediaCursor.getLong(1);
if(size == fileSize){
orientation = mediaCursor.getInt(0);
break;
}
}
}
orientation = (orientation<0)?0:orientation;
image_path = changeName(image_path);
if(image_path.length()==0) return;
String image_jadid = copyFile(image_path);
if(states.getMain() && image_jadid.length()>0){
removeMain(image_path);
removeMedia(context, new File(image_path));
}
if(states.getPayam()) Toast.makeText(this, getText(R.string.imageSaved)+": "+states.getKhas(), 500).show();
}
private void checkExternalStorage(){
String[] aaa = new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE};
ActivityCompat.requestPermissions(this, aaa , REQUEST_EXTERNAL_STORAGE);
if(ContextCompat.checkSelfPermission(context, android.Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_EXTERNAL_STORAGE);
} else {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
mExternalStorageAvailable = mExternalStorageWriteable = true;
} else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
mExternalStorageAvailable = true;
mExternalStorageWriteable = false;
} else {
mExternalStorageAvailable = mExternalStorageWriteable = false;
}
}
}
private static void removeMedia(Context context, File f) {
ContentResolver resolver = context.getContentResolver();
resolver.delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, MediaStore.Images.Media.DATA + "=?", new String[] { f.getAbsolutePath() });
}
// OK
private String changeName(String image_path){
String result = "";
day = cal.getDay();
month = cal.getMonth();
year = cal.getYear();
saat = Integer.parseInt(cal.getHHour());
minut = Integer.parseInt(cal.getMinute());
secnd = Integer.parseInt(cal.getSecond());
String persianDateName = String.format("%1$s_%2$s_%3$s__%4$s_%5$s_%6$s.jpg",
year,
((month<10)?"0"+month:month),
((day<10)?"0"+day:day),
((saat<10)?"0"+saat:saat),
((minut<10)?"0"+minut:minut),
((secnd<10)?"0"+secnd:secnd));
File from = new File(image_path);
if(from.exists()){
if(states.getOnimage()){
addTextToImage(image_path, persianDateName);
}
File to = new File(from.getParentFile(),persianDateName);
try
{
boolean b = from.renameTo(to);
if (!b) {
copy(from, to);
from.delete();
}
removeMedia(context, from);
sendToMedia(to, persianDateName);
result = to.getAbsolutePath();
}
catch(Exception ex){
ex.printStackTrace();
}
}
return result;
}
private void addTextToImage(String from, String persianDateName) {
Log.i("info","Draw "+persianDateName+" on image");
try
{
Log.i("info","1");
FileOutputStream fos = new FileOutputStream(from);
if(fos==null) Log.i("info","fos = null");
Log.i("info","2 = "+from);
Bitmap bitmap = BitmapFactory.decodeFile(from);
if(bitmap==null) Log.i("info","bitmap = null");
// Log.i("info","3");
android.graphics.Bitmap.Config bitmapConfig = bitmap.getConfig();
if(bitmapConfig==null) Log.i("info","bitmapConfig = null");
// Log.i("info","4");
// if (bitmapConfig == null) {
// bitmapConfig = android.graphics.Bitmap.Config.ARGB_8888;
// }
Log.i("info","5");
bitmap = bitmap.copy(bitmapConfig, true);
Log.i("info","6");
Canvas canvas = new Canvas(bitmap);
Log.i("info","7");
Resources resources = this.getResources();
float scale = resources.getDisplayMetrics().density;
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.rgb(61, 61, 61));
paint.setTextSize((int) (14 * scale));
paint.setShadowLayer(1f, 0f, 1f, Color.WHITE);
Rect qab = new Rect();
paint.getTextBounds(persianDateName, 0, persianDateName.length(), qab);
int x = (bitmap.getWidth() - qab.width()) / 2;
int y = (bitmap.getHeight() + qab.height()) / 2;
canvas.drawText(persianDateName, x, y, paint);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
}
catch (IOException e)
{
e.printStackTrace();
}
Log.i("info","Text added on image");
}
private void copy(final File f1, final File f2) throws IOException {
if(f2.exists()) f2.delete();
//checkExternalStorage();
checkMultiplePermissions();
if(mExternalStorageAvailable && mExternalStorageWriteable) {
f2.createNewFile();
final RandomAccessFile file1 = new RandomAccessFile(f1, "r");
final RandomAccessFile file2 = new RandomAccessFile(f2, "rw");
file2.getChannel().write(file1.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, f1.length()));
file1.close();
file2.close();
}
}
private boolean canRename(final File f1, final File f2) {
final String p1 = f1.getAbsolutePath().replaceAll("^(/mnt/|/)", "");
final String p2 = f2.getAbsolutePath().replaceAll("^(/mnt/|/)", "");
return p1.replaceAll("\\/\\w+", "").equals(p2.replaceAll("\\/\\w+", ""));
}
// OK
private void removeMain(String image_path){
File f = new File(image_path);
if(f.exists()) f.delete();
}
// OK
private File createFileName(){
day = cal.getDay();
month = cal.getMonth();
year = cal.getYear();
saat = Integer.parseInt(cal.getHHour());
minut = Integer.parseInt(cal.getMinute());
secnd = Integer.parseInt(cal.getSecond());
String persianDateName = String.format("%1$s_%2$s_%3$s__%4$s_%5$s_%6$s.jpg",
year,
((month<10)?"0"+month:month),
((day<10)?"0"+day:day),
((saat<10)?"0"+saat:saat),
((minut<10)?"0"+minut:minut),
((secnd<10)?"0"+secnd:secnd));
String masirFolder = "";
if(states.getSal()) masirFolder += year;
if(states.getMah()) masirFolder += File.separator+ year+"_"+((month<10)?"0"+month:month);
if(states.getRuz()) masirFolder += File.separator+ year+"_"+((month<10)?"0"+month:month)+"_"+((day<10)?"0"+day:day);
if(states.getSaat()) masirFolder += File.separator+ year+"_"+((month<10)?"0"+month:month)+"_"+((day<10)?"0"+day:day)+"_"+((saat<10)?"0"+saat:saat);
if(states.getMinut()) masirFolder += File.separator+ year+"_"+((month<10)?"0"+month:month)+"_"+((day<10)?"0"+day:day)+"_"+((saat<10)?"0"+saat:saat)+"_"+((minut<10)?"0"+minut:minut);
if(states.getKhas().length()>0) masirFolder += File.separator+states.getKhas();
File directTime = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), masirFolder);
if (!directTime.mkdir()) makeDir(directTime);
directTime = new File(directTime, persianDateName);
return directTime;
}
// OK
private void makeDir(File direct){
direct.mkdirs();
}
// OK
private String copyFile(String image_path){
String masir = "";
File sourceFile = new File(image_path);
if (!sourceFile.exists()) {return masir;}
File destinationFile = createFileName();
FileChannel source = null;
FileChannel destination = null;
try {
source = new FileInputStream(sourceFile).getChannel();
destination = new FileOutputStream(destinationFile).getChannel();
if (destination != null && source != null) {
destination.transferFrom(source, 0, source.size());
}
if (source != null) {
source.close();
}
if (destination != null) {
destination.close();
}
masir = destinationFile.getName();
sendToMedia(destinationFile, masir);
masir = destinationFile.getAbsolutePath();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return masir;
}
// OK
private void sendToMedia(File imageFile, String imageTitle){
ContentValues image = new ContentValues();
Date dateTaken = new Date();
File parent = imageFile.getParentFile();
String path = parent.toString().toLowerCase();
String name = parent.getName().toLowerCase();
image.put(MediaStore.Images.Media.TITLE, imageTitle);
image.put(MediaStore.Images.Media.DISPLAY_NAME, String.format(this.getText(R.string.imageDisplayName).toString(),states.getKhas()));
image.put(MediaStore.Images.Media.DESCRIPTION, String.format(this.getText(R.string.imageDescription).toString(),name));
image.put(MediaStore.Images.Media.DATE_ADDED, dateTaken.toString());
image.put(MediaStore.Images.Media.DATE_TAKEN, dateTaken.toString());
image.put(MediaStore.Images.Media.DATE_MODIFIED, dateTaken.toString());
image.put(MediaStore.Images.Media.MIME_TYPE, "image/png");
image.put(MediaStore.Images.Media.ORIENTATION, orientation);//getImageOrientation(imageFile.getAbsolutePath()));
image.put(MediaStore.Images.ImageColumns.BUCKET_ID, path.hashCode());
image.put(MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME, name);
image.put(MediaStore.Images.Media.SIZE, imageFile.length());
image.put(MediaStore.Images.Media.DATA, imageFile.getAbsolutePath());
this.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, image);
}
private void checkMultiplePermissions() {
if (Build.VERSION.SDK_INT >= 23) {
List<String> permissionsNeeded = new ArrayList<String>();
List<String> permissionsList = new ArrayList<String>();
if (!addPermission(permissionsList, android.Manifest.permission.ACCESS_FINE_LOCATION)) {
permissionsNeeded.add("GPS");
}
if (!addPermission(permissionsList, android.Manifest.permission.READ_EXTERNAL_STORAGE)) {
permissionsNeeded.add("Read Storage");
}
if (permissionsList.size() > 0) {
requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
return;
}
}
}
private boolean addPermission(List<String> permissionsList, String permission) {
try {
if (Build.VERSION.SDK_INT >= 23)
if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
permissionsList.add(permission);
if (!shouldShowRequestPermissionRationale(permission))
return false;
}
} catch(Exception ex){
ex.printStackTrace();
}
return true;
}
}
But class addPermission raise error:
java.lang.NullPointerException: Attempt to invoke virtual method 'int
android.content.Context.checkSelfPermission(java.lang.String)' on a
null object reference
I think the way I call activity is not correct, but I have no idea how to do it, please help.
Edit:
I have found this difference in returned path:
String image_path = cursor.getString(cursor.getColumnIndex("_data"));
The changed part is obvious:
old but correct path: /storage/emulated/0/DCIM/Camera/IMG_20161215_173334.jpg
new but incorrect path: /storage/3466-033/DCIM/Camera/IMG_20161215_173334.jpg
I think since new devices permit user to select where to save Images, then returning address is changed accordingly.
How to get correct address out of cursor?
You can't do that with a broadcast receiver. You can check if you have a permission via ContextCompat.checkSelfPermission, but in order to request the permission, you need to call ActivityCompat.requestPermissions. It needs an activity, and the result will also arrive to that activity.
Given that, the best solution for you is to implement some activity which will explain the user what is going on and request the permission. If the broadcast receiver detects that it doesn't have the necessary permission, it would launch this activity. When the permission is granted, the normal operation would be resumed.
I have to say that as a user it would be very weird to me if a dialog with a permission request suddenly popped up out of the blue, so I think it's for the best that you need to have an activity to request permissions.
Judging by your path, however, it is definitely somewhere on the SD card. This means that the SD card write restrictions apply. That means that requesting permissions for writing won't help. Take a look at this question: How to avoid the “EACCES permission denied” on SD card?
I need to store multimedia files in Amazons3.
I used the following code for uploading a the file.
Method 1:
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.StrictMode;
import android.util.Log;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.AbortMultipartUploadRequest;
import com.amazonaws.services.s3.model.CannedAccessControlList;
import com.amazonaws.services.s3.model.CompleteMultipartUploadRequest;
import com.amazonaws.services.s3.model.CompleteMultipartUploadResult;
import com.amazonaws.services.s3.model.InitiateMultipartUploadRequest;
import com.amazonaws.services.s3.model.InitiateMultipartUploadResult;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.PartETag;
import com.amazonaws.services.s3.model.ProgressEvent;
import com.amazonaws.services.s3.model.ProgressListener;
import com.amazonaws.services.s3.model.UploadPartRequest;
import com.amazonaws.services.s3.model.UploadPartResult;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class AmazonUploader {
private static final long MIN_DEFAULT_PART_SIZE = 5 * 1024 * 1024;
private static final String TAG = "AmazonUploader";
private static final String PREFS_NAME = "preferences_simpl3r";
private static final String PREFS_UPLOAD_ID = "_uploadId";
private static final String PREFS_ETAGS = "_etags";
private static final String PREFS_ETAG_SEP = "~~";
private AmazonS3Client s3Client;
private String s3bucketName;
private String s3key;
private File file;
private SharedPreferences prefs;
private long partSize = MIN_DEFAULT_PART_SIZE;
private UploadProgressListener progressListener;
private long bytesUploaded = 0;
private boolean userInterrupted = false;
private boolean userAborted = false;
public AmazonUploader(Context context, AmazonS3Client s3Client, String s3bucketName, String s3key, File file) {
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
this.s3Client = s3Client;
this.s3key = s3key;
this.s3bucketName = s3bucketName;
this.file = file;
prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
}
/**
* Initiate a multipart file upload to Amazon S3
*
* #return the URL of a successfully uploaded file
*/
public String start() {
// initialize
List<PartETag> partETags = new ArrayList<PartETag>();
final long contentLength = file.length();
long filePosition = 0;
int startPartNumber = 1;
userInterrupted = false;
userAborted = false;
bytesUploaded = 0;
// check if we can resume an incomplete download
String uploadId = getCachedUploadId();
if (uploadId != null) {
// we can resume the download
Log.i(TAG, "resuming upload for " + uploadId);
// get the cached etags
List<PartETag> cachedEtags = getCachedPartEtags();
partETags.addAll(cachedEtags);
// calculate the start position for resume
startPartNumber = cachedEtags.size() + 1;
filePosition = (startPartNumber - 1) * partSize;
bytesUploaded = filePosition;
Log.i(TAG, "resuming at part " + startPartNumber + " position " + filePosition);
} else {
// initiate a new multi part upload
Log.i(TAG, "initiating new upload");
InitiateMultipartUploadRequest initRequest = new InitiateMultipartUploadRequest(s3bucketName, s3key);
// ObjectMetadata obj = new ObjectMetadata();
// obj.setContentType("image/jpeg");
// obj.setHeader(Constants.APP_HEADER_REFERER, Constants.APP_REFERER_URL);
// initRequest.setObjectMetadata(obj);
configureInitiateRequest(initRequest);
InitiateMultipartUploadResult initResponse = s3Client.initiateMultipartUpload(initRequest);
uploadId = initResponse.getUploadId();
}
final AbortMultipartUploadRequest abortRequest = new AbortMultipartUploadRequest(s3bucketName, s3key, uploadId);
for (int k = startPartNumber; filePosition < contentLength; k++) {
long thisPartSize = Math.min(partSize, (contentLength - filePosition));
Log.i(TAG, "starting file part " + k + " with size " + thisPartSize);
UploadPartRequest uploadRequest = new UploadPartRequest().withBucketName(s3bucketName)
.withKey(s3key).withUploadId(uploadId)
.withPartNumber(k).withFileOffset(filePosition).withFile(file)
.withPartSize(thisPartSize);
ProgressListener s3progressListener = new ProgressListener() {
public void progressChanged(ProgressEvent progressEvent) {
// bail out if user cancelled
// TODO calling shutdown too brute force?
if (userInterrupted) {
s3Client.shutdown();
throw new UploadIterruptedException("User interrupted");
} else if (userAborted) {
// aborted requests cannot be resumed, so clear any cached etags
clearProgressCache();
s3Client.abortMultipartUpload(abortRequest);
s3Client.shutdown();
}
bytesUploaded += progressEvent.getBytesTransfered();
//Log.d(TAG, "bytesUploaded=" + bytesUploaded);
// broadcast progress
float fpercent = ((bytesUploaded * 100) / contentLength);
int percent = Math.round(fpercent);
if (progressListener != null) {
progressListener.progressChanged(progressEvent, bytesUploaded, percent);
}
}
};
uploadRequest.setProgressListener(s3progressListener);
UploadPartResult result = s3Client.uploadPart(uploadRequest);
partETags.add(result.getPartETag());
// cache the part progress for this upload
if (k == 1) {
initProgressCache(uploadId);
}
// store part etag
cachePartEtag(result);
filePosition += thisPartSize;
}
CompleteMultipartUploadRequest compRequest = new CompleteMultipartUploadRequest(
s3bucketName, s3key, uploadId,
partETags);
CompleteMultipartUploadResult result = s3Client.completeMultipartUpload(compRequest);
bytesUploaded = 0;
Log.i(TAG, "upload complete for " + uploadId);
clearProgressCache();
return result.getLocation();
}
private String getCachedUploadId() {
return prefs.getString(s3key + PREFS_UPLOAD_ID, null);
}
private List<PartETag> getCachedPartEtags() {
List<PartETag> result = new ArrayList<PartETag>();
// get the cached etags
ArrayList<String> etags = SharedPreferencesUtils.getStringArrayPref(prefs, s3key + PREFS_ETAGS);
for (String etagString : etags) {
String partNum = etagString.substring(0, etagString.indexOf(PREFS_ETAG_SEP));
String partTag = etagString.substring(etagString.indexOf(PREFS_ETAG_SEP) + 2, etagString.length());
PartETag etag = new PartETag(Integer.parseInt(partNum), partTag);
result.add(etag);
}
return result;
}
private void cachePartEtag(UploadPartResult result) {
String serialEtag = result.getPartETag().getPartNumber() + PREFS_ETAG_SEP + result.getPartETag().getETag();
ArrayList<String> etags = SharedPreferencesUtils.getStringArrayPref(prefs, s3key + PREFS_ETAGS);
etags.add(serialEtag);
SharedPreferencesUtils.setStringArrayPref(prefs, s3key + PREFS_ETAGS, etags);
}
private void initProgressCache(String uploadId) {
// store uploadID
Editor edit = prefs.edit().putString(s3key + PREFS_UPLOAD_ID, uploadId);
AmazonSharedPreferencesCompact.apply(edit);
// create empty etag array
ArrayList<String> etags = new ArrayList<String>();
SharedPreferencesUtils.setStringArrayPref(prefs, s3key + PREFS_ETAGS, etags);
}
private void clearProgressCache() {
// clear the cached uploadId and etags
Editor edit = prefs.edit();
edit.remove(s3key + PREFS_UPLOAD_ID);
edit.remove(s3key + PREFS_ETAGS);
AmazonSharedPreferencesCompact.apply(edit);
}
public void interrupt() {
userInterrupted = true;
}
public void abort() {
userAborted = true;
}
/**
* Override to configure the multipart upload request.
* <p/>
* By default uploaded files are publicly readable.
*
* #param initRequest S3 request object for the file to be uploaded
*/
protected void configureInitiateRequest(InitiateMultipartUploadRequest initRequest) {
initRequest.setCannedACL(CannedAccessControlList.PublicRead);
ObjectMetadata obj = new ObjectMetadata();
obj.setContentType("image/jpeg");
obj.setHeader(Constants.APP_HEADER_REFERER, Constants.APP_REFERER_URL);
initRequest.withObjectMetadata(obj);
}
public void setPrefs(SharedPreferences prefs) {
this.prefs = prefs;
}
public long getPartSize() {
return partSize;
}
public void setPartSize(long partSize) {
if (partSize < MIN_DEFAULT_PART_SIZE) {
throw new IllegalStateException("Part size is less than S3 minimum of " + MIN_DEFAULT_PART_SIZE);
} else {
this.partSize = partSize;
}
}
public void setProgressListener(UploadProgressListener progressListener) {
this.progressListener = progressListener;
}
public interface UploadProgressListener {
public void progressChanged(ProgressEvent progressEvent, long bytesUploaded, int percentUploaded);
}
}
Method 2:
TransferObserver transferObserver = transferUtility.upload(
Constants.S3_BUCKET_NAME, /* The bucket to upload to */
fileName, /* The key for the uploaded object */
new File(imagePath), /* The file where the data to upload exists */
objectMetadata);
transferObserverListener(transferObserver);
in both method i got the following error
com.amazonaws.services.s3.model.AmazonS3Exception: Forbidden (Service: Amazon S3; Status Code: 403; Error Code: 403 Forbidden; Request...
Here i must pass customer header parameters, so i add like following
ObjectMetadata objectMetadata = new ObjectMetadata();
HashMap<String, String> mMetaMap = new HashMap<String, String>();
mMetaMap.put("content-type", "image/jpeg");
mMetaMap.put(Constants.APP_HEADER_REFERER, Constants.APP_REFERER_URL);
objectMetadata.setUserMetadata(mMetaMap);
But still i got the above error.
Is i'm passing the header parameters in correct way either i need to do changes. Kindly advise on this. Thanks
I am developing android app where SQlite as a database.I want to export certain result from DB in to excel file format programatically, want to store that excel to local device path
I have come across following links
SQlite database programmatically convert into Excel file format in Android
Android - Generate CSV file from table values
android exporting to csv and sending as email attachment
So what is exact procedure to implement Export to Excel for android apps ?
Guys here is answer that I have implemented successfully
//new async task for file export to csv
private class ExportDatabaseCSVTask extends AsyncTask<String, String, Boolean> {
private final ProgressDialog dialog = new ProgressDialog(SearchResultActivity.this);
boolean memoryErr = false;
// to show Loading dialog box
#Override
protected void onPreExecute() {
this.dialog.setMessage("Exporting database...");
this.dialog.show();
}
// to write process
protected Boolean doInBackground(final String... args) {
boolean success = false;
String currentDateString = new SimpleDateFormat(Constants.SimpleDtFrmt_ddMMyyyy).format(new Date());
File dbFile = getDatabasePath("HLPL_FRETE.db");
Log.v(TAG, "Db path is: " + dbFile); // get the path of db
File exportDir = new File(Environment.getExternalStorageDirectory() + File.separator + Constants.FileNm.FILE_DIR_NM, "");
long freeBytesInternal = new File(getApplicationContext().getFilesDir().getAbsoluteFile().toString()).getFreeSpace();
long megAvailable = freeBytesInternal / 1048576;
if (megAvailable < 0.1) {
System.out.println("Please check"+megAvailable);
memoryErr = true;
}else {
exportDirStr = exportDir.toString();// to show in dialogbox
Log.v(TAG, "exportDir path::" + exportDir);
if (!exportDir.exists()) {
exportDir.mkdirs();
}
try {
List<SalesActivity> listdata = salesLst;
SalesActivity sa = null;
String lob = null;
for (int index = 0; index < listdata.size();) {
sa = listdata.get(index);
lob = sa.getLob();
break;
}
if (Constants.Common.OCEAN_LOB.equals(lob)) {
file = new File(exportDir, Constants.FileNm.FILE_OFS + currentDateString + ".csv");
} else {
file = new File(exportDir, Constants.FileNm.FILE_AFS + currentDateString + ".csv");
}
file.createNewFile();
CSVWriter csvWrite = new CSVWriter(new FileWriter(file));
// this is the Column of the table and same for Header of CSV
// file
if (Constants.Common.OCEAN_LOB.equals(lob)) {
csvWrite.writeNext(Constants.FileNm.CSV_O_HEADER);
}else{
csvWrite.writeNext(Constants.FileNm.CSV_A_HEADER);
}
String arrStr1[] = { "SR.No", "CUTSOMER NAME", "PROSPECT", "PORT OF LOAD", "PORT OF DISCHARGE" };
csvWrite.writeNext(arrStr1);
if (listdata.size() > 0) {
for (int index = 0; index < listdata.size(); index++) {
sa = listdata.get(index);
String pol;
String pod;
if (Constants.Common.OCEAN_LOB.equals(sa.getLob())) {
pol = sa.getPortOfLoadingOENm();
pod = sa.getPortOfDischargeOENm();
} else {
pol = sa.getAirportOfLoadNm();
pod = sa.getAirportOfDischargeNm();
}
int srNo = index;
String arrStr[] = { String.valueOf(srNo + 1), sa.getCustomerNm(), sa.getProspectNm(), pol, pod };
csvWrite.writeNext(arrStr);
}
success = true;
}
csvWrite.close();
} catch (IOException e) {
Log.e("SearchResultActivity", e.getMessage(), e);
return success;
}
}
return success;
}
// close dialog and give msg
protected void onPostExecute(Boolean success) {
if (this.dialog.isShowing()) {
this.dialog.dismiss();
}
if (success) {
dialogBox(Constants.Flag.FLAG_EXPRT_S);
} else {
if (memoryErr==true) {
dialogBox(Constants.Flag.FLAG_MEMORY_ERR);
} else {
dialogBox(Constants.Flag.FLAG_EXPRT_F);
}
}
}
}
this is my answer: And this works !
Excel file is the same as a .csv file.
Step 1: download this jar file https://code.google.com/p/opencsv/downloads/detail?name=opencsv-2.4.jar&can=2&q=
Step 2:
private class ExportDatabaseCSVTask extends AsyncTask<String ,String, String>{
private final ProgressDialog dialog = new ProgressDialog(MainActivity.this);
#Override
protected void onPreExecute() {
this.dialog.setMessage("Exporting database...");
this.dialog.show();
}
protected String doInBackground(final String... args){
File exportDir = new File(Environment.getExternalStorageDirectory(), "");
if (!exportDir.exists()) {
exportDir.mkdirs();
}
File file = new File(exportDir, "ExcelFile.csv");
try {
file.createNewFile();
CSVWriter csvWrite = new CSVWriter(new FileWriter(file));
//data
ArrayList<String> listdata= new ArrayList<String>();
listdata.add("Aniket");
listdata.add("Shinde");
listdata.add("pune");
listdata.add("anything#anything");
//Headers
String arrStr1[] ={"First Name", "Last Name", "Address", "Email"};
csvWrite.writeNext(arrStr1);
String arrStr[] ={listdata.get(0), listdata.get(1), listdata.get(2), listdata.get(3)};
csvWrite.writeNext(arrStr);
csvWrite.close();
return "";
}
catch (IOException e){
Log.e("MainActivity", e.getMessage(), e);
return "";
}
}
#SuppressLint("NewApi")
#Override
protected void onPostExecute(final String success) {
if (this.dialog.isShowing()){
this.dialog.dismiss();
}
if (success.isEmpty()){
Toast.makeText(MainActivity.this, "Export successful!", Toast.LENGTH_SHORT).show();
}
else {
Toast.makeText(MainActivity.this, "Export failed!", Toast.LENGTH_SHORT).show();
}
}
}
Write Async task in your .java file
Step3: Add call this task
ExportDatabaseCSVTask task=new ExportDatabaseCSVTask();
task.execute();
ExcelFile.csv file will be created in your sdcard.
ExportDatabaseCSVTask:
public class ExportDatabaseCSVTask extends AsyncTask<String, Void, Boolean> {
private final ProgressDialog dialog = new ProgressDialog(MainActivity.this);
#Override
protected void onPreExecute() {
this.dialog.setMessage("Exporting database...");
this.dialog.show();
}
protected Boolean doInBackground(final String... args) {
String currentDBPath = "/data/"+ "your Package name" +"/databases/abc.db";
File dbFile = getDatabasePath(""+currentDBPath);
System.out.println(dbFile); // displays the data base path in your logcat
File exportDir = new File(Environment.getExternalStorageDirectory(), "/your Folder Name/");
if (!exportDir.exists()) { exportDir.mkdirs(); }
File file = new File(exportDir, "myfile.csv");
try {
file.createNewFile();
CSVWriter csvWrite = new CSVWriter(new FileWriter(file));
Cursor curCSV = simpledb.rawQuery("select * from " + tablename,null);
csvWrite.writeNext(curCSV.getColumnNames());
while(curCSV.moveToNext()) {
String arrStr[]=null;
String[] mySecondStringArray = new String[curCSV.getColumnNames().length];
for(int i=0;i<curCSV.getColumnNames().length;i++)
{
mySecondStringArray[i] =curCSV.getString(i);
}
csvWrite.writeNext(mySecondStringArray);
}
csvWrite.close();
curCSV.close();
return true;
} catch (IOException e) {
Log.e("MainActivity", e.getMessage(), e);
return false;
}
}
protected void onPostExecute(final Boolean success) {
if (this.dialog.isShowing()) { this.dialog.dismiss(); }
if (success) {
Toast.makeText(MainActivity.this, "Export successful!", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "Export failed", Toast.LENGTH_SHORT).show();
}
}
}
CSVWriter:
public class CSVWriter {
private PrintWriter pw;
private char separator;
private char quotechar;
private char escapechar;
private String lineEnd;
/** The character used for escaping quotes. */
public static final char DEFAULT_ESCAPE_CHARACTER = '"';
/** The default separator to use if none is supplied to the constructor. */
public static final char DEFAULT_SEPARATOR = ',';
/**
* The default quote character to use if none is supplied to the
* constructor.
*/
public static final char DEFAULT_QUOTE_CHARACTER = '"';
/** The quote constant to use when you wish to suppress all quoting. */
public static final char NO_QUOTE_CHARACTER = '\u0000';
/** The escape constant to use when you wish to suppress all escaping. */
public static final char NO_ESCAPE_CHARACTER = '\u0000';
/** Default line terminator uses platform encoding. */
public static final String DEFAULT_LINE_END = "\n";
/**
* Constructs CSVWriter using a comma for the separator.
*
* #param writer
* the writer to an underlying CSV source.
*/
public CSVWriter(Writer writer) {
this(writer, DEFAULT_SEPARATOR, DEFAULT_QUOTE_CHARACTER,
DEFAULT_ESCAPE_CHARACTER, DEFAULT_LINE_END);
}
/**
* Constructs CSVWriter with supplied separator, quote char, escape char and line ending.
*
* #param writer
* the writer to an underlying CSV source.
* #param separator
* the delimiter to use for separating entries
* #param quotechar
* the character to use for quoted elements
* #param escapechar
* the character to use for escaping quotechars or escapechars
* #param lineEnd
* the line feed terminator to use
*/
public CSVWriter(Writer writer, char separator, char quotechar, char escapechar, String lineEnd) {
this.pw = new PrintWriter(writer);
this.separator = separator;
this.quotechar = quotechar;
this.escapechar = escapechar;
this.lineEnd = lineEnd;
}
/**
* Writes the next line to the file.
*
* #param nextLine
* a string array with each comma-separated element as a separate
* entry.
*/
public void writeNext(String[] nextLine) {
if (nextLine == null)
return;
StringBuffer sb = new StringBuffer();
for (int i = 0; i < nextLine.length; i++) {
if (i != 0) {
sb.append(separator);
}
String nextElement = nextLine[i];
if (nextElement == null)
continue;
if (quotechar != NO_QUOTE_CHARACTER)
sb.append(quotechar);
for (int j = 0; j < nextElement.length(); j++) {
char nextChar = nextElement.charAt(j);
if (escapechar != NO_ESCAPE_CHARACTER && nextChar == quotechar) {
sb.append(escapechar).append(nextChar);
} else if (escapechar != NO_ESCAPE_CHARACTER && nextChar == escapechar) {
sb.append(escapechar).append(nextChar);
} else {
sb.append(nextChar);
}
}
if (quotechar != NO_QUOTE_CHARACTER)
sb.append(quotechar);
}
sb.append(lineEnd);
pw.write(sb.toString());
}
/**
* Flush underlying stream to writer.
*
* #throws IOException if bad things happen
*/
public void flush() throws IOException {
pw.flush();
}
/**
* Close the underlying stream writer flushing any buffered content.
*
* #throws IOException if bad things happen
*
*/
public void close() throws IOException {
pw.flush();
pw.close();
}
}
I have recently implemented the excel export function in my app. I have also included my full code on how to export filtered data to excel instead of the whole table.
You will need to create a second table for this. The second that will hold the data you require for this operation (In my second table I have removed my autoincrament ID column because I dont want it in my excel file).
You will need to clear the second table first and then add entries.
Then use the SqLiteToExcel object to export db to excel and save the file somewhere.
Then I have an email intent with the excel file attached for sharing (allows sharing with other apps other than email). here is my method:
private void ExportData() {
//CHECK IF YOU HAVE WRITE PERMISSIONS OR RETURN
int permission = ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permission != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(getContext(), "Storage permissions not granted", Toast.LENGTH_SHORT).show();
return;
}
//get database object
myDbhelper = new MyDbHelper(getContext());
SQLiteDatabase database = myDbhelper.getWritableDatabase();
//delete all entries in the second table
database.delete("Table2",null,null);
//Create a cursor of the main database with your filters and sort order applied
Cursor cursor = getActivity().getContentResolver().query(
uri,
projections,
selection,
args,
sortOrder);
//loop through cursor and add entries from first table to second table
try {
while (cursor.moveToNext()) {
final String ColumnOneIndex = cursor.getString(cursor.getColumnIndexOrThrow("COLUMN_ONE"));
final String ColumnTwoIndex = cursor.getString(cursor.getColumnIndexOrThrow("COLUMN_TWO"));
final String ColumnThreeIndex = cursor.getString(cursor.getColumnIndexOrThrow("COLUMN_THREE"));
//add entries from table one into the table two
ContentValues values = new ContentValues();
values.put("TABLE2_COLUMN_1", ColumnOneIndex);
values.put("TABLE2_COLUMN_2", ColumnTwoIndex );
values.put("TABLE2_COLUMN_3", ColumnThreeIndex);
database.insert("table2", null, values);
}
} finally {
//close cursor after looping is complete
cursor.close();
}
//create a string for where you want to save the excel file
final String savePath = Environment.getExternalStorageDirectory() + "/excelfileTemp";
File file = new File(savePath);
if (!file.exists()) {
file.mkdirs();
}
//create the sqLiteToExcel object
SQLiteToExcel sqLiteToExcel = new SQLiteToExcel(getContext(), "databasefile.db",savePath);
//use sqLiteToExcel object to create the excel file
sqLiteToExcel.exportSingleTable("table2","excelfilename.xls", new SQLiteToExcel.ExportListener() {
#Override
public void onStart() {
}
#Override
public void onCompleted(String filePath) {
//now attach the excel file created and be directed to email activity
Uri newPath = Uri.parse("file://" + savePath + "/" +"excelfilename.xls");
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
Intent emailintent = new Intent(Intent.ACTION_SEND);
emailintent.setType("application/vnd.ms-excel");
emailintent.putExtra(Intent.EXTRA_SUBJECT, "Subject");
emailintent.putExtra(Intent.EXTRA_TEXT, "I'm email body.");
emailintent.putExtra(Intent.EXTRA_STREAM,newPath);
startActivity(Intent.createChooser(emailintent, "Send Email"));
}
#Override
public void onError(Exception e) {
System.out.println("Error msg: " + e);
Toast.makeText(getContext(), "Failed to Export data", Toast.LENGTH_SHORT).show();
}
});
}
I have this method implemented in my app and it works
The CSV format is "string, string, string /n" for each line,
the "," is the column separator and "/n" for rows.
Get the data from the database and export them like this:
public static Boolean exportToCSV(List<Data> data, File file) {
try {
final String head = "ValueX, ValueY \n";
if (!file.exists()) {
file.createNewFile();
}
FileWriter fileWriter = new FileWriter(file.getAbsoluteFile());
BufferedWriter writer = new BufferedWriter(fileWriter);
writer.write(head);
for (Item item : items) {
final String line = String.format("%s,%s\n",
item.getValueX(),
item.getValueY());
writer.write(line);
}
writer.close();
} catch (IOException e) {
return false;
}
return true;
}
I'm currently loading a webpage using a thread and I need a progress bar to display while the page loads up. Whats the best way to implement this? My code to load the webpage is this
private Thread checkUpdate = new Thread() {
#Override
public void run() {
try {
/**
* establish a URL connection
*/
URL updateURL = new URL("http://www.mtsu.edu/alertupdates/");
URLConnection conn = updateURL.openConnection();
/**
* create an Input stream and buffered array to
* prepare for parsing.
*/
InputStream is = conn.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
ByteArrayBuffer baf = new ByteArrayBuffer(50);
/**
* read in the html and parse it to bytes.
*/
int current = 0;
while((current = bis.read()) != -1){
baf.append((byte)current);
}
/**
* Convert the Bytes read to a String.
*/
html = new String(baf.toByteArray());
int position = html.indexOf("<h1>");
int position2 = html.indexOf("<!--",position);
html = html.substring(position, position2);
mHandler.post(showUpdate);
} catch (Exception e){}
}
};
Here is my attempt at Using AsyncTask and the entire code of my project.
package com.MTSUAndroid;
import java.io.BufferedInputStream;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.Calendar;
import org.apache.http.util.ByteArrayBuffer;
import android.app.Activity;
import android.app.ProgressDialog;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import android.text.Html;
import android.view.Gravity;
import android.view.View;
import java.lang.String;
import android.content.Context;
public class Alerts extends Activity {
/**
* private variables to hold the html strings for parsing.
*/
private String html = "";
private Handler mHandler;
private TextView text1;
private TextView timestamp;
private Button home;
private Button refresh;
private ProgressDialog myProgress;
private int myProgressStatus = 0;
private Handler myHandler = new Handler();
/**
* overriding on create with a new handler for threading
*/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.alerts);
initialControls();
//mHandler = new Handler();
//checkUpdate.start();
}
public void connectivityMessage(String msg){
Context context = getApplicationContext();
Toast toast = Toast.makeText(context, "", Toast.LENGTH_LONG);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.setText(msg);
toast.show();
}
/**
* InitialControls function to set up all the initial controls for the GUI
* Such as buttons, etc...
*/
private void initialControls(){
text1 = (TextView)findViewById(R.id.textView1);
home = (Button)findViewById(R.id.home_button);
//myProgress = (ProgressBar)findViewById(R.id.progressBar1);
home.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
finish();
}
});
/**
* TimeStamp for the alerts refresh button
*/
timestamp = (TextView)findViewById(R.id.timestamp);
refresh = (Button)findViewById(R.id.update);
/**
* implementing the refresh button/loading the website
*/
refresh.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
/**
* establish a URL connection
*/
URL updateURL = new URL("http://www.mtsu.edu/alertupdates/");
URLConnection conn = updateURL.openConnection();
/**
* create an Input stream and buffered array to
* prepare for parsing.
*/
InputStream is = conn.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
ByteArrayBuffer baf = new ByteArrayBuffer(50);
/**
* read in the html and parse it to bytes.
*/
int current = 0;
while((current = bis.read()) != -1){
baf.append((byte)current);
}
/**
* Convert the Bytes read to a String.
*/
html = new String(baf.toByteArray());
int position = html.indexOf("<h1>");
int position2 = html.indexOf("<!--",position);
html = html.substring(position, position2);
mHandler.post(showUpdate);
/**
* using calendar class for the refresh button
*/
Calendar c = Calendar.getInstance();
int seconds = c.get(Calendar.SECOND);
int minutes = c.get(Calendar.MINUTE);
int hours = c.get(Calendar.HOUR);
int years = c.get(Calendar.YEAR);
int months = 1 + c.get(Calendar.MONTH);
int days = c.get(Calendar.DAY_OF_MONTH);
try{
if (c.get(Calendar.AM_PM) == 0)
{
String AM = "";
AM = "AM";
if (hours == 0)
{
hours = 12;
}
timestamp.setText("Refreshed on " + days + "-"
+ months + "-" + years + " " + hours + ":" + minutes + ":" + seconds + " " + AM);
timestamp.setTextSize(17f);
timestamp.setTextColor(Color.GREEN);
}
else
{
String PM = "";
PM = "PM";
timestamp.setText("Refreshed on " + days + "-"
+ months + "-" + years + " " + hours + ":" + minutes + ":" + seconds + " " + PM);
timestamp.setTextSize(17f);
timestamp.setTextColor(Color.GREEN);
}
}
catch (Exception e){}
}
/**
* Catch exception E to catch all errors.
*/
catch (Exception e) {}
}
}
);}
/**
* creating a new thread to run the URL.
*/
private Thread checkUpdate = new Thread() {
#Override
public void run() {
try {
/**
* establish a URL connection
*/
URL updateURL = new URL("http://www.mtsu.edu/alertupdates/");
URLConnection conn = updateURL.openConnection();
/**
* create an Input stream and buffered array to
* prepare for parsing.
*/
InputStream is = conn.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
ByteArrayBuffer baf = new ByteArrayBuffer(50);
/**
* read in the html and parse it to bytes.
*/
int current = 0;
while((current = bis.read()) != -1){
baf.append((byte)current);
}
/**
* Convert the Bytes read to a String.
*/
html = new String(baf.toByteArray());
int position = html.indexOf("<h1>");
int position2 = html.indexOf("<!--",position);
html = html.substring(position, position2);
mHandler.post(showUpdate);
} catch (Exception e){}
}
};
/**
* set the textView to the freshly parsed html for viewing
*/
private Runnable showUpdate = new Runnable(){
#Override
public void run(){
text1.setText(Html.fromHtml(html));
}
};
public class myTask extends AsyncTask<Void,Void,Void>{
ProgressDialog progress;
public myTask(ProgressDialog progress) {
this.progress = progress;
}
#Override
protected void onPreExecute() {
progress = ProgressDialog.show(Alerts.this, "Loading data..", "Please Wait");
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... params) {
try {
/**
* establish a URL connection
*/
URL updateURL = new URL("http://www.mtsu.edu/alertupdates/");
URLConnection conn = updateURL.openConnection();
/**
* create an Input stream and buffered array to
* prepare for parsing.
*/
InputStream is = conn.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
ByteArrayBuffer baf = new ByteArrayBuffer(50);
/**
* read in the html and parse it to bytes.
*/
int current = 0;
while((current = bis.read()) != -1){
baf.append((byte)current);
}
/**
* Convert the Bytes read to a String.
*/
html = new String(baf.toByteArray());
int position = html.indexOf("<h1>");
int position2 = html.indexOf("<!--",position);
html = html.substring(position, position2);
mHandler.post(showUpdate);
} catch (Exception e){}
return null;
}
protected void onPostExecute() {
progress.dismiss();
}
}
}
An AsyncTask will help handle progress for you. Read here: http://developer.android.com/reference/android/os/AsyncTask.html
We have to port our software to android. One of the main feature of our software should be that the software can download a new version of itself from the net (our own server) and install it's new version too. All this thing should be done programmatically.
I'm new to android, so haven't got any clue how should it be done.
How to create apk? - solved
How to sign apk? - solved
How to download apk? - solved
How to copy the downloaded file overwriting /data/apk/my.software.name.apk? - unsolved
How to restart the software by the running version? - unsolved
File file = new File(dir, "App.apk");
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file),
"application/vnd.android.package-archive");
startActivity(intent);
I had the same problem and after several attempts, it worked for me this way. Previously i got my new apk from a webservice.
You do not have to do this. You just upload the new version of your program on the Android Market, and people see it right away. Users who checked the option "update automatically" for your program upgrade automatically without having to give explicit consent ; others see "upgrade available" and can just click 'upgrade' to upgrade to the new version of your program.
If for some reason you're thinking that you want to force the update on the user with or without their consent though, you just cannot do it. You can download the apk and should be able to hand it to the package manager, which in turn will ask the user to confirm whether they actually want to install it - and then again, for that you need the user to have checked the "allow unknown sources" option in development options, else the package manager will downright refuse to do it. But android will not let you install a new package without the user explicitly requesting it, or explicitly allowing auto-updates through the market.
If you have some backward compatibility issue of some sort and want to disallow running of deprecated versions of your application, you can embed in your application some logic that will check on your server for version information and terminate if it's outdated, with a message "this version is outdated, you need to upgrade to continue using this application" or something. But no upgrading in the back of the user.
Sorry for inconvenience this is code and I also posted the XML permissions required to use it.
package com.SelfInstall01;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import com.SelfInstall01.SelfInstall01Activity;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.AlertDialog.Builder;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class SelfInstall01Activity extends Activity
{
class PInfo {
private String appname = "";
private String pname = "";
private String versionName = "";
private int versionCode = 0;
//private Drawable icon;
/*private void prettyPrint() {
//Log.v(appname + "\t" + pname + "\t" + versionName + "\t" + versionCode);
}*/
}
public int VersionCode;
public String VersionName="";
public String ApkName ;
public String AppName ;
public String BuildVersionPath="";
public String urlpath ;
public String PackageName;
public String InstallAppPackageName;
public String Text="";
TextView tvApkStatus;
Button btnCheckUpdates;
TextView tvInstallVersion;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//Text= "Old".toString();
Text= "New".toString();
ApkName = "SelfInstall01.apk";//"Test1.apk";// //"DownLoadOnSDcard_01.apk"; //
AppName = "SelfInstall01";//"Test1"; //
BuildVersionPath = "http://10.0.2.2:82/Version.txt".toString();
PackageName = "package:com.SelfInstall01".toString(); //"package:com.Test1".toString();
urlpath = "http://10.0.2.2:82/"+ Text.toString()+"_Apk/" + ApkName.toString();
tvApkStatus =(TextView)findViewById(R.id.tvApkStatus);
tvApkStatus.setText(Text+" Apk Download.".toString());
tvInstallVersion = (TextView)findViewById(R.id.tvInstallVersion);
String temp = getInstallPackageVersionInfo(AppName.toString());
tvInstallVersion.setText("" +temp.toString());
btnCheckUpdates =(Button)findViewById(R.id.btnCheckUpdates);
btnCheckUpdates.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View arg0)
{
GetVersionFromServer(BuildVersionPath);
if(checkInstalledApp(AppName.toString()) == true)
{
Toast.makeText(getApplicationContext(), "Application Found " + AppName.toString(), Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(getApplicationContext(), "Application Not Found. "+ AppName.toString(), Toast.LENGTH_SHORT).show();
}
}
});
}// On Create END.
private Boolean checkInstalledApp(String appName){
return getPackages(appName);
}
// Get Information about Only Specific application which is Install on Device.
public String getInstallPackageVersionInfo(String appName)
{
String InstallVersion = "";
ArrayList<PInfo> apps = getInstalledApps(false); /* false = no system packages */
final int max = apps.size();
for (int i=0; i<max; i++)
{
//apps.get(i).prettyPrint();
if(apps.get(i).appname.toString().equals(appName.toString()))
{
InstallVersion = "Install Version Code: "+ apps.get(i).versionCode+
" Version Name: "+ apps.get(i).versionName.toString();
break;
}
}
return InstallVersion.toString();
}
private Boolean getPackages(String appName)
{
Boolean isInstalled = false;
ArrayList<PInfo> apps = getInstalledApps(false); /* false = no system packages */
final int max = apps.size();
for (int i=0; i<max; i++)
{
//apps.get(i).prettyPrint();
if(apps.get(i).appname.toString().equals(appName.toString()))
{
/*if(apps.get(i).versionName.toString().contains(VersionName.toString()) == true &&
VersionCode == apps.get(i).versionCode)
{
isInstalled = true;
Toast.makeText(getApplicationContext(),
"Code Match", Toast.LENGTH_SHORT).show();
openMyDialog();
}*/
if(VersionCode <= apps.get(i).versionCode)
{
isInstalled = true;
/*Toast.makeText(getApplicationContext(),
"Install Code is Less.!", Toast.LENGTH_SHORT).show();*/
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface dialog, int which) {
switch (which)
{
case DialogInterface.BUTTON_POSITIVE:
//Yes button clicked
//SelfInstall01Activity.this.finish(); Close The App.
DownloadOnSDcard();
InstallApplication();
UnInstallApplication(PackageName.toString());
break;
case DialogInterface.BUTTON_NEGATIVE:
//No button clicked
break;
}
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("New Apk Available..").setPositiveButton("Yes Proceed", dialogClickListener)
.setNegativeButton("No.", dialogClickListener).show();
}
if(VersionCode > apps.get(i).versionCode)
{
isInstalled = true;
/*Toast.makeText(getApplicationContext(),
"Install Code is better.!", Toast.LENGTH_SHORT).show();*/
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface dialog, int which) {
switch (which)
{
case DialogInterface.BUTTON_POSITIVE:
//Yes button clicked
//SelfInstall01Activity.this.finish(); Close The App.
DownloadOnSDcard();
InstallApplication();
UnInstallApplication(PackageName.toString());
break;
case DialogInterface.BUTTON_NEGATIVE:
//No button clicked
break;
}
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("NO need to Install.").setPositiveButton("Install Forcely", dialogClickListener)
.setNegativeButton("Cancel.", dialogClickListener).show();
}
}
}
return isInstalled;
}
private ArrayList<PInfo> getInstalledApps(boolean getSysPackages)
{
ArrayList<PInfo> res = new ArrayList<PInfo>();
List<PackageInfo> packs = getPackageManager().getInstalledPackages(0);
for(int i=0;i<packs.size();i++)
{
PackageInfo p = packs.get(i);
if ((!getSysPackages) && (p.versionName == null)) {
continue ;
}
PInfo newInfo = new PInfo();
newInfo.appname = p.applicationInfo.loadLabel(getPackageManager()).toString();
newInfo.pname = p.packageName;
newInfo.versionName = p.versionName;
newInfo.versionCode = p.versionCode;
//newInfo.icon = p.applicationInfo.loadIcon(getPackageManager());
res.add(newInfo);
}
return res;
}
public void UnInstallApplication(String packageName)// Specific package Name Uninstall.
{
//Uri packageURI = Uri.parse("package:com.CheckInstallApp");
Uri packageURI = Uri.parse(packageName.toString());
Intent uninstallIntent = new Intent(Intent.ACTION_DELETE, packageURI);
startActivity(uninstallIntent);
}
public void InstallApplication()
{
Uri packageURI = Uri.parse(PackageName.toString());
Intent intent = new Intent(android.content.Intent.ACTION_VIEW, packageURI);
// Intent intent = new Intent(android.content.Intent.ACTION_VIEW);
//intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//intent.setFlags(Intent.ACTION_PACKAGE_REPLACED);
//intent.setAction(Settings. ACTION_APPLICATION_SETTINGS);
intent.setDataAndType
(Uri.fromFile(new File(Environment.getExternalStorageDirectory() + "/download/" + ApkName.toString())),
"application/vnd.android.package-archive");
// Not open this Below Line Because..
////intent.setClass(this, Project02Activity.class); // This Line Call Activity Recursively its dangerous.
startActivity(intent);
}
public void GetVersionFromServer(String BuildVersionPath)
{
//this is the file you want to download from the remote server
//path ="http://10.0.2.2:82/Version.txt";
//this is the name of the local file you will create
// version.txt contain Version Code = 2; \n Version name = 2.1;
URL u;
try {
u = new URL(BuildVersionPath.toString());
HttpURLConnection c = (HttpURLConnection) u.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect();
//Toast.makeText(getApplicationContext(), "HttpURLConnection Complete.!", Toast.LENGTH_SHORT).show();
InputStream in = c.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024]; //that stops the reading after 1024 chars..
//in.read(buffer); // Read from Buffer.
//baos.write(buffer); // Write Into Buffer.
int len1 = 0;
while ( (len1 = in.read(buffer)) != -1 )
{
baos.write(buffer,0, len1); // Write Into ByteArrayOutputStream Buffer.
}
String temp = "";
String s = baos.toString();// baos.toString(); contain Version Code = 2; \n Version name = 2.1;
for (int i = 0; i < s.length(); i++)
{
i = s.indexOf("=") + 1;
while (s.charAt(i) == ' ') // Skip Spaces
{
i++; // Move to Next.
}
while (s.charAt(i) != ';'&& (s.charAt(i) >= '0' && s.charAt(i) <= '9' || s.charAt(i) == '.'))
{
temp = temp.toString().concat(Character.toString(s.charAt(i))) ;
i++;
}
//
s = s.substring(i); // Move to Next to Process.!
temp = temp + " "; // Separate w.r.t Space Version Code and Version Name.
}
String[] fields = temp.split(" ");// Make Array for Version Code and Version Name.
VersionCode = Integer.parseInt(fields[0].toString());// .ToString() Return String Value.
VersionName = fields[1].toString();
baos.close();
}
catch (MalformedURLException e) {
Toast.makeText(getApplicationContext(), "Error." + e.getMessage(), Toast.LENGTH_SHORT).show();
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(), "Error." + e.getMessage(), Toast.LENGTH_SHORT).show();
}
//return true;
}// Method End.
// Download On My Mobile SDCard or Emulator.
public void DownloadOnSDcard()
{
try{
URL url = new URL(urlpath.toString()); // Your given URL.
HttpURLConnection c = (HttpURLConnection) url.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect(); // Connection Complete here.!
//Toast.makeText(getApplicationContext(), "HttpURLConnection complete.", Toast.LENGTH_SHORT).show();
String PATH = Environment.getExternalStorageDirectory() + "/download/";
File file = new File(PATH); // PATH = /mnt/sdcard/download/
if (!file.exists()) {
file.mkdirs();
}
File outputFile = new File(file, ApkName.toString());
FileOutputStream fos = new FileOutputStream(outputFile);
// Toast.makeText(getApplicationContext(), "SD Card Path: " + outputFile.toString(), Toast.LENGTH_SHORT).show();
InputStream is = c.getInputStream(); // Get from Server and Catch In Input Stream Object.
byte[] buffer = new byte[1024];
int len1 = 0;
while ((len1 = is.read(buffer)) != -1) {
fos.write(buffer, 0, len1); // Write In FileOutputStream.
}
fos.close();
is.close();//till here, it works fine - .apk is download to my sdcard in download file.
// So please Check in DDMS tab and Select your Emulator.
//Toast.makeText(getApplicationContext(), "Download Complete on SD Card.!", Toast.LENGTH_SHORT).show();
//download the APK to sdcard then fire the Intent.
}
catch (IOException e)
{
Toast.makeText(getApplicationContext(), "Error! " +
e.toString(), Toast.LENGTH_LONG).show();
}
}
}