问题
i want to make an application for transfer files using wifi direct, but my send and receiver progress bar won't update
my sender
public void Server () {
new Thread(new Runnable()
{
@Override
public void run() {
// TODO Auto-generated method stub
try {
//receive ip
serverSocket = new ServerSocket(port);
Socket socket = serverSocket.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line = null;
while ((line = in.readLine()) != null) {
ClientIP = line;
}
in.close();
socket.close();
serverSocket.close();
socket = null;
serverSocket = null;
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
//send file
socket = new Socket();
socket.bind(null);
socketAddress = new InetSocketAddress(ClientIP, portal);
socket.connect(socketAddress, SOCKET_TIMEOUT);
FragmentManager fm = getFragmentManager();
md = new MyDialog("Send to " + ClientIP );
md.setRetainInstance(true);
md.setCancelable(true);
md.show(fm, "Sender");
//reset progress bar status
progressBarStatus = 0;
//reset filesize
fileSize = 0;
byte buf[] = new byte[1024];
File myFile = new File (path);
filelength = file.length();
OutputStream os = socket.getOutputStream();
FileInputStream fis = new FileInputStream(myFile);
BufferedInputStream bis = new BufferedInputStream(fis);
while ((len = bis.read(buf)) != -1) {
fileSize+=len;
os.write(buf, 0, len);
os.flush();
//count for progress bar
double d = (double) (fileSize * 100) / filelength;
progressBarStatus = (int) Math.round(d);
progressBarHandler.post(new Runnable() {
public void run() {
md.updateProgress(progressBarStatus);
}
});
}
os.close();
fis.close();
bis.close();
socket.close();
// ok, file is downloaded,
if (progressBarStatus >= 100) {
// sleep 2 seconds, so that you can see the 100%
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
isSent = true;
runOnUiThread(new Runnable() {
public void run() {
if(isSent) {
Toast.makeText(getApplicationContext(), "File Sent", Toast.LENGTH_SHORT).show();
}
}
});
md.dismiss();
}
} catch (IOException e) {
Log.e(TAG, "I/O Exception", e);
} finally {
if (socket != null) {
if (socket.isConnected()) {
try {
socket.close();
} catch (IOException e) {
// Give up
e.printStackTrace();
}
}
}
}
}
}).start();
}
my receiver
public void Client (final String hostAddress) {
socketAddress = new InetSocketAddress(hostAddress, port);
socket = new Socket();
new Thread(new Runnable()
{
@Override
public void run() {
// TODO Auto-generated method stub
try {
//sent ip
socket.bind(null);
socket.connect(socketAddress, SOCKET_TIMEOUT);
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
out.println(messsage);
out.flush();
out.close();
socket.close();
socket = null;
//receive file
socket = new Socket();
serverSocket = new ServerSocket(portal);
socket = serverSocket.accept();
final String name;
final String ext;
String[] tokens = filename.split("\\.(?=[^\\.]+$)");
name = tokens[0];
ext = tokens[1];
final File f = new File(Environment.getExternalStorageDirectory() + "/"
+ getPackageName() + "/" + name + System.currentTimeMillis()
+ "." + ext);
File dirs = new File(f.getParent());
if (!dirs.exists())
dirs.mkdirs();
f.createNewFile();
FragmentManager fm = getFragmentManager();
md = new MyDialog("Receive from " + HostIP);
md.setRetainInstance(true);
md.setCancelable(true);
md.show(fm, "Receiver");
//reset progress bar status
progressBarStatus = 0;
//reset filesize
fileSize = 0;
filelength = f.length();
InputStream is = socket.getInputStream();
FileOutputStream fos = new FileOutputStream(f);
BufferedOutputStream bos = new BufferedOutputStream(fos);
byte buf[] = new byte[1024];
while ((len = is.read(buf)) != -1) {
bos.write(buf, 0, len);
bos.flush();
fileSize+=len;
double d = (double) (fileSize * 100) / filelength;
progressBarStatus = (int) Math.round(d);
progressBarHandler.post(new Runnable() {
public void run() {
md.updateProgress(progressBarStatus);
}
});
}
is.close();
fos.close();
bos.close();
socket.close();
serverSocket.close();
if (progressBarStatus >= 100) {
// sleep 2 seconds, so that you can see the 100%
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
isSent = true;
// close the progress bar dialog
//progressBar.dismiss();
runOnUiThread(new Runnable() {
public void run() {
// some code #3 (that needs to be ran in UI thread)
if(isSent) {
Toast.makeText(getApplicationContext(), "File Received", Toast.LENGTH_SHORT).show();
btn.setEnabled(true);
}
}
});
md.dismiss();
}
} catch (IOException e) {
Log.e(TAG, "IO Exception.", e);
}
}
}).start();
}
and i use dialog fragment because i use API 14+
my dialog class
public class MyDialog extends DialogFragment {
ProgressBar mProgressBar;
String title;
public MyDialog (String title) {
this.title = title;
}
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.popup, container);
mProgressBar = (ProgressBar)view.findViewById(R.id.pb);
getDialog().setTitle(title);
getDialog().setCanceledOnTouchOutside(false);
return view;
}
@Override
public void onDestroyView()
{
if (getDialog() != null && getRetainInstance())
getDialog().setDismissMessage(null);
super.onDestroyView();
}
@Override
public void onCancel(DialogInterface dialog) {
// TODO Auto-generated method stub
super.onCancel(dialog);
Toast.makeText(getActivity().getApplicationContext(), "Connection lost. Retry", Toast.LENGTH_SHORT).show();
getActivity().finish();
}
public void updateProgress(int percent)
{
mProgressBar.setProgress(percent);
}
}
i don't know why my code isn't working, my progress bar won't update and file not send. Anyone can help me? thx before
回答1:
You've got a lot of code, but as long as I know, the receiver should use an AsyncTask, that's how I do it and it works for me. Instead of a thread use an Asynctask and the OnProgressUpdate method of the AsyncTask to update the ProgressDialog in the main thread. For example:
public class getFile extends AsyncTask<Void, String, Void>
{
ProgressDialog pB;
String hostAddress=null;
InetSocketAddress socketAddress;
Socket socket=null;
ServerSocket serverSocket=null;
int port=3001;
int SOCKET_TIMEOUT = 3000;
public getFile(String _hostAddress, Context context)
{
this.pB = new ProgressDialog(context);
this.pB.setTitle(context.getText(R.string.sYourMessageText);
this.pB.setMessage(null);
this.pB.setProgressNumberFormat(null);
this.pB.setProgressPercentFormat(null);
this.pB.setCancelable(false);
Drawable d = getResources().getDrawable(R.drawable.x_greenprogress);
pB.setProgressDrawable(d);
pB.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
hostAddress=_hostAddress;
}
@Override
protected void onPreExecute()
{
this.pB.show();
}
@Override
protected Void doInBackground(Void... params)
{
try {
//sent ip
socketAddress = new InetSocketAddress(this.hostAddress, port);
socket = new Socket();
socket.bind(null);
socket.connect(socketAddress, SOCKET_TIMEOUT);
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
out.println(messsage);
out.flush();
out.close();
socket.close();
socket = null;
//receive file
socket = new Socket();
serverSocket = new ServerSocket(portal);
socket = serverSocket.accept();
final String name;
final String ext;
String[] tokens = filename.split("\\.(?=[^\\.]+$)");
name = tokens[0];
ext = tokens[1];
final File f = new File(Environment.getExternalStorageDirectory() + "/"
+ getPackageName() + "/" + name + System.currentTimeMillis()
+ "." + ext);
File dirs = new File(f.getParent());
if (!dirs.exists())
dirs.mkdirs();
f.createNewFile();
InputStream is = socket.getInputStream();
FileOutputStream fos = new FileOutputStream(f);
BufferedOutputStream bos = new BufferedOutputStream(fos);
byte buf[] = new byte[1024];
while ((len = is.read(buf)) != -1)
{
bos.write(buf, 0, len);
bos.flush();
fileSize+=len;
// to update the progress bar just call:
this.publishProgress("" + (int) ((fileSize * 100) / filelength));
}
is.close();
fos.close();
bos.close();
socket.close();
serverSocket.close();
}
@Override
protected void onProgressUpdate(String... progress)
{
this.pB.setProgress(Integer.parseInt(progress[0]));
}
@Override
protected void onPostExecute(Void result)
{
if (this.pB.isShowing())
this.pB.dismiss();
}
}
EDIT: By the way, why do you connect to the server, send an IP close the connection and wait for the server to connect? Why don't use the first socket to do the file transfer? The connection has already been established.
来源:https://stackoverflow.com/questions/17031618/android-send-file-between-two-phones-using-socket-and-progress-bar