Does base64 decoding disable search in pdf files? - android

There is Arabic encoded pdf file that is received from a server via a web service in my Android application, then I decode it and save it to be cashed to open it anytime,this is the file I download_which also is encoded_ the problem is the file became not searchable anymore, this is the code I use to decode the file:
protected Void doInBackground(String... myLink) {
if (conDetector.isConnectingToInternet()) {
File myDir = getFilesDir();
String fileName = PDFCACHE;
File cachedFile = new File(myDir, fileName);
// to check if the cached file in the memory or not
if (cachedFile.exists()) {
try {
readPDFFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else if (!cachedFile.exists()) {
try {
URL url = new URL(myLink[0]);
URLConnection urlConnection = url.openConnection();
urlConnection.connect();
file_size = urlConnection.getContentLength();
source = new BufferedInputStream(url.openStream(), 8192);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
buffer = new byte[1024];
long total = 0;
int count = 0;
// buffer=new
// Scanner(source).useDelimiter("\\A").next().getBytes();*/
// buffer = Base64.decode(buffer, 0);
for (int i; (i = source.read(buffer)) != -1;) {
total += i;
bos.write(buffer, 0, i); // no doubt here is 0
publishProgress(""
+ (int) ((total * 100) / file_size));
}
if (flag == false) {
bytes = bos.toByteArray();
bytes = Base64.decode(bytes, Base64.DEFAULT);
String decodedString = new String(bytes);
if (bytes != null) {
openBuffer(bytes);
if (manipulateCache())
try {
savePDFFile(bytes);
// source.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
core = openFile(decodedString);
}
}
} catch (MalformedURLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// when there is no internet connection "offline mode"
} else if (!(conDetector.isConnectingToInternet())) {
if (!PDFCACHE.equals(null)) {
try {
readPDFFile();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
} }

The file you received is not searchable, the font objects contain ToUnicode maps claiming most of the glyphs used are numbers, symbols, or Latin characters which does not match their appearance as Arabic characters.
Thus, no standard PDF viewer can be used to search the files.

Related

Using decodeByteArray to convert bitmap: Showing a black image and LogCat shows skimagedecoder factory returned null

I am trying to receive an image from a remote server which sends images every 5 seconds. Right now, on the Android side, I am using decodeByteArray() to convert it to a bitmap. When it is running, sometimes it shows an image on the screen, and sometimes it shows a black screen and the LogCat shows the skimagedecoder factory returning null. I don't know what the problem is.
Here is the code I have:
public class connection extends AsyncTask {
#Override
protected Object doInBackground(Object... arg0) {
int i = 0;
try {
clientSocket = new Socket("134.129.125.126", 8080);
input = clientSocket.getInputStream();
} catch (UnknownHostException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
while (true) {
data = new byte[2048 * 2048];
try {
read = input.read(data, 0, data.length);
System.out.println("getInputStream()");
bitmap = BitmapFactory.decodeByteArray(data, 0, read);
System.out.println("deco");
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
System.out.println(e);
}
runOnUiThread(new Runnable() {
public void run() {
image.setImageBitmap(bitmap);
System.out.println("setImage at less than 500");
}
});
}
}
}
Update
Right now, try to receive the size of image from server, and make became right size of byte array. then decodeByteArray(), it become Factory returned Null again. here is my revised code:
public class connection extends AsyncTask {
#Override
protected Object doInBackground(Object... arg0) {
try {
clientSocket = new Socket("134.129.125.126", 8080);
System.out.println("client connect to server");
input = clientSocket.getInputStream();
System.out.println("getinputstream");
} catch (UnknownHostException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
// while (true) {
int totalBytesRead = 0;
int chunkSize = 0;
int tempRead = 0;
String msg = null;
// byte[] data = null;
byte[] tempByte = new byte[1024 * 1024 * 4];
try {
tempRead = input.read(tempByte);
System.out.println("read:" + tempRead);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
if (tempRead < 2000) {
String message = new String(tempByte, 0, tempRead);
msg = message.substring(0, 6);
System.out.println("message head:" + msg);
byteSize = Integer.parseInt(msg);
System.out.println("ByteSize:" + byteSize);
data = new byte[byteSize];
}
try {
while (chunkSize > -1) {
System.out.println("data length:" + data.length);
chunkSize = input.read(data, totalBytesRead, data.length
- totalBytesRead);
System.out.println("chunkSize is " + chunkSize);
totalBytesRead += chunkSize;
System.out.println("Total byte read " + totalBytesRead);
if (totalBytesRead == data.length) {
if (input.read() != -1) {
// error, the file is larger than our buffer
throw new RuntimeException("Buffer overflow error!");
}
}
}
} catch (Exception e) {
}
bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
System.out.println("deco");
runOnUiThread(new Runnable() {
public void run() {
image.setImageBitmap(bitmap);
System.out.println("setImage at less than 500");
}
});
return null;
}
}
For one thing, there is no guarantee that your read command is reading the whole image. InputStreams tend to read the number of bytes currently available, which may or may not be until end of file, that is implementation dependent.
You should continue reading into your byte array until the value returned from input.read() is -1. This will obviously require a rework of some of the logic to loop until you get a -1 back and have a variable that tracks total bytes read as the summation of all the read calls.
For example, to read everything out of a stream
int totalBytesRead = 0;
int chunkSize = 0;
byte[] fileBuffer = new byte[4 * 1024 * 1024]; // 4MB buffer
while (chunkSize > -1) {
chunkSize = inputStream.read(fileBuffer, totalBytesRead, fileBuffer.length - totalBytesRead);
totalBytesRead += chunkSize;
if (totalBytesRead == fileBuffer.length) {
if (inputStream.read() != -1) {
// error, the file is larger than our buffer
throw new RuntimeException("Buffer overflow error!");
}
}
}

android, Read content of 100-300 files from FTP folder... Hangs

I am using RetrieveFilestream method with BufferedInputStream in a for loop. I am closing all
streams after processing each file and also adding ftp complete pending command.
Every thing works as expected in my test environment with few files. But in realtime data where there are 200-300 files, it hangs somewhere.
It is not throwing any exception making it difficult to debug. Cannot debug one by one. Any help?
Here is my code Block.
public String LoopThroughFiles(FTPClient myftp, String DirectoryName)
{
boolean flag=false;
String output="";
InputStream inStream=null;
BufferedInputStream bInf= null;
StringBuilder mystring = new StringBuilder();
progressBar = (ProgressBar) findViewById(R.id.progressBar);
try {
flag= myftp.changeWorkingDirectory(DirectoryName);
if(flag==true)
{
FTPFile[] files = myftp.listFiles();
progressBar.setMax(files.length);
String fname="";
myftp.enterLocalPassiveMode();
if(files.length > 0)
{
int n=0;
for (FTPFile file : files)
{
n=n+1;
int r= progressBar.getProgress();
progressBar.setProgress(r+n);
fname=file.getName();
// String path= myftp.printWorkingDirectory();
if(fname.indexOf("txt") != -1)
{
inStream = myftp.retrieveFileStream(fname);
int reply = myftp.getReplyCode();
if (inStream == null || (!FTPReply.isPositivePreliminary(reply) && !FTPReply.isPositiveCompletion(reply))) {Log.e("error retrieving file",myftp.getReplyString()); }
bInf=new BufferedInputStream (inStream);
int bytesRead;
byte[] buffer=new byte[1024];
String fileContent=null;
while((bytesRead=bInf.read(buffer))!=-1)
{
fileContent=new String(buffer,0,bytesRead);
mystring.append(fileContent);
}
mystring.append(",");
bInf.close();
inStream.close();
boolean isSucess= myftp.completePendingCommand();
if(isSucess == false)
Log.e("error retrieving file","Failed to retrieve the stream for " + fname);
}
}
flag= myftp.changeToParentDirectory();
}
}
}
catch (java.net.UnknownHostException e) {
e.printStackTrace();
Log.e("readfile,UnknownHost",e.getMessage());
}
catch (java.io.IOException e) {
e.printStackTrace();
Log.e("readfile,IO",e.getMessage());
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.e("readfile,General",e.getMessage());
}
finally
{
try {
output = mystring.toString();
if(bInf != null)
bInf.close();
if(inStream != null)
inStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.e("readfile,finallyblock",e.getMessage());
}
}
return output;
}

Concatenate two audio files and play resulting file

I am really facing problem from last couple of days but I am not able to find the exact solution please help me.
I want to merge two .mp3 or any audio file and play final single one mp3 file. But when I am combine two file the final file size is ok but when I am trying to play it just play first file, I have tried this with SequenceInputStream or byte array but I am not able to get exact result please help me.
My code is the following:
public class MerginFileHere extends Activity {
public ArrayList<String> audNames;
byte fileContent[];
byte fileContent1[];
FileInputStream ins,ins1;
FileOutputStream fos = null;
String combined_file_stored_path = Environment
.getExternalStorageDirectory().getPath()
+ "/AudioRecorder/final.mp3";
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
audNames = new ArrayList<String>();
String file1 = Environment.getExternalStorageDirectory().getPath()
+ "/AudioRecorder/one.mp3";
String file2 = Environment.getExternalStorageDirectory().getPath()
+ "/AudioRecorder/two.mp3";
File file = new File(Environment.getExternalStorageDirectory()
.getPath() + "/AudioRecorder/" + "final.mp3");
try {
file.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
audNames.add(file1);
audNames.add(file2);
Button btn = (Button) findViewById(R.id.clickme);
btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
createCombineRecFile();
}
});
}
public void createCombineRecFile() {
// String combined_file_stored_path = // File path in String to store
// recorded audio
try {
fos = new FileOutputStream(combined_file_stored_path, true);
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
File f = new File(audNames.get(0));
File f1 = new File(audNames.get(1));
Log.i("Record Message", "File Length=========>>>" + f.length()+"------------->"+f1.length());
fileContent = new byte[(int) f.length()];
ins = new FileInputStream(audNames.get(0));
int r = ins.read(fileContent);// Reads the file content as byte
fileContent1 = new byte[(int) f1.length()];
ins1 = new FileInputStream(audNames.get(1));
int r1 = ins1.read(fileContent1);// Reads the file content as byte
// from the list.
Log.i("Record Message", "Number Of Bytes Readed=====>>>" + r);
//fos.write(fileContent1);// Write the byte into the combine file.
byte[] combined = new byte[fileContent.length + fileContent1.length];
for (int i = 0; i < combined.length; ++i)
{
combined[i] = i < fileContent.length ? fileContent[i] : fileContent1[i - fileContent.length];
}
fos.write(combined);
//fos.write(fileContent1);*
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
fos.close();
Log.v("Record Message", "===== Combine File Closed =====");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
I already published an app with this function... try my method using SequenceInputStream, in my app I just merge 17 MP3 files in one and play it using the JNI Library MPG123, but I tested the file using MediaPlayer without problems.
This code isn't the best, but it works...
private void mergeSongs(File mergedFile,File...mp3Files){
FileInputStream fisToFinal = null;
FileOutputStream fos = null;
try {
fos = new FileOutputStream(mergedFile);
fisToFinal = new FileInputStream(mergedFile);
for(File mp3File:mp3Files){
if(!mp3File.exists())
continue;
FileInputStream fisSong = new FileInputStream(mp3File);
SequenceInputStream sis = new SequenceInputStream(fisToFinal, fisSong);
byte[] buf = new byte[1024];
try {
for (int readNum; (readNum = fisSong.read(buf)) != -1;)
fos.write(buf, 0, readNum);
} finally {
if(fisSong!=null){
fisSong.close();
}
if(sis!=null){
sis.close();
}
}
}
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(fos!=null){
fos.flush();
fos.close();
}
if(fisToFinal!=null){
fisToFinal.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Mp3 files are some frames.
You can concatenate these files by appending the streams to each other if and only if the bit rate and sample rate of your files are same.
If not, the first file plays because it has truly true encoding but the second file can not decode to an true mp3 file.
Suggestion: convert your files with some specific bit rate and sample rate, then use your function.

How to get URL of web-service method in android?

I have to write XML to my SD card for that I want to get input-Stream but to establish this how can I get URL when I call any method from android?
For instance I want to download all login details containing 10,000 records when I call it from android that method is called but how to get URL so that I can establish connection and get Input Stream to write to file...Please help me on this below is my code
public void DownloadFiles(){
try {
URL url = new URL("http://192.168.0.10/INIFARM/fieldbook/webservice1.asmx?wsdl");
URLConnection conexion = url.openConnection();
conexion.connect();
int lenghtOfFile = conexion.getContentLength();
InputStream is = url.openStream();
File testDirectory = new File("/data/data/com.example.androidwebservice/");
if (!testDirectory.exists()) {
testDirectory.mkdir();
}
FileOutputStream fos = new FileOutputStream(testDirectory + "/response.xml");
byte data[] = new byte[1024];
int count = 0;
long total = 0;
int progress = 0;
while ((count = is.read(data)) != -1) {
total += count;
int progress_temp = (int) total * 100 / lenghtOfFile;
if (progress_temp % 10 == 0 && progress != progress_temp) {
progress = progress_temp;
}
fos.write(data, 0, count);
}
is.close();
fos.close();
Log.v(TAG, "File is Downloaded Successfully");
} catch (MalformedURLException 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();
}
}
You mean the URL to call? Your web server admin needs to create a REST API for this and tell you the url so that your app can consume the data by querying this API.

Android Sockets always timeout

I have this class which connects to a server through sockets, for some reason it is always timing out from here and I can't figure out why, I thought at first it had to do with it being with onCreate(), thats why doit() even exists. any help would be appreciated. here is my code...
public class Ads extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ads);
doit();
};
public void doit(){
Socket socket = null;
FileOutputStream fos = null;
DataInputStream dis = null;
BufferedOutputStream buf = null;
DataOutputStream dos = null;
try {
socket = new Socket("192.168.1.106", 4447);
Bundle extras = getIntent().getExtras();
String value = extras.getString("keyName");
dos = new DataOutputStream(
new BufferedOutputStream(socket.getOutputStream()));
dis = new DataInputStream(new BufferedInputStream(
socket.getInputStream()));
//dos.writeChars(value);
int numFiles = dis.readInt();
File sdCard = Environment.getExternalStorageDirectory();
File dir = new File (sdCard.getAbsolutePath() +value);
dir.mkdirs();
if (dir.isDirectory()) {
String[] children = dir.list();
for (int i=0; i<children.length; i++) {
new File(dir, children[i]).delete();
}
}
int n = 0;
int fileLength = 0;
for (int i=0;i<numFiles;i++){
File file = new File(dir, String.valueOf(i)+".png");
Log.d("debug tag","created file "+file);
}
for (int i=0;i<numFiles;i++){
fileLength = dis.readInt();
byte[] temp = new byte[(int) fileLength];
String path = sdCard.getAbsolutePath()+value+"/"+i+".png";
buf = new BufferedOutputStream(new FileOutputStream(path));
while ((fileLength > 0) && (n = dis.read(temp, 0, (int) Math.min(temp.length, fileLength))) != -1) {
buf.write(temp,0,n);
buf.flush();
fileLength -= n;
}
//buf.close();
Log.d("debug tag","the file is "+temp.length+" bytes long");
}
// now read in text files
n = 0;
fileLength = 0;
for (int i=0;i<numFiles;i++){
File file = new File(dir, String.valueOf(i)+".txt");
Log.d("debug tag","created file "+file);
}
for (int i=0;i<numFiles;i++){
fileLength = dis.readInt();
byte[] temp = new byte[(int) fileLength];
String path = sdCard.getAbsolutePath()+value+"/"+i+".txt";
buf = new BufferedOutputStream(new FileOutputStream(path));
while ((fileLength > 0) && (n = dis.read(temp, 0, (int) Math.min(temp.length, fileLength))) != -1) {
buf.write(temp,0,n);
buf.flush();
fileLength -= n;
}
//buf.close();
Log.d("debug tag","the text file is "+temp.length+" bytes long");
}
generateListView(sdCard.getAbsoluteFile()+value+"/");
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally{
if (socket != null){
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (fos != null){
try {
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (dis != null){
try {
dis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (dos != null){
try {
dos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
;
I'm afraid the question lacks some important details (it timeouts when connecting, right?), but my blind guess is that your device is using cellular connection, while 192.168.1.106 is on your WiFi network - IPs in the 192.168.x.x pool are private IP addresses, and obviously you can't connect to any such IP address over Internet.
But there's another serious problem with your code - you're trying to make blocking I/O calls in onCreate() - which is executed in the main thread of the application. You should never do this (actually, as soon as you try it on Android 3.x or higher, you'll get NetworkOnMainThreadException). Network I/O should always happen in another thread, either explicitly, or perhaps using AsyncTask (which runs the background thread for you).
For a good introduction, see this post and Designing for Responsiveness guide.

Categories

Resources