Dropbox Sync API Android - Updating Cached Files - android

I am facing trouble in updating the existing cached file within my Android Application.
for(DbxFileInfo fInfo : fileList)
{
Log.d(TAG, "File Path = "+fInfo.path.toString());
String fileName = fInfo.path.getName().trim();
try
{
DbxPath tempFilePath = new DbxPath(fInfo.path.toString());
DbxFile tempFile = mDbFileSystem.open(tempFilePath);
if(tempFile.getSyncStatus().isCached)
{
Log.v(TAG, "File is already cached !");
if(tempFile.getSyncStatus().isLatest)
{
Log.v(TAG, "File's Latest Version is Cached !");
}
else
{
Log.v(TAG, "File's Latest Version is not Cached !");
}
}
try
{
tempFile.getNewerStatus();
}
catch(Exception dBException)
{
Log.e(TAG, "Error while getting newer Status !");
}
InputStream input = new BufferedInputStream(tempFile.getReadStream());
OutputStream output = new FileOutputStream(cntx.getFilesDir() + "/SyncedData/" + fileName);
byte data[] = new byte[1024];
int count;
//total size is in Bytes
while ((count = input.read(data)) != -1)
{
totalBytesDownloaded += count;
publishProgress((int) (totalBytesDownloaded * 100/totalFileSize));
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
tempFile.close();
mDbFileSystem.delete(tempFile.getPath());
result = true;
}
catch(Exception e)
{
Log.e(TAG, "Error occured while downloading files !, Error = "+e.toString());
result = false;
}
}
I am putting different files with same names on my Synced Dropbox folder and after Downloading them i am getting the older version of files.
Is there any way i can update my existing cached files or Clear the Dropbox Cache (that is within my App)
Any help is highly appreciated, thanks.

Here's how the Sync API works:
It constantly syncs metadata (what files exist and their revisions) and notifies you via listeners you set up on the file system.
For open files, it downloads any newer version of the file available and notifies you via the listener you set up on the file itself.
So if you want to get the latest version of a file, you need to open the file and hold it open while waiting for the listener to notify you that the newer version of the file is cached. Then you can call update to get access to that new data.
EDIT: Pasting code from https://www.dropbox.com/developers/sync/start/android#listeners:
DbxFileStatus status = testFile.getSyncStatus();
if (!status.isCached) {
testFile.addListener(new DbxFile.Listener() {
#Override
public void onFileChange(DbxFile file) {
// Check testFile.getSyncStatus() and read if it's ready
}
});
// Check if testFile.getSyncStatus() is ready already to ensure nothing
// was missed while adding the listener
}

Here is my attempt to get the latest file but as I stated in the comment to your question, it seems I sometimes have to do two sync calls in order to get the latest file.
The fileModified and fileSize comparison is rather crude but seems to do the trick. Better than what I have found so far at least.
public DropboxFileDownloader() {
super("FileDownloader");
}
#Override
protected void onHandleIntent(Intent intent) {
String turiosHome = intent.getStringExtra(Constants.EXTRA_HOME);
String fileName = intent.getStringExtra(Constants.EXTRA_FILENAME);
String folderPath = intent.getStringExtra(Constants.EXTRA_FOLDERPATH);
ResultReceiver receiver = intent.getParcelableExtra(Constants.EXTRA_RECEIVER);
Bundle bundle = new Bundle();
String fullpath = folderPath + "/" + fileName;
DbxFile file;
long fileModified = 0;
long fileSize = 0;
try {
file = dbxFs.open(new DbxPath(fullpath));
try {
DbxFileStatus fileStatus = file.getNewerStatus();
if (fileStatus != null && !fileStatus.isLatest) {
/*while (file.getNewerStatus().pending == PendingOperation.DOWNLOAD) {
Log.d(TAG, "Waiting for " + fileName + " to be downloaded");
Thread.sleep(1000);
}*/
if (fileStatus.isCached) {
//Start of Edit
try
{
//Running this do while loop until the Latest version of this file is cached.
do
{
Log.d(TAG, "Updating the existing file !");
//Updating the file
file.update();
while (file.getNewerStatus().pending ==PendingOperation.DOWNLOAD)
{
Log.d(TAG, "Waiting for " + fileName+ " to be downloaded");
Thread.sleep(1000);
}
} while (fileStatus.isLatest);
}
catch (Exception dBException)
{
Log.e(TAG, "Error while getting newer Status !, Error = "+dBException.toString());
dBException.printStackTrace();
}
//End of Edit
}
}
fileModified = file.getInfo().modifiedTime.getTime();
fileSize = file.getInfo().size;
} catch (DbxException e) {
Log.e(TAG, e.getMessage(), e);
bundle.putString(Constants.EXTRA_MESSAGE, e.getMessage());
receiver.send(DropboxFileDownloaderResultReceiver.RESULTCODE_ERROR, bundle);
return;
} catch (InterruptedException e) {
e.printStackTrace();
}
} catch (InvalidPathException e1) {
Log.e(TAG, e1.getMessage(), e1);
bundle.putString(Constants.EXTRA_MESSAGE, e1.getMessage());
receiver.send(DropboxFileDownloaderResultReceiver.RESULTCODE_ERROR, bundle);
return;
} catch (DbxException e1) {
Log.e(TAG, e1.getMessage(), e1);
bundle.putString(Constants.EXTRA_MESSAGE, e1.getMessage());
receiver.send(DropboxFileDownloaderResultReceiver.RESULTCODE_ERROR, bundle);
return;
}
File stored_dir = new File(turiosHome + "/" + folderPath);
if (!stored_dir.exists()) {
stored_dir.mkdirs();
}
File stored_file = new File(turiosHome + "/" + folderPath,
fileName);
// File stored_file = getFileStreamPath(fileName);
long local_modified = stored_file.lastModified();
long local_size = stored_file.length();
boolean should_sync = (fileModified > local_modified)
|| fileSize != local_size;// && Math.abs(fileModified -
// local_modified) >
// TimeUnit.MILLISECONDS.convert(1,
// TimeUnit.MINUTES);
boolean fileexists = stored_file.exists();
if (should_sync || !fileexists) {
InputStream inputStream = null;
FileOutputStream out = null;
try {
// read this file into InputStream
inputStream = file.getReadStream();
out = new FileOutputStream(stored_file);
int read = 0;
byte[] bytes = new byte[1024];
int bytes_counter = 0;
while ((read = inputStream.read(bytes)) != -1) {
out.write(bytes, 0, read);
bytes_counter++;
}
Log.d(TAG, "Wrote: " + file.getPath().getName() + " "
+ bytes_counter + " kb");
if (!fileexists) {
bundle.putString(Constants.EXTRA_FILEPATH, fullpath);
receiver.send(DropboxFileDownloaderResultReceiver.RESULTCODE_CREATED, bundle);
} else {
bundle.putString(Constants.EXTRA_FILEPATH, fullpath);
receiver.send(DropboxFileDownloaderResultReceiver.RESULTCODE_UPDATED, bundle);
}
} catch (IOException e) {
Log.e(TAG, e.getMessage(), e);
bundle.putString(Constants.EXTRA_MESSAGE, e.getMessage());
receiver.send(DropboxFileDownloaderResultReceiver.RESULTCODE_ERROR, bundle);
} finally {
try {
if (inputStream != null) {
inputStream.close();
}
if (out != null) {
out.flush();
out.close();
}
} catch (IOException e) {
Log.e(TAG, e.getMessage(), e);
bundle.putString(Constants.EXTRA_MESSAGE, e.getMessage());
receiver.send(DropboxFileDownloaderResultReceiver.RESULTCODE_ERROR, bundle);
}
}
}
else {
bundle.putString(Constants.EXTRA_FILEPATH, fullpath);
receiver.send(DropboxFileDownloaderResultReceiver.RESULTCODE_UPTODATE, bundle);
}
file.close();
}
}

