我想逐个上传多个图片,就像用户点击上传所有按钮一样,它必须从列表中可见的第一张图片开始,一旦第一张图片上传到服务器然后自动必须开始第二次上传,但是在一到两秒间隔之后,对于列表中的所有可用图像都是相同的。
这是我的代码,允许我上传单张图片: -
上传单张图片的代码
// btnUpload
holder.uploadImageButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Upload
startUpload(position);
}
});
我正在使用以下代码,但其上传/同步所有图片同时出现,我的意思是一起,就像我有 500张图片在列表中,以便将所有500个上传到一起,因此当互联网连接中断时很多时候出现错误,很多时候无法获得上传图片的准确状态!
private SparseBooleanArray flags = new SparseBooleanArray();
// At onClick, set all the flags to indicate that some data needs to be synced
ImageButton buttonUploadAll = (ImageButton) findViewById(R.id.sync_btn);
buttonUploadAll.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
for(int position=0; position<listView.getAdapter().getCount(); position++)
{
flags.put(position, true);
}
// Calling this would ensure a call to getView() on every
// visible child of the listview. That is where we will check if
// the data is to be synced and displayed or not
((BaseAdapter) listView.getAdapter()).notifyDataSetChanged();
}
});
@Override
// In getView of the listview's adapter
public View getView(int position, View convertView, ViewGroup parent) {
// If this item is to be synced
if(flags.get(position)) {
startUpload();
// Mark as synced
flags.put(position, false);
}
// Rest of the method that draws the view....
}
这就是为什么我想逐个上传多张图片(以队列方式)
答案 0 :(得分:6)
我试图编写一个服务,它将逐个从共享的pref上传图像: 注意:我hv硬编码这里的一些东西,如图像来自SD卡,所以路径是硬编码的,图像名称是硬编码的,所以PLZ适当地改变它并尝试下面的代码,我已经测试并为我工作
以下代码包含服务,活动 [上传按钮,列表视图], xmlLayout , php服务在ftp上传图片。
活动:
public class MainActivity extends Activity {
SharedPreferences sharedPref;
SharedPreferences.Editor editor;
ListView listview;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sharedPref = getSharedPreferences("myfiles", MODE_PRIVATE);
editor = sharedPref.edit();
editor.putString("0", "monika_pin.png");
editor.putString("1", "monika_pin1.png");
editor.putString("2", "monika_pin2.png");
editor.commit();
String[] arr = new String[] { "/mnt/sdcard/monika_pin.png",
"/mnt/sdcard/monika_pin1.png", "/mnt/sdcard/monika_pin2.png" };
List<String> list = Arrays.asList(arr);
MyAdapter adapter = new MyAdapter(this, R.layout.listitem_imv, list);
listview = (ListView) findViewById(R.id.listView1);
listview.setAdapter(adapter);
}
class MyAdapter extends ArrayAdapter<String> {
List<String> mList;
LayoutInflater mInflater;
int mResource;
public MyAdapter(Context context, int resource, List<String> objects) {
super(context, resource, objects);
mResource = resource;
mInflater = getLayoutInflater();
mList = objects;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view;
if (convertView == null) {
view = mInflater.inflate(mResource, null);
} else {
view = convertView;
}
ImageView imageView = (ImageView) view
.findViewById(R.id.imageView1);
TextView textView = (TextView) view.findViewById(R.id.textView1);
imageView.setTag(mList.get(position));// tag of imageView == path to
// image
new LoadImage(imageView).execute();
textView.setText(mList.get(position).toString());
return view;
}
}
class LoadImage extends AsyncTask<Object, Void, Bitmap> {
private ImageView imv;
private String path;
public LoadImage(ImageView imv) {
this.imv = imv;
this.path = imv.getTag().toString();
}
@Override
protected Bitmap doInBackground(Object... params) {
Bitmap bitmap = null;
// File file = new File(
// Environment.getExternalStorageDirectory().getAbsolutePath() +
// path);
File file = new File(path);
if (file.exists()) {
bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
}
return bitmap;
}
@Override
protected void onPostExecute(Bitmap result) {
if (!imv.getTag().toString().equals(path)) {
/*
* The path is not same. This means that this image view is
* handled by some other async task. We don't do anything and
* return.
*/
return;
}
if (result != null && imv != null) {
imv.setVisibility(View.VISIBLE);
imv.setImageBitmap(result);
} else {
imv.setVisibility(View.GONE);
}
}
}
public void buttonClick(View view) {
Intent intent = new Intent(this, MyService.class);
startService(intent);
}
}
服务:
public class MyService extends Service {
SharedPreferences sharedPref;
SharedPreferences.Editor editor;
int serverResponseCode = 0;
String upLoadServerUri = null;
private static final String TAG = "com.example.ServiceExample";
@Override
public void onCreate() {
Log.i(TAG, "Service onCreate");
sharedPref = getSharedPreferences("myfiles", MODE_PRIVATE);
/************* Php script path ****************/
upLoadServerUri = "http://myserver/uploadimage.php";
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "Service onStartCommand " + startId);
final int currentId = startId;
Runnable r = new Runnable() {
public void run() {
for (int i = 0; i < 3; i++) {
// long endTime = System.currentTimeMillis() + 10*1000;
// while (System.currentTimeMillis() < endTime) {
synchronized (this) {
try {
uploadFile(sharedPref.getString(i + "", ""));
} catch (Exception e) {
}
}
// }
Log.i(TAG, "Service running " + currentId);
}
stopSelf();
}
};
Thread t = new Thread(r);
t.start();
return Service.START_STICKY;
}
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
Log.i(TAG, "Service onBind");
return null;
}
@Override
public void onDestroy() {
Log.i(TAG, "Service onDestroy");
}
public int uploadFile(String sourceFileUri) {
String fileName = sourceFileUri;
HttpURLConnection conn = null;
DataOutputStream dos = null;
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
int bytesRead, bytesAvailable, bufferSize;
byte[] buffer;
int maxBufferSize = 1 * 1024 * 1024;
// File sourceFile = new
// File(Environment.getExternalStorageDirectory(),sourceFileUri);
File sourceFile = new File(Environment.getExternalStorageDirectory()
.getAbsolutePath() + "/" + fileName);
if (!sourceFile.isFile()) {
return 0;
} else {
try {
// open a URL connection to the Servlet
FileInputStream fileInputStream = new FileInputStream(
sourceFile);
URL url = new URL(upLoadServerUri);
// Open a HTTP connection to the URL
conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true); // Allow Inputs
conn.setDoOutput(true); // Allow Outputs
conn.setUseCaches(false); // Don't use a Cached Copy
conn.setRequestMethod("POST");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("ENCTYPE", "multipart/form-data");
conn.setRequestProperty("Content-Type",
"multipart/form-data;boundary=" + boundary);
conn.setRequestProperty("uploaded_file", fileName);
dos = new DataOutputStream(conn.getOutputStream());
dos.writeBytes(twoHyphens + boundary + lineEnd);
// dos.writeBytes("Content-Disposition: form-data; name="uploaded_file";filename=""+ fileName + """
// + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"uploaded_file\";filename=\""
+ fileName + "\"" + lineEnd);
dos.writeBytes(lineEnd);
// create a buffer of maximum size
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
// read file and write it into form...
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
while (bytesRead > 0) {
dos.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
}
// send multipart form data necesssary after file data...
dos.writeBytes(lineEnd);
dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
// Responses from the server (code and message)
serverResponseCode = conn.getResponseCode();
String serverResponseMessage = conn.getResponseMessage();
Log.i("uploadFile", "HTTP Response is : "
+ serverResponseMessage + ": " + serverResponseCode);
if (serverResponseCode == 200) {
}
// close the streams //
fileInputStream.close();
dos.flush();
dos.close();
} catch (MalformedURLException ex) {
ex.printStackTrace();
Log.e("Upload file to server", "error: " + ex.getMessage(), ex);
} catch (Exception e) {
e.printStackTrace();
Log.e("Upload file to server Exception",
"Exception : " + e.getMessage(), e);
}
return serverResponseCode;
} // End else block
}
}
XmlLayout :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.service.MainActivity" >
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:onClick="buttonClick"
android:text="Button" />
<ListView
android:id="@+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/button1"
android:layout_centerHorizontal="true" >
</ListView>
</RelativeLayout>
<强> AndroidManifest 强>
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.service"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="21" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
>
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".MyService" />
</application>
</manifest>
PhP脚本:
<?php
$file_path = "uploads/";
$file_path = $file_path . basename( $_FILES['uploaded_file']['name']);
if(move_uploaded_file($_FILES['uploaded_file']['tmp_name'], $file_path)) {
echo "success";
} else{
echo "fail";
}
?>
注意:确定在ftp上创建此php文件的位置,创建一个名为upload的文件夹,其中所有文件都将上传
如果您想下载完整的源代码 - &gt; Source Code
答案 1 :(得分:3)
conn.close()
Runnables
/ Threads
1)将以下界面添加到AsyncTask
:
public interface onImageUploadListener{
void onImageUploaded(String status);
}
2)在AsyncTask
(我称之为监听器)中将其实例声明为类字段并添加以下构造函数:
public UploadFileAsync(onImageUploadListener listener){
this.listener = listener;
}
3)如果您使用的是API&gt; 11,请使用AsyncTask.THREAD_POOL_EXECUTOR
,以防止上传任务阻止您可能正在运行的其他任务。
4)让你的Adapter
课程(为了上帝的缘故,首先删除Runnable
部分)实现界面:
public class ImageAdapter extends BaseAdapter implements UploadFileAsync.onImageUploadListener
您需要实施onImageUploaded(String status)
方法:
@Override
public void onImageUploaded(String status){
//here you are getting your server response)
//I use a bit of pseudo-code to describe this condition
if(position < lastPosition){
new UploadFileAsync(this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, String.valueOf(nextPosition));
}else{
//we are done
}}
5)在AsyncTask中,将服务器响应的值分配给某些String,并在onPostExecute()
方法上执行以下操作:
listener.onImageUploaded(yourResponseCode);
6)要强制延迟1秒,只需在返回语句之前的Thread.sleep(1000);
方法中调用doInBackground()
。
每次onImageUploaded()
完成时都会触发AsyncTask
回调,您可以通过此方法反复执行,直到完成上传为止。您还可以为此方法添加更多检查,例如检查错误代码,但这取决于您。
希望这会有所帮助。干杯
答案 2 :(得分:2)
首先在此处创建一个类似ImageSyncService
的类。当我从正在进行的项目中提取它时,这个类的许多组件都丢失了,但是你会得到概述。如果事情不明确,你可以问我。
public class ImageSyncService extends IntentService {
private static final String TAG = "ImageSyncService";
private Image image;
private ImageOpenHelper imageOpenHelper;
private SharedPreferences preferences;
public ImageSyncService() {
super(TAG);
}
@Override
protected void onHandleIntent(Intent intent) {
Logger.d(TAG, "onHandleIntent");
imageOpenHelper = new ImageOpenHelper(getApplicationContext());
preferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
image = (Image) intent.getSerializableExtra(Config.REQUEST_EXTRA_OBJECT);
if(image == null)
return;
if(image.getResourceURI() == null) {
image.setSyncStatus(SyncStatus.SYNCING);
imageOpenHelper.updateImage(image, false);
Response response = MultiPartDataServer.postData(Config.URL_IMAGE_UPLOAD, nameValuePairs, null);
/* on success:
*
* image.setSyncStatus(SyncStatus.SYNCED);
* imageOpenHelper.updateImage(image, false);
*
* */
}
}
在uploadAll
按钮上单击执行以下操作:
ArrayList<Image> images = imageOpenHelper.getUnsyncedImages(SyncStatus.TO_BE_UPLOADED);
Intent imageSyncService = null;
for(Image i: images) {
imageSyncService = new Intent(getApplicationContext(), ImageSyncService.class);
imageSyncService.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
imageSyncService.putExtra(Config.REQUEST_EXTRA_OBJECT, i);
startService(imageSyncService);
}
希望这会有所帮助:)
答案 3 :(得分:1)
我只是将AsyncTask
排队,直到不再上传图片为止。像
if (++position < flags.size()) {
new UploadFileAsync().execute(String.valueOf(position));
}
您可以在AsyncTask的onPostExecute()
或statusWhenFinished()
方法中执行此操作。我不确定你是否还需要Runnable ......
HTH
答案 4 :(得分:1)
====活动类将从中触发图像上传====
import android.app.Activity;
import android.view.View;
import android.view.View.OnClickListener;
public class MActivity extends Activity implements OnClickListener, ImageStatusUpdater{
String img_url[] = new String[3];
@Override
public void onImageUpload(boolean status, String img_url) {
//here you will get the status update with corresponding
//image url or say image name what ever
}
@Override
public void onClick(View v) {
img_url[0] = "img1_url";
img_url[1] = "img2_url";
img_url[2] = "img3_url";
new ImageUploader(this).execute(img_url);
}
}
===从AsyncTask类上传后,接口类将用于更新每个图像的标志===
public interface ImageStatusUpdater {
public void onImageUpload(boolean status, String img_url);
}
===实际上传的AsyncTask类===
import android.os.AsyncTask;
public class ImageUploader extends AsyncTask<String, String, Void>{
ImageStatusUpdater isu;
public ImageUploader(ImageStatusUpdater isu) {
this.isu = isu;
}
@Override
protected Void doInBackground(String... params) {
for (String img_name: params){
//Here you have to write your uploading code
String[] result;
result = new String[1];
result[0] = img_name;
result[1] = "true";
onProgressUpdate(result);
}
return null;
}
@Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
this.isu.onImageUpload(Boolean.getBoolean(values[1]), values[0]);
}
}
这只是一种演示代码,用于解释您的流程,您需要在适当的地方编写实际代码。
答案 5 :(得分:1)
逐个上传的简单方法是,只需在synchronised(mLock){ }
函数中添加doinBackground
块。这使得代码的一部分互相排斥,一次只上传一个图像。它的 QuickFix或解决方法,我不喜欢这种方法来实现这一目标。
// Async Upload
private static final Object mLock = new Object();//have an object to lock, and define out side the async task class
public class UploadFileAsync extends AsyncTask<String, Void, Void> {
String resServer;
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Void doInBackground(String... params) {
// TODO Auto-generated method stub
synchronized(mLock){ //sync block starts
position = Integer.parseInt(params[0]);
int bytesRead, bytesAvailable, bufferSize;
byte[] buffer;
int maxBufferSize = 1 * 1024 * 1024;
int resCode = 0;
String resMessage = "";
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
// File Path
String strSDPath = ImageList.get(position).toString();
// Upload to PHP Script
String strUrlServer = "";
try {
/** Check file on SD Card ***/
File file = new File(strSDPath);
if(!file.exists())
{
resServer = "{\"StatusID\":\"0\",\"Error\":\"Please check path on SD Card\"}";
return null;
}
FileInputStream fileInputStream = new FileInputStream(new File(strSDPath));
URL url = new URL(strUrlServer);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setRequestMethod("POST");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("Content-Type",
"multipart/form-data;boundary=" + boundary);
DataOutputStream outputStream = new DataOutputStream(conn
.getOutputStream());
outputStream.writeBytes(twoHyphens + boundary + lineEnd);
outputStream
.writeBytes("Content-Disposition: form-data; name=\"filUpload\";filename=\""
+ strSDPath + "\"" + lineEnd);
outputStream.writeBytes(lineEnd);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
// Read file
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
while (bytesRead > 0) {
outputStream.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
}
outputStream.writeBytes(lineEnd);
outputStream.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
// Response Code and Message
resCode = conn.getResponseCode();
if(resCode == HttpURLConnection.HTTP_OK)
{
InputStream is = conn.getInputStream();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int read = 0;
while ((read = is.read()) != -1) {
bos.write(read);
}
byte[] result = bos.toByteArray();
bos.close();
resMessage = new String(result);
}
Log.d("resCode=",Integer.toString(resCode));
Log.d("resMessage=",resMessage.toString());
fileInputStream.close();
outputStream.flush();
outputStream.close();
resServer = resMessage.toString();
} catch (Exception ex) {
ex.printStackTrace();
}
}//Sync block ends
return null;
}
protected void onPostExecute(Void unused) {
statusWhenFinish(position,resServer);
}
}
答案 6 :(得分:0)
Looper
中的{p> WorkerThread
。尝试如下 -
public class MyActivity extends Activity{
public static final int LOAD_IMAGE = 1;
public static final MAX_IMAGE_INDEX = 500;
public static final DELAY_TIME = 1*1000; // 1 second
private WorkerThread mWorkerThread;
onCreate(Bundle bundle){
mWorkerThread = new WorkerThread();
mWorkerThread.start();
}
public void onCLick(View pView){
Message message = Message.obtain();
message.what = LOAD_IMAGE;
message.arg1 = 0; // Start from Image index zero;
mWorkerThread.queJob(message, 0);
}
private class WorkerThread{
Looper looper;
Handler handler;
private void init(){
if(!isAlive()){
start();
}
}
public void queJob(Message msg, int delay){
init();
if(handler!=null){
handler.sendMessageDelayed(msg, delay);
}
}
public void run(){
Looper.prepare();
looper = Looper.MyLoop();
handler = new Handler(){
public void handleMessage(Message msg){
if(msg.what==LOAD_IMAGE){
if(msg.agr1<0||msg.arg1>=MAX_IMAGE_INDEX)
return;
inr imageIndex = msg.arg1;
// Create connection here and load image
Message message = Message.obtain();
message.what = LOAD_IMAGE;
if(loadingSuccess){ // Load next image
message.agr1 = msg.arg1 + 1; // increase index to next
}else{ // en que the same failed job
message.arg1 = msg.arg1;
}
queJob(message, DELAY_TIME);
}
}
};
Looper.loop();
}
}
}
答案 7 :(得分:0)
BitmapFactory.Options options = new BitmapFactory.Options();
// down sizing image as it throws OutOfMemory Exception for larger
// images
options.inSampleSize = 8;
Bitmap bitmap = BitmapFactory.decodeFile(filePath, options);
imgView.setImageBitmap(bitmap);