So I looked around a little bit to find a good PDF APIs for android and I've discovered PDFBox. I started to play with this library and mainly I'm looking for manipulating specific pdf form.
Now I am loading the file successfuly from my assets folder, but when I try to call
getAcroForm();
It turns me a null object, Thus I can't get into the fields and start to insert some data.
Here is the code where I load the pdf file, copy it to the sdcard and load it to an PDDocument object:
package com.silverfix.pdfpractice;
import android.content.res.AssetManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDDocumentCatalog;
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
import org.apache.pdfbox.pdmodel.interactive.form.PDFieldTreeNode;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
public class MainActivity extends AppCompatActivity{
private final String FORM_NAME = "dgc.pdf";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
AssetManager assetManager = getAssets();
File file = createFileFromInputStream(assetManager.open(FORM_NAME));
PDDocument form = PDDocument.load(file);
PDDocumentCatalog catalog = form.getDocumentCatalog();
catalog.getPages().getCount();
Toast.makeText(this, "Loaded! " + catalog.getPages().getCount(), Toast.LENGTH_LONG).show();
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(this, "Loading has failed", Toast.LENGTH_LONG).show();
}
}
private File createFileFromInputStream(InputStream inputStream) {
try{
OutputStream outputStream = new FileOutputStream("/sdcard/PDFPractice/" + FORM_NAME);
byte buffer[] = new byte[1024];
int length = 0;
while((length=inputStream.read(buffer)) > 0) {
outputStream.write(buffer,0,length);
}
outputStream.close();
inputStream.close();
File result = new File("/sdcard/PDFPractice/" + FORM_NAME);
return result;
}catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
How can I manipulate a pdf file without acroform? Or, can I add an somesort of acroform to this pdf file by myself?
Ok so I finally solved this problem. I downloaded Foxit PhantomPDF and it turns out you can define text fields and align them for your needs. I don't know if there is another software that does that but this one did the job for me
Related
I am trying to use FileWrite to write sensor data of the phone. But I could the get the basic generating new FileWriter working. It seems to return null. Here is the code, basically it tries to create a writer when a button is clicked then just write a few lines of 'hi'. But the program catches the exception at writer = new FileWriter(destPath, true); and Writer unsuccess. is toasted. Any idea why this error happens?
package com.example.jiajunyang.bowdetection;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
public class MainActivity extends AppCompatActivity implements SensorEventListener
{
private static final String destPath = "mySensorData.txt";
FileWriter writer;
// Used to load the 'native-lib' library on application startup.
static {
System.loadLibrary("native-lib");
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
File sdCardFile = new File(Environment.getExternalStorageDirectory() + " \filename.txt");
Log.d("TAG", sdCardFile.getPath());
}
public void onStartClick(View view) {
try {
writer = new FileWriter(destPath, true);
Toast.makeText(getApplicationContext(), "Start writer. ",
Toast.LENGTH_SHORT).show();
writer.write("hi \n");
writer.write("hi \n");
writer.write("hi \n");
writer.flush();
writer.close();
} catch (IOException e) {
Toast.makeText(getApplicationContext(), "Writer unsuccess. ",
Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
}
I develop Mobile Applications with Java.
Some Java APIs just don't work with Android. Are you sure FileWriter does?
Also, the way you define your destination path seems a little bit odd to me.
Here is an Android code example:
String filename = "myfile";
String string = "Hello world!";
FileOutputStream outputStream;
try {
outputStream = openFileOutput(filename, Context.MODE_PRIVATE);
outputStream.write(string.getBytes());
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
You can find more details here.
I am trying to read a file as inputstream to fill in the file with additional data. This data is then supposed to be sent over to a second activity which unwraps the data and displays it on the screen. this is my code
package com.example.daniel.finalproject;
import android.content.Intent;
import android.content.res.AssetManager;
import android.net.Uri;
import android.renderscript.ScriptGroup;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import com.google.android.gms.appindexing.Action;
import com.google.android.gms.appindexing.AppIndex;
import com.google.android.gms.appindexing.Thing;
import com.google.android.gms.common.api.GoogleApiClient;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
public class Secondactivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.secondactivity);
}
public void Proceed(View view) {
AssetManager am = getAssets();
InputStream is = am.open("madlibsimple.txt");
Story story = new Story(is);
EditText editText = (EditText)findViewById(R.id.word);
String text;
story.toString();
while (!story.isFilledIn()) {
story.read(is);
story.getNextPlaceholder();
text = editText.getText().toString();
story.fillInPlaceholder(text);
}
Intent intent = new Intent(this, Thirdactivity.class).putExtra("story",story);
startActivity(intent);
}
}
However this line: InputStream is = am.open("madlibsimple.txt");
returns the error. madlibsimple.txt is in the assetsfolder, but I
don't know what goes wrong. Any help would be much appreciated.
open(String file) can throw an error (i expect IOException) that you have to catch with an
try {
AssetManager am = getAssets();
InputStream is = am.open("madlibsimple.txt");
Story story = new Story(is);
EditText editText = (EditText)findViewById(R.id.word);
String text;
story.toString();
while (!story.isFilledIn()) {
story.read(is);
story.getNextPlaceholder();
text = editText.getText().toString();
story.fillInPlaceholder(text);
}
Intent intent = new Intent(this, Thirdactivity.class).putExtra("story",story);
startActivity(intent);
} catch (Exception e) {
e.printStacktrace();
}
statement.
This whole topic is not about what goes wrong, but what COULD go wrong
For more information on the topic of exceptions and errorhandling you can click here
This question already has answers here:
Java multiple file transfer over socket
(3 answers)
Closed 7 years ago.
I'm developing an application and I want to transfer files from a computer to a phone using sockets. I'm able to transfer one file but when I want to transfer multiple files, they pile up. Here's how the program works:
I get a screenshot from computer using Robot.
I save it as Send.jpg.
I send the image. Let's say for example its size is 1 MB.
I receive the image on phone.
I display it in an ImageView.
And loop through these steps again until the user closes the activity on phone.
But the result is this :
I get the first screenshot (Send.jpg: 1 MB) send it and receive it on phone. Get the second one (Send.jpg: 2 MB) send it and receive it on phone. and the third one and etc...
It never gets displayed on phone. And when I check the phone storage using explorer, I see one image - its size is the size of the first image + the second + the third ...
I guess my problem is i have to stop the InputStream, please help.
Code :
Server :
package application;
import java.awt.AWTException;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import javax.imageio.ImageIO;
public class ScreenCapture {
Socket socket;
OutputStream os;
Robot robot;
PrintStream ps;
public ScreenCapture() throws IOException, AWTException {
// TODO Auto-generated constructor stub
socket = SocketWrapper.getSocket();
os = socket.getOutputStream();
robot = new Robot();
ps = new PrintStream(socket.getOutputStream());
new Record().start();
}
private class Record extends Thread{
#Override
public void run() {
while(true){
int count;
Rectangle rect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
BufferedImage img = robot.createScreenCapture(rect);
try {
ImageIO.write(img, "jpg", new File("/Users/Tomahawk/Documents/MovieMaker/send.jpg"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
FileInputStream fis;
try {
File f = new File("/Users/Tomahawk/Documents/MovieMaker/send.jpg");
fis = new FileInputStream(f);
BufferedInputStream bis = new BufferedInputStream(fis);
byte[] byteArray = new byte[(int) f.length()];
long filesize = f.length();
while((count = bis.read(byteArray)) > 0){
os.write(byteArray,0,count);
}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
System.out.println("Sent File");
}
}
}
}
Client (Phone) :
package com.pcontrol.tomahawk.pcontrol;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ImageView;
import android.widget.Toast;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ScreenCapture extends Activity {
Socket socket;
InputStream is;
OutputStream os;
Scanner scanner;
ImageView screenCap;
long filesize = 0;
int i=0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_screen_capture);
socket = SocketWrapper.getSocket();
try {
is = socket.getInputStream();
scanner = new Scanner(is);
} catch (IOException e) {
e.printStackTrace();
}
screenCap = (ImageView) findViewById(R.id.screenCap);
new ReceiveFiles().execute();
}
private class ReceiveFiles extends AsyncTask<Void,Void,Void> {
#Override
protected Void doInBackground(Void... params) {
try {
os = new FileOutputStream("/sdcard/"+i+".jpg");
copy(is, os);
publishProgress();
} catch (IOException e) {
e.printStackTrace();
}
i++;
return null;
}
#Override
protected void onProgressUpdate(Void... values) {
Bitmap bmp = BitmapFactory.decodeFile("/sdcard/"+i+".jpg");
screenCap.setImageBitmap(bmp);
}
}
static void copy(InputStream in, OutputStream out) throws IOException {
byte[] buf = new byte[60000];
int len = 0;
while ((len = in.read(buf)) != -1) {
out.write(buf, 0, len);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_screen_capture, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
You're not telling the receiver where one file ends and the next one starts.
You could add a basic framing protocol, for example one where you first send the size of the file and then the data. That way the receiver can count the bytes it reads and knows when to close the current file and open another.
Alternatively you could use separate sockets to send each file, but it looks like that would require major changes to your architecture.
Hey Im making a new project which requires you to download some files from my Dropbox. I added a new class called DownloadFile which has the code to download a file. For some reason the app crashes when I click download. Thanks.
Heres the DownloadFile:
package com.Matt7262.download.app;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
//Chat bot library
import org.alicebot.ab.Chat;
import org.alicebot.ab.Bot;
import android.view.View;
import android.widget.Button;
import android.os.Environment;
import android.widget.TextView;
import android.widget.Toast;
import java.io.InputStream;
import java.net.URL;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import android.widget.ProgressBar;
import java.net.URL;
import java.net.URLConnection;
import android.app.Activity;
import android.app.ProgressDialog;
import android.os.Environment;
import android.view.View.OnClickListener;
public class DownloadFile extends ActionBarActivity{
public void updateProgress(int currentSize, int totalSize)
{
Toast.makeText(getApplicationContext(), "Loading Files...",
Toast.LENGTH_SHORT).show();
}
public void Download()
{
try {
//set the download URL, a url that points to a file on the internet
//this is the file to be downloaded
URL url = new URL("https://dl.dropboxusercontent.com/shz/9cyfz0b45mj6szr/7pBuupNz3N/xecta?token_hash=AAEs9cDFswt98D1IhLnab4dHwhwh5z2Lmhq_N6H-2M0LWg&top_level_offset=6");
//create the new connection
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
//set up some things on the connection
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(true);
//and connect!
urlConnection.connect();
//set the path where we want to save the file
//in this case, going to save it on the root directory of the
//sd card.
File SDCardRoot = Environment.getExternalStorageDirectory();
//create a new file, specifying the path, and the filename
//which we want to save the file as.
File file = new File(SDCardRoot,"hello.zip");
//this will be used to write the downloaded data into the file we created
FileOutputStream fileOutput = new FileOutputStream(file);
//this will be used in reading the data from the internet
InputStream inputStream = urlConnection.getInputStream();
//this is the total size of the file
int totalSize = urlConnection.getContentLength();
//variable to store total downloaded bytes
int downloadedSize = 0;
//create a buffer...
byte[] buffer = new byte[1024];
int bufferLength = 0; //used to store a temporary size of the buffer
//now, read through the input buffer and write the contents to the file
while ( (bufferLength = inputStream.read(buffer)) > 0 ) {
//add the data in the buffer to the file in the file output stream (the file on the sd card
fileOutput.write(buffer, 0, bufferLength);
//add up the size so we know how much is downloaded
downloadedSize += bufferLength;
//this is where you would do something to report the prgress, like this maybe
updateProgress(downloadedSize, totalSize);
}
//close the output stream when done
fileOutput.close();
//catch some possible errors...
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
MainActivity:
package com.Matt7262.download.app;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
//Chat bot library
import org.alicebot.ab.Chat;
import org.alicebot.ab.Bot;
import android.view.View;
import android.widget.Button;
import android.os.Environment;
import android.widget.TextView;
import android.widget.Toast;
import android.os.AsyncTask;
public class MainActivity extends ActionBarActivity {
TextView input;
String dPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Download";
private DownloadFile df;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
//EditText mEdit = (EditText)findViewById(R.id.editText1);
public void buttonOnClick(View v)
{
input = (TextView) findViewById(R.id.editText1);
String dbPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Download/Ab";
Button button=(Button) v;
//Creating bot
String botname="xecta";
String path= dbPath;
Bot xecta = new Bot(botname, path);
Chat chatSession = new Chat(xecta);
String request = input.getText().toString();
String response = chatSession.multisentenceRespond(request);
((Button) v).setText(response);
}
public void onClickDownload(View view)
{
df.Download();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/*public void updateProgress(int currentSize, int totalSize)
{
Toast.makeText(getApplicationContext(), "Retrieving Files...",
Toast.LENGTH_SHORT).show();
}/*
/*public void Download()
{
try {
//set the download URL, a url that points to a file on the internet
//this is the file to be downloaded
URL url = new URL("https://dl.dropboxusercontent.com/shz/9cyfz0b45mj6szr/7pBuupNz3N/xecta?token_hash=AAEs9cDFswt98D1IhLnab4dHwhwh5z2Lmhq_N6H-2M0LWg&top_level_offset=6");
//create the new connection
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
//set up some things on the connection
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(true);
//and connect!
urlConnection.connect();
//set the path where we want to save the file
//in this case, going to save it on the root directory of the
//sd card.
File SDCardRoot = Environment.getExternalStorageDirectory();
//create a new file, specifying the path, and the filename
//which we want to save the file as.
File file = new File(SDCardRoot,"hello.zip");
//this will be used to write the downloaded data into the file we created
FileOutputStream fileOutput = new FileOutputStream(file);
//this will be used in reading the data from the internet
InputStream inputStream = urlConnection.getInputStream();
//this is the total size of the file
int totalSize = urlConnection.getContentLength();
//variable to store total downloaded bytes
int downloadedSize = 0;
//create a buffer...
byte[] buffer = new byte[1024];
int bufferLength = 0; //used to store a temporary size of the buffer
//now, read through the input buffer and write the contents to the file
while ( (bufferLength = inputStream.read(buffer)) > 0 ) {
//add the data in the buffer to the file in the file output stream (the file on the sd card
fileOutput.write(buffer, 0, bufferLength);
//add up the size so we know how much is downloaded
downloadedSize += bufferLength;
//this is where you would do something to report the prgress, like this maybe
updateProgress(downloadedSize, totalSize);
}
//close the output stream when done
fileOutput.close();
//catch some possible errors...
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}*/
}
I think this is all I got out of the logcat:
logcat
You are declaring DownloadFile object but not initializing it.
private DownloadFile df;
df.Download(); // Throws NPE
Don't forget to initialize it.
private DownloadFile df = new DownloadFile();
df.Download();
EDIT:
Now you initialised the object and avoided NPE but this time you are getting a NetworkOnMainThreadException. After Honeycomb version, Android does not allow you to do network operations on main thread. You can use an AsyncTask to overcome this.
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import java.io.FileOutputStream;
import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import com.itextpdf.text.Document;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfWriter;
public class MainActivity extends Activity {
private static String FILE = "/HelloWorld.pdf";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
</i>
try {
Document document = new Document();
boolean mExternalStorageAvailable = true;
boolean mExternalStorageWriteable = false;
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
// We can read and write the media
mExternalStorageAvailable = mExternalStorageWriteable = true;
} else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
// We can only read the media
mExternalStorageAvailable = true;
mExternalStorageWriteable = false;
} else {
// Something else is wrong. It may be one of many other states, but all we need
// to know is we can neither read nor write
mExternalStorageAvailable = mExternalStorageWriteable = false;
}
String file = null;
if(mExternalStorageWriteable) {
file = Environment.getExternalStorageDirectory().getPath() + FILE;
}
PdfWriter.getInstance(document,new FileOutputStream(file));
document.open();
Paragraph p = new Paragraph("Hello iText World!");
document.add(p);
document.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
I'm trying to generate one more for another set of data and generated file has size 0kb, and whene opened shows message "Adobe Reader could not open "List.pdf" and type or beacuse the file has been damaged".
iText needs a License key. Check you logcat for the exception. Go onto their site to get a license key and to see how to implement it.