I can't found working example for me. But for my case - i don't need cashed version of files - only newest (data synchronization between devices).
I used
mDbFileSystem.setMaxFileCacheSize(0);
All or nothing. But now nessasary thread for downloading in background.

Related

java.io.FileNotFoundException: /: open failed: EISDIR (Is a directory)

File albumF = getVideoAlbumDir();
String path = albumF.getAbsolutePath();
// path =/storage/emulated/0/Pictures/.MyImages (Hidden folder)
// fileSelected.fileName()=IMG_20140417_113847.jpg
File localFile = new File(path + "/" + fileSelected.fileName());
Log.v("", "file exist===" + localFile.exists());
if (!localFile.exists()) {
Log.v("", "inside if===");
Log.v("", "Parent Filet===" + localFile.getParentFile());
localFile.getParentFile().mkdirs();
// localFile.createNewFile();
copy(fileSelected, localFile);
} else {
Log.v("", "inside else===");
mCurrentPhotoPath = localFile.getAbsolutePath();
uploadMediaFile();
}
This copy method copies data from dropbox file to my local storage.
private void copy(final Entry fileSelected, final File localFile) {
final ProgressDialog pd = ProgressDialog.show(ChatActivity.this,
"Downloading...", "Please wait...");
new Thread(new Runnable() {
#Override
public void run() {
BufferedInputStream br = null;
BufferedOutputStream bw = null;
DropboxInputStream fd;
try {
fd = mDBApi.getFileStream(fileSelected.path,
localFile.getAbsolutePath());
br = new BufferedInputStream(fd);
bw = new BufferedOutputStream(new FileOutputStream(
localFile));
byte[] buffer = new byte[4096];
int read;
while (true) {
read = br.read(buffer);
if (read <= 0) {
break;
}
bw.write(buffer, 0, read);
}
pd.dismiss();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
android.os.Message msg = new android.os.Message();
msg.arg1 = 100;
if (msg.arg1 >= 100) {
progressHandler.sendMessage(msg);
mCurrentPhotoPath = localFile.getAbsolutePath();
}
} catch (DropboxException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bw != null) {
try {
bw.close();
if (br != null) {
br.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}).start();
I am creating file in a folder using localFile.getParentFile().mkdirs();
I got above error when I upload this file to server.
how to fix this?
If you've tried all other options - and problem still persists - then maybe you have a case when the file you want to create matches name of already existing directory.(which might be earlier created my some call to mkdirs() maybe accidentally).
Example:
You want to save file Test\test.pdf but you already have folder Test\Test.pdf\

Android FTP client application- how to download the file from FTP Server

i am using org.apache.commons.net.ftp library, i have uploaded the file but when i try to download the file from FTP Server to my emulator's virtual SDCard it didn't work.
how to specify the destination path? that is the SD Card path where i need to download, and how to specify the source file path ( file in FTP server page path)?
here is the code i tried to perform the download,
try
{
FileOutputStream desFileStream1 = new FileOutputStream("/sdcard/Baby.jpg");
Boolean status1 = con.retrieveFile("/Baby", desFileStream1);
if(status1)
{
lblResult2.setText("File downloaded Successfully");
}
else
{
lblResult2.setText("File download failed");
}
DesFileStream1.close();
} catch (Exception e)
{
Log.d(TAG, "download failed");
}
any one of you help me out.
Use getExternalStorageDirectory() or getExternalStoragePublicDirectory() on Environment to find the proper root of external storage, which is not /sdcard on most Android devices.
File file = new File(Environment.getExternalStorageDirectory() + "/pdf");
if(!file.exists())
file.mkdir(); //directory is created;
try {
ftp = new FTPClient();
ftp.connect("yours ftp URL",21);//don't write ftp://
try {
int reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
throw new Exception("Connect failed: " + ftp.getReplyString());
}
if (!ftp.login("username","password")) {
throw new Exception("Login failed: " + ftp.getReplyString());
}
try {
ftp.enterLocalPassiveMode();
if (!ftp.setFileType(FTP.BINARY_FILE_TYPE)) {
// Log.e(TAG, "Setting binary file type failed.");
}
transferFile(ftp);
} catch(Exception e) {
// handleThrowable(e);
} finally {
if (!ftp.logout()) {
// Log.e(TAG, "Logout failed.");
}
}
} catch(Exception e) {
// handleThrowable(e);
} finally {
ftp.disconnect();
}
} catch(Exception e) {
// handleThrowable(e);
}
}
private void transferFile(FTPClient ftp) throws Exception {
long fileSize=0;
fileSize = getFileSize(ftp, "nag.pdf");
Log.v("async","fileSize"+fileSize);
if(!(fileSize==0)){
InputStream is = retrieveFileStream(ftp, "nag.pdf");
downloadFile(is, fileSize);
is.close();
}
else
//nosuch files
if (!ftp.completePendingCommand()) {
throw new Exception("Pending command failed: " + ftp.getReplyString());
}
}
private InputStream retrieveFileStream(FTPClient ftp, String filePath)
throws Exception {
InputStream is = ftp.retrieveFileStream(filePath);
int reply = ftp.getReplyCode();
if (is == null
|| (!FTPReply.isPositivePreliminary(reply)
&& !FTPReply.isPositiveCompletion(reply))) {
throw new Exception(ftp.getReplyString());
}
return is;
}
private byte[] downloadFile(InputStream is, long fileSize)
throws Exception {
outputStream os = newFileOutputStream(Environment.getExternalStorageDirectory()
+ "/pdf/nag.pdf");
byte[] buffer = new byte[(int) fileSize];
int readCount;
while( (readCount = is.read(buffer)) > 0) {
os.write(buffer, 0, readCount);
}
Log.i("tag", "buffer = " + buffer);
return buffer; // <-- Here is your file's contents !!!
}
private long getFileSize(FTPClient ftp, String filePath) throws Exception {
long fileSize = 0;
FTPFile[] files = ftp.listFiles(filePath);
if (files.length == 1 && files[0].isFile()) {
fileSize = files[0].getSize();
}
Log.i("tag", "File size = " + fileSize);
return fileSize;
}
}

Android FTPClient - retrieveFileStream() always returns null

I am a newbie to Android. I am trying download a file from ftp server to sdcard using Apache Commons FTPClient. The line InputStream input = client.retrieveFileStream("/" + fileName); always returns null. But the file is there in Ftp location. Kindly help me to know where the mistake is.
I have set the following permissions in my manifest; android:name="android.permission.INTERNET" and android:name="android.permission.WRITE_EXTERNAL_STORAGE"
My Code
private static void downLoad(){
FTPClient client = new FTPClient();
FileOutputStream fos = null;
try {
client.connect("ftp.doamin.com");
client.login("8888", "8888");
String filePath = "/mnt/sdcard/download/CheckboxHTML.txt" ;
String fileName = "CheckboxHTML.txt";
fos = new FileOutputStream(filePath);
InputStream input = client.retrieveFileStream("/" + fileName);
byte[] data = new byte[1024];
int count = input.read(data);
while ((count = input.read(data)) != -1) {
fos.write(data, 0, count);
}
fos.close();
if(!client.completePendingCommand()) {
client.logout();
client.disconnect();
System.err.println("File transfer failed.");
}
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Thanks for your time and interest. Ananth.
AFAIK. You are suppose to finalize file transfers by calling completePendingCommand() and verifying that the transfer was indeed successful. i.e. you need to add call the function below fos.clos().
fos.close();
client.completePendingCommand()
You may also consider this, according to the API for FTPClient.retrieveFileStream(), the method returns null when it cannot open the data connection, in which case you should check the reply code (e.g. getReplyCode(), getReplyString(), getReplyStrings()) to see why it failed.
File file = new File(Environment.getExternalStorageDirectory() + "/pdf");
if(!file.exists())
file.mkdir(); //directory is created;
try {
ftp = new FTPClient();
ftp.connect("yours ftp URL",21);//don't write ftp://
try {
int reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
throw new Exception("Connect failed: " + ftp.getReplyString());
}
if (!ftp.login("username","password")) {
throw new Exception("Login failed: " + ftp.getReplyString());
}
try {
ftp.enterLocalPassiveMode();
if (!ftp.setFileType(FTP.BINARY_FILE_TYPE)) {
// Log.e(TAG, "Setting binary file type failed.");
}
transferFile(ftp);
} catch(Exception e) {
// handleThrowable(e);
} finally {
if (!ftp.logout()) {
// Log.e(TAG, "Logout failed.");
}
}
} catch(Exception e) {
// handleThrowable(e);
} finally {
ftp.disconnect();
}
} catch(Exception e) {
// handleThrowable(e);
}
}
private void transferFile(FTPClient ftp) throws Exception {
long fileSize=0;
fileSize = getFileSize(ftp, "nag.pdf");
Log.v("async","fileSize"+fileSize);
if(!(fileSize==0)){
InputStream is = retrieveFileStream(ftp, "nag.pdf");
downloadFile(is, fileSize);
is.close();
}
else
//nosuch files
if (!ftp.completePendingCommand()) {
throw new Exception("Pending command failed: " + ftp.getReplyString());
}
}
private InputStream retrieveFileStream(FTPClient ftp, String filePath)
throws Exception {
InputStream is = ftp.retrieveFileStream(filePath);
int reply = ftp.getReplyCode();
if (is == null
|| (!FTPReply.isPositivePreliminary(reply)
&& !FTPReply.isPositiveCompletion(reply))) {
throw new Exception(ftp.getReplyString());
}
return is;
}
private byte[] downloadFile(InputStream is, long fileSize)
throws Exception {
outputStream os = newFileOutputStream(Environment.getExternalStorageDirectory()
+ "/pdf/nag.pdf");
byte[] buffer = new byte[(int) fileSize];
int readCount;
while( (readCount = is.read(buffer)) > 0) {
os.write(buffer, 0, readCount);
}
Log.i("tag", "buffer = " + buffer);
return buffer; // <-- Here is your file's contents !!!
}
private long getFileSize(FTPClient ftp, String filePath) throws Exception {
long fileSize = 0;
FTPFile[] files = ftp.listFiles(filePath);
if (files.length == 1 && files[0].isFile()) {
fileSize = files[0].getSize();
}
Log.i("tag", "File size = " + fileSize);
return fileSize;
}
}
After have worked on this problem and spent hours, I've found out that the Android Apache retrieveFile() and retrieveFileStream sometimes don't work very well when the FileSize is too big.
Ensure to set the right TypeFile to BinaryFile
mFTPClient.setFileType(FTP.BINARY_FILE_TYPE);
Also never forget to pass in LocalPassiveMode for download commands
mFTPClient.enterLocalPassiveMode();

Android / Java: HttpURLConnection doesn't return headers of redirected file (e.g. on S3)

My code (reproduced below), connects to a url and downloads the file to disk on android. All standard stuff. When I try using this code on a file on S3 accessed via a subdomain on our server mapped to a bucket (e.g. foo.example.com => bucket called foo.example.com), it often fails. Turns out (using the handy curl command..
"curl -v -L -X GET http://foo.example.com/f/a.txt")
.. that there's a redirect going on here.
The file download works ok, as HttpURLConnection will follow redirects by default, but the calls that require the header infomation (getContentLength, getHeaderFieldDate("Last-Modified", 0 ) etc) are returns the headers from the 307 redirect, and not the actual file thats downloaded.
Anyone know how to get around this?
Thanks
File local = null;
try {
Log.i(TAG, "Downloading file " + source);
conn = (HttpURLConnection) new URL(source).openConnection();
fileSize = conn.getContentLength(); // ** THIS IS WRONG ON REDIRECTED FILES
out = new BufferedOutputStream(new FileOutputStream(destination, false), 8 * 1024);
conn.connect();
stream = new BufferedInputStream(conn.getInputStream(), 8 * 1024);
byte[] buffer = new byte[MAX_BUFFER_SIZE];
while (true) {
int read = stream.read(buffer);
if (read == -1) {
break;
}
// writing to buffer
out.write(buffer, 0, read);
downloaded += read;
publishProgress(downloaded, fileSize);
if (isCancelled()) {
return "The user cancelled the download";
}
}
} catch (Exception e) {
String msg = "Failed to download file " + source + ". " + e.getMessage();
Log.e(TAG, msg );
return msg;
} finally {
if (out != null) {
try {
out.flush();
out.close();
} catch (IOException e) {
Log.e(TAG, "Failed to close file " + destination);
e.printStackTrace();
}
}
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
Log.e(TAG, "Failed to close file " + destination);
e.printStackTrace();
}
} else {
long dateLong = conn.getHeaderFieldDate("Last-Modified", 0 ); // ** THIS IS WRONG ON REDIRECTED FILES
Date d = new Date(dateLong);
local.setLastModified(dateLong);
}
have you tried to set redirects to false and try to manually capture the redirected URL and associated header fields with it?
For example something like this:
URL url = new URL(url);
HttpURLConnection ucon = (HttpURLConnection) url.openConnection();
ucon.setInstanceFollowRedirects(false);
URL secondURL = new URL(ucon.getHeaderField("Location"));
URLConnection conn = secondURL.openConnection();
This example captures the redirected URL, but you could easily tweak this to try for any other header field. Does this help?
Consider using httpclient-android. You should get the right headers after redirection with this:
HttpClient client = HttpClientBuilder.create().build();
HttpGet request = new HttpGet(YOUR_URL);
HttpResponse response = client.execute(request);
response.getAllHeaders()
Note that android comes with an older version of httpclient, but it has the same problem as you reported. You actually need to import "httpclient-android" for a newer version.
Note: The code snippet is for v4.3. For other versions, look for how to do it in regular apache HttpClient.
Well, I've been playing a bit and this code, which uses the HttpClient library rather than HttpUrlConnection works fine. The headers it returns are those of the final redirect hop.
At least on the devices I've tested it on.
HttpClient client = null;
HttpGet get = null;
HttpResponse response = null;
try {
client = new DefaultHttpClient();
get = new HttpGet(source);
response = client.execute(get);
Header contentSize = response.getFirstHeader("Content-Length");
if (contentSize != null) {
String value = contentSize.getValue();
fileSize = Long.parseLong(value);
}
if (fileSize == -1) {
Log.e(TAG, "Failed to read the content length for the file " + source);
}
Header lastModified = response.getFirstHeader("Last-Modified");
lastModifiedDate = null;
if (lastModified != null) {
lastModifiedDate = DateUtils.parseDate(lastModified.getValue());
}
if (lastModifiedDate == null) {
Log.e(TAG, "Failed to read the last modified date for the file " + source);
}
out = new BufferedOutputStream(new FileOutputStream(destination, false), 8 * 1024); // false means don't append
stream = new BufferedInputStream(response.getEntity().getContent(), 8 * 1024);
byte[] buffer = new byte[MAX_BUFFER_SIZE];
int count = 0;
while (true) {
int read = stream.read(buffer);
if (read == -1) {
break;
}
// writing to buffer
out.write(buffer, 0, read);
downloaded += read;
publishProgress(downloaded, fileSize);
if (isCancelled()) {
Log.w(TAG, "User Cancelled");
return; // NOTE that onPostExecute is not called here..
}
}// end of while
publishProgress(downloaded, fileSize);
} catch (Exception e) {
String msg = "Failed to download file " + source + ". " + e.getMessage();
Log.e(TAG, msg );
return msg;
} finally {
if (out != null) {
try {
out.flush();
out.close();
} catch (IOException e) {
Log.e(TAG, "Failed to close file " + destination);
e.printStackTrace();
}
}
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
Log.e(TAG, "Failed to close file " + destination);
e.printStackTrace();
}
}
}

Download And Install apk from a link

I`am trying to download and install an apk from some link,
but for some reason i get an exception.
I have one method downloadfile() which downloading the file and a call
to and installFile() method, which supposed to install it in the device.
some code:
public void downloadFile()
{
String fileName = "someApplication.apk";
MsgProxyLogger.debug(TAG, "TAG:Starting to download");
try
{
URL u = new URL(
"http://10.122.233.22/test/someApplication.apk");
try
{
HttpURLConnection c = (HttpURLConnection) u.openConnection();
try
{
c.setRequestMethod("GET");
c.setDoOutput(true);
try
{
c.connect();
FileOutputStream f = context.openFileOutput(fileName,
context.MODE_WORLD_READABLE);
try
{
InputStream in = c.getInputStream();
byte[] buffer = new byte[1024];
int len1 = 0;
int totsize = 0;
try
{
while ((len1 = in.read(buffer)) > 0)
{
totsize += len1;
f.write(buffer, 0, len1);// .write(buffer);
}
} catch (IOException e)
{
e.printStackTrace();
}
f.close();
MsgProxyLogger.debug(TAG, TAG
+ ":Saved file with name: " + fileName);
InstallFile(fileName);
} catch (IOException e)
{
e.printStackTrace();
}
} catch (IOException e)
{
e.printStackTrace();
}
} catch (ProtocolException e)
{
e.printStackTrace();
}
} catch (IOException e)
{
e.printStackTrace();
}
} catch (MalformedURLException e)
{
e.printStackTrace();
}
}
and this is the install file method:
private void InstallFile(String fileName)
{
MsgProxyLogger.debug(TAG, TAG + ":Installing file " + fileName);
String src = String.format(
"file:///data/data/com.test/files/",
fileName);
Uri mPackageURI = Uri.parse(src);
PackageManager pm = context.getPackageManager();
int installFlags = 0;
try
{
PackageInfo pi = pm.getPackageInfo("com.mirs.agentcore.msgproxy",
PackageManager.GET_UNINSTALLED_PACKAGES);
if (pi != null)
{
MsgProxyLogger.debug(TAG, TAG + ":replacing " + fileName);
installFlags |= PackageManager.REPLACE_EXISTING_PACKAGE;
}
} catch (NameNotFoundException e)
{
}
try
{
// PackageInstallObserver observer = new PackageInstallObserver();
pm.installPackage(mPackageURI);
} catch (SecurityException e)
{
//!!!!!!!!!!!!!here i get an security exception!!!!!!!!!!!
MsgProxyLogger.debug(TAG, TAG + ":not permission? " + fileName);
}
this is the exception details:
"Neither user 10057 nor current process has android.permission.INSTALL_PACKAGES".
and i have set in my main app that permission in the manifest.
anyone has any idea?
thanks,
ray.
You cannot install APKs that way -- only applications that are part of the system firmware can do that.
You should be able to use an ACTION_VIEW Intent, with a MIME type of application/vnd.android.package-archive and a Uri pointing to your file. Note that this may not work on devices that do not have "allow non-Market installs" checked.
You need add that permission to manifest
http://developer.android.com/reference/android/Manifest.permission.html

Categories

Resources