Цикл для загрузки изображений в виде списка по одному

Я хочу загружать несколько изображений один за другим , например, как только пользователь нажимает на кнопку «Загрузить все», он должен начинаться с первого изображения, видимого в списке, как только первое изображение будет загружено на сервер, а затем автоматически должно начинаться с секунды для загрузки, но после один или два вторых интервала и одинаковые для всех доступных изображений в списке.

Это мой код, который позволяет загрузить одно изображение:

Код для загрузки одного изображения

// 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.... } 

поэтому я хочу загружать несколько изображений один за другим (в порядке очереди)

Я попытался написать службу, которая будет загружать изображение из общего префикса один за другим: Примечание: i hv hardcoded некоторые из вещей здесь, как изображение, из sdcard, поэтому путь жестко закодирован, имена изображений жестко закодированы, поэтому plz соответствующим образом измените его и попробуйте ниже кода, я тестировал и работал для меня

Ниже код содержит Сервис , Активность [кнопка загрузки, listview], 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 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 { List mList; LayoutInflater mInflater; int mResource; public MyAdapter(Context context, int resource, List 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 { 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 :

      

AndroidManifest

                

Php Script :

  

Примечание. Выше уверенно, где вы создаете этот php-файл на ftp, создайте папку, также называемую upload, где будут загружены все файлы

Если вы хотите скачать полный Исходный код -> Исходный код

  • не забудьте закрыть соединение после того, как вы закончите писать байты conn.close()
  • вам не нужно использовать Runnables / Threads

1) добавьте в свой AsyncTask следующий интерфейс:

  public interface onImageUploadListener{ void onImageUploaded(String status); } 

2) Объявите свой экземпляр как поле classа в вашей AsyncTask (я назвал его слушателем) и добавлю следующий конструктор:

  public UploadFileAsync(onImageUploadListener listener){ this.listener = listener; } 

3) Используйте AsyncTask.THREAD_POOL_EXECUTOR если вы используете API> 11, чтобы ваша задача загрузки не блокировала другие задачи, которые вы могли бы запустить.

4) Пусть ваш class 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); задержку, просто вызовите Thread.sleep(1000); внутри вашего doInBackground() непосредственно перед оператором return .

onImageUploaded() вызов onImageUploaded() будет запускаться каждый раз, AsyncTask заканчивается ваш AsyncTask , и вы можете повторять его снова и снова из этого метода до тех пор, пока вы не закончите загрузку. Вы также можете добавить дополнительные проверки к этому методу, например, проверить коды ошибок, но это зависит от вас.

Надеюсь это поможет. ура

Я бы просто AsyncTask пока не будет загружено больше фото. Что-то вроде

 if (++position < flags.size()) { new UploadFileAsync().execute(String.valueOf(position)); } 

Вы можете сделать это либо в onPostExecute() AsyncTask, либо в вашем режиме statusWhenFinished() . Я не уверен, что вам даже нужен Runnable ...

НТН

Сначала создайте class, например ImageSyncService . Многие компоненты этого classа отсутствуют, поскольку я извлек его из моего текущего проекта, но вы получите обзор. Если что-то неясно, вы можете спросить меня.

 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 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); } 

Надеюсь это поможет 🙂

==== Класс активности От того, с какой загрузки изображения будет запущено ====

 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); } } 

=== Класс интерфейса будет использоваться для обновления флага для каждого изображения после загрузки из classа AsyncTask ===

 public interface ImageStatusUpdater { public void onImageUpload(boolean status, String img_url); } 

=== Класс AsyncTask, из которого будет выполняться фактическая загрузка ===

 import android.os.AsyncTask; public class ImageUploader extends AsyncTask{ 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]); } } 

Это всего лишь своего рода демо-код, объясняющий вам stream, вам нужно написать реальный код, где это необходимо.

Более простой способ загрузки по одному – просто добавить 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 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); } } 

Looper в 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(); } } } 
  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); 
  • Непрокручиваемый ListView внутри ScrollView
  • ListFragment не принимает мой макет
  • Справка относительно события onClick () для элемента пользовательской строки списка ListView
  • Обнаружение прокрутки вверх и прокрутка вниз в ListView
  • Преобразование JSONarray в ArrayList
  • Android: доступ к дочерним представлениям из списка ListView
  • Android. Как работает метод notifyDataSetChanged () и ListViews?
  • Пользовательский getFilter в пользовательском ArrayAdapter в android
  • Программно перейдите к определенной позиции в Android ListView
  • Цвет монитора ListView для Android
  • Просмотр элементов списка изменений при прокрутке андроида?
  • Давайте будем гением компьютера.