Parse error in Android 5.0 , working in previous versions - android

I have an apk to download from a website. It works fine in Android 4, but when I downloaded it with an Android 5.0 device, I got the typical error:
Parse Error
There was a problem while parsing the package
Can anyone shed a bit of light on what is happening?
My server code to get the apk file (I don't want to place the apk file directly to download in website):
InputStream is = ApkDownloadController.class.getResourceAsStream("/apk/fileName.apk");
try {
response.addHeader("Content-Description", "File Transfer");
response.addHeader("Content-Type", " application/vnd.android.package-archive");
response.addHeader("Content-Disposition", "attachment; filename=apkName.apk");
response.addHeader("Content-Transfer-Encoding", "binary");
ServletOutputStream out = response.getOutputStream();
byte[] outputByte = new byte[4096];
// copy binary contect to output stream
while (is.read(outputByte, 0, 4096) != -1) {
out.write(outputByte, 0, 4096);
}
is.close();
out.flush();
out.close();
Thanks all!

Related

error on download apk from own server with movile data

I was implement download apk from my own server, and install that, when i download with wifi its working fine, but when the movile is conected to internet with movile data the transfer is very low, and the apk not donwload, dont give me an error.
The code that i implemented is:
//Download the actual apk
InputStream inputStream = consumirWebService.ventaMovilUpdate("1", direccionUrlBase);
String pathApk = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)+Dictionary.APK_NAME;
OutputStream os = new FileOutputStream(pathApk);
byte[] buffer = new byte[1024];
int bytesRead;
while((bytesRead = inputStream.read(buffer)) !=-1){
os.write(buffer, 0, bytesRead);
}
inputStream.close();
os.flush();
os.close();
//Install the new apk
PackageInfo info = IMAdministrador.this.getPackageManager().getPackageArchiveInfo(pathApk, PackageManager.GET_META_DATA);
File file = new File(pathApk);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.putExtra(Intent.ACTION_PACKAGE_REPLACED, info.packageName);
intent.setDataAndType(Uri.fromFile(file),"application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
if(info.packageName != null){
IMAdministrador.INSTALL_APK_INFO.put(info.packageName, file);
}
I am thinking on download the apk by parts compressed with rest webservices. The weight of apk is 5MB, download each of a parts some thing like 1Mb by part, and when i have the five parts, uncompress and install. But really i dont have idea how can I do that.
Or if you have any best idea, I am very appreciate for your help.
Thanks in advance.

Trouble downloading PNG images in Android

I am facing a problem downloading PNG images from my server to my Android app. The problem is specific to PNG images (JPG works fine), and the issue is that the downloaded files are corrupt images. I will explain in more details, below.
Scenario :
I need to download JPG and PNG images from my server, and display them to the user of the Android app.
Issue :
The JPG images get downloaded without an issue. But the downloaded PNG files are corrupt. I have double checked the source of the images at my server, and they are proper. Its only the downloaded PNG files, that are corrupt. So, the problem probably lies in the way I am downloading them in Android.
Code Sample :
URL imageURL;
File imageFile = null;
InputStream is = null;
FileOutputStream fos = null;
byte[] b = new byte[1024];
try {
// get the input stream and pass to file output stream
imageURL = new URL(image.getServerPath());
imageFile = new File(context.getExternalFilesDir(null), image.getLocalPath());
fos = new FileOutputStream(imageFile);
// get the input stream and pass to file output stream
is = imageURL.openConnection().getInputStream();
// also tried but gave same results :
// is = imageURL.openStream();
while(is.read(b) != -1)
fos.write(b);
} catch (FileNotFoundException e) {
} catch (MalformedURLException e) {
} catch (IOException e) {
} finally {
// close the streams
try {
if(fos != null)
fos.close();
if(is != null)
is.close();
} catch(IOException e){
}
}
Any pointers on how I can work on this, will be very appreciated.
Note :
Since this is happening in a service, there are no problems of doing this inside an AsyncTask.
The problem is here
while(is.read(b) != -1)
fos.write(b);
This is wrong, because in each iteration it will write the full buffer (1024 bytes) to the file. But the previous read could have read less bytes than than (almost surely on the last loop, unless the image lenght happens to be exactly a multiple of 1024). You should check how many bytes were read each time, and write that amount of bytes.
int bytesRead;
while( (bytesRead = is.read(b)) != -1)
fos.write(b,0,bytesRead );
Your error makes you write always files with sizes that are multiple of 1024 - which of course is not the case in general. Now, what happens when a image is saved with extra trailing bytes depends on the format and on the image reader. In some cases, it might work. Still, it's wrong.
BTW: never swallow exceptions - even if that's not the problem today, it might be tomorrow and you might spend hours finding the problem.

Android Java TCP Client Server File Transfer

Edit*
I have successful on the client server. Now I am doing a file transferring between 2 emulators. The file did transfer between the emulators, but I notice that the file size received is not the same as the original file. For example, A.jpg size is 900KB, but the received file is less than 900KB. I checked the file transfer size, found that there were some data(byte) lost when transferring. How is this happening?
Here's the code:
Client (Send File)
File myFile = new File ("/mnt/sdcard/Pictures/A.jpg");
FileInputStream fis = new FileInputStream(myFile);
OutputStream os = socket.getOutputStream();
int filesize = (int) myFile.length();
byte [] buffer = new byte [filesize];
int bytesRead =0;
while ((bytesRead = fis.read(buffer)) > 0) {
os.write(buffer, 0, bytesRead);
//Log display exact the file size
System.out.println("SO sendFile" + bytesRead);
}
os.flush();
os.close();
fis.close();
Log.d("Client", "Client sent message");
socket.close();
Server (Receive File)
FileOutputStream fos = new FileOutputStream("/mnt/sdcard/Pictures/B.jpg");
#SuppressWarnings("resource")
BufferedOutputStream bos = new BufferedOutputStream(fos);
InputStream is = clientSocket.getInputStream();
byte[] aByte = new byte[1024];
int bytesRead;
while ((bytesRead = is.read(aByte)) != -1)
{
bos.write(aByte, 0, bytesRead);
//Log display few parts the file size is less than 1024. I total up, the lost size caused the file received is incomplete
System.out.println("SO sendFile" + bytesRead);
}
clientSocket.close();
*Edit 2
While I surfed around google, I found that .read(buffer) does not guarantee read the full size(byte) of the file. Hence, the received file always lost some bytes (like space, empty character). To solve this, send the file size first to inform the receiver, then only start transfer the file.
NetworkOnMainThreadException occurs because you have to use AsyncTask
NullPointerException occurs because you are trying to use PrintWriter with the result of Sockets. As you have got nothing with Sockets you get this error.
The NetworkOnMainThreadException tells you what you are doing wrong.
You need to put the network stuff into a separate Thread (or AsyncTask or similar).
You can not call any server operation on Main Thread in Android.
In Android O.S 4.0 and above this will directly cause to NetworkOnMainThreadException. You have 2 choices :
1) Either to use AsyncTask to call your every server operation.
2) Or Use User defined Thread for any type of server operation.
I was also struggling with this Exception, only in OS version above 4.0 devices, So you can not ignore these small needs of Android.

Android, VideoView, Internal Storage

currently I'm working on an application that's supposed to download videos onto its internal storage (unfortunately they do NOT have a sd card) and simply play them.
What I've tried so far is:
Standard VideoView, set the /data/data/.../file.mp4 as path - did not work.
Use MediaPlayer with a SurfaceView, use path or file descriptor - did not work.
What I'm having here right now is a slightly modded version of the VideoView, which has the following changes:
if(mUri != null)
{
mMediaPlayer.setDataSource(mContext, mUri);
}
else
{
mMediaPlayer.setDataSource(mFd);
}
Also a setFD method allowing me to set my File Descriptor. This is way easier and cleaner - imo - than putting the whole MediaPlayer/SurfaceView into my activity.
The problem is the following:
The file in the internal storage is created like this:
FileInputStream fis = openFileInput(Downloader.TMP_FILENAME);
FileOutputStream fos = openFileOutput(Downloader.FILENAME
+ ext, Context.MODE_WORLD_READABLE);
byte[] buf = new byte[2048];
while (fis.read(buf) > 0) {
fos.write(buf);
}
fis.close();
fos.close();
deleteFile(Downloader.TMP_FILENAME);
Log.d(TAG, "Replacement done!");
Basically it's reading a temporary file (as I don't want to overwrite the currently played one.. but that doesn't really matter) and writing it (after onCompletion) into the new file, afterwards deleting the temporary file.
I've tested it on 3 different Android versions and devices so far:
- Tablet with Android 2.2
- Nexus 7 with Android 4.2
- HTC Sensation with Android 4.1.2
It simply did not work. It plays lets say the first 100ms of the video incl. sound then a popup pops up and logcat is telling me:
12-19 14:33:48.074: W/MediaPlayer(5560): info/warning (3, 0)
12-19 14:33:48.074: I/MediaPlayer(5560): Info (3,0)
12-19 14:33:48.394: E/MediaPlayer(5560): error (1, -1007)
12-19 14:33:48.394: E/MediaPlayer(5560): Error (1,-1007)
But I really have no idea what this is supposed to mean.
I've searched for it in the whole internet, all I found was "use WORLD_READABLE, it will solve the problem!" or "just use the file descriptor, seems to not care about permissions!". But for me, it does not work.
I'd really appreciate any help.
EDIT:
FileInputStream fid = new FileInputStream((getFilesDir() + "/"
+ Downloader.FILENAME + ext)));
mVideoView.setVideoFD(fid.getFD());
This is how I add the File Descriptor to the MediaPlayer.
After reencoding the file, this is what I get:
12-19 15:06:45.664: E/MediaPlayer(7616): Unable to to create media player
12-19 15:06:45.664: W/System.err(7616): java.io.IOException: setDataSourceFD failed.: status=0x80000000
12-19 15:06:45.664: W/System.err(7616): at android.media.MediaPlayer.setDataSource(Native Method)
12-19 15:06:45.664: W/System.err(7616): at android.media.MediaPlayer.setDataSource(MediaPlayer.java:976)
This is how I download it from my webserver:
Log.i(TAG, "Opening remote connection to " + mFile.getHost()
+ mFile.getPath());
URLConnection c = mFile.openConnection();
c.connect();
final long lastModified = c.getLastModified();
final String mExtension;
if (c.getHeaderField("Content-Disposition") != null) {
final String mFilename = c
.getHeaderField("Content-Disposition").split("=")[1];
Log.i("Downloader", "Filename is " + mFilename
+ ", split length is " + mFilename.split("\\.").length);
mExtension = mFilename.split("\\.")[mFilename
.split("\\.").length - 1];
} else {
mExtension = "mp4";
}
InputStream is = c.getInputStream();
Log.i(TAG, "Creating temporary local file");
// create local temporary file
FileOutputStream fos = mContext.openFileOutput(TMP_FILENAME,
Context.MODE_WORLD_READABLE);
// start reading
byte[] buf = new byte[BUFFER_SIZE];
int bytesRead = 0;
int curRead = 0;
Log.i(TAG, "Starting download.. to " + TMP_FILENAME);
if (mDownloadChangeListener != null)
mDownloadChangeListener.onDownloadStart();
while ((curRead = is.read(buf)) > -1) {
fos.write(buf);
bytesRead += curRead;
}
Log.i(TAG, "Read " + bytesRead + " bytes in total.");
Log.i(TAG, "Download finished!");
// end of stream, tell app to rename file.
if (mDownloadChangeListener != null)
mDownloadChangeListener.onDownloadFinished(TMP_FILENAME,
mExtension);
is.close();
fos.close();
After downloading it, on the onDownloadFinished listener, I execute the following code:
FileInputStream fis = openFileInput(Downloader.TMP_FILENAME);
FileOutputStream fos = openFileOutput(Downloader.FILENAME
+ ext, Context.MODE_WORLD_WRITEABLE);
byte[] buf = new byte[2048];
while (fis.read(buf) > 0) {
fos.write(buf);
}
fis.close();
fos.close();
deleteFile(Downloader.TMP_FILENAME);
Log.d(TAG, "Replacement done!");
Any ideas what could possibly go wrong? My only other idea would be that it's because of the internal storage-thing.. but the error message says something else?
Error -1007 stands for MEDIA_ERROR_MALFORMED. It means that the file you're trying to play doesn't conform to the file specification put down in the official documentation. Something is either wrong with the media you're receiving, or in your method of saving it.
Personally, your method of saving it looks fine to me, so I'm guessing that the source file itself is the problem.
Found the solution. Every way I've tested worked probably, because all errors I received came from "wrong downloaded media files"...
while((curRead = in.read(buf)) {
out.write(buf);
}
Was simply missing a ",0 ,curRead" - all working now. It's obviously because read() can always return less than BUFFER_SIZE and then writes 0-bytes into the rest or something...
Thanks!

Android: Extra bytes in file transferred to device

So, I have a simple Android app that connects to a Java Server application using Sockets.
Specifically, I want to be able to send a file from the Server application to the Android app and then store that file in internal memory on the device.
The basis of the server code for transferring the file is:
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(new File(System.getProperty("user.home"), "text.txt")));
BufferedOutputStream bos = new BufferedOutputStream(clientSocket.getOutputStream());
byte buffer[] = new byte[1024];
int read;
while ((read = bis.read(buffer)) != -1) {
bos.write(buffer, 0, read);
}
bos.flush();
bos.close();
and the Client code to receive the file is as follows:
BufferedInputStream bis = new BufferedInputStream(clientSocket.getInputStream());
BufferedOutputStream bos = new BufferedOutputStream(openFileOutput("text.txt", Context.MODE_PRIVATE));
byte buffer[] = new byte[1024];
int read;
while ((read = bis.read(buffer)) != -1) {
bos.write(buffer, 0, read);
}
bos.flush();
bos.close();
The code appears to work fine when the client code is in a standard Java application, that is, the file sends successfully from server to client.
The problem arises when I use this code in an Android app. (Note: I use a standard FileOutputStream in the standard Java app instead of the
openFileOutput("text.txt", Context.MODE_PRIVATE))
line above).
For example purposes, the file I am transferring is a simple UTF-8 text file, which contains a single string
This is a text file.
However, when I pull this file I have copied to the emulator, from the "/data/data//files" folder on the emulator, there are an extra couple of bytes at the top of the file so the content is now
¨ÌThis is a text file.
I have no idea why this is happening and it has me stumped. I think the problem might be related to the line:
BufferedOutputStream bos = new BufferedOutputStream(openFileOutput("text.txt", Context.MODE_PRIVATE));
but I can't quite figure it out.
Any suggestions as to what I am doing wrong would be most helpful.
Thank you in advance

Categories

Resources