2017-03-03 126 views
1

我有一個包含照片的Firebase存儲。 我正在組織照片的名稱1,2,3等.... 我試圖讓所有的照片dowload網址,所以在未來,我會進入他們到URL的Arraylist和呈現他們在使用Glide的照片庫(這就是爲什麼我只是在尋找URLS)Firebase存儲下載多張照片網址

我正在尋找一種方法,只要onSucsess被調用,onFailure被調用時會繼續給我Urls(因爲有沒有更多的照片)我想循環結束。

我正在嘗試使用Firebase的getDownloadUrl方法,並添加了一個布爾值,當onFailure被調用時會觸發false。 並增加我的photoOrder int從1開始,由此將更改所選照片的​​路徑。

public class Photopackges extends AppCompatActivity { 

public static boolean shouldRun = true; 
public static final String TAG = "debug"; 
public static int photoOrder = 1; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_photopackges); 

    //just normal firebase setup 
    FirebaseStorage storage = FirebaseStorage.getInstance(); 


    // while shouldRun boolean is true keep going , until it will be defined false 
    while (shouldRun == true) { 

      // define my Firebase storage path,which contain one folder called "test" and three photos 1.jpg,2.jpg,3.jpg 
     // the number of the photo is represented in the photoOrder int. 
     String storagePath = "test/" + String.valueOf(photoOrder) + ".jpg"; 
     StorageReference ref = storage.getReference().child(storagePath); 

     try { 

      ref.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() { 
       @Override 
       public void onSuccess(Uri uri) { 

        // trying to define that if the action was successful , keep on going. 
        shouldRun = true; 
        Log.e(TAG, "sucsess! " + uri); 


       } 
      }).addOnFailureListener(new OnFailureListener() { 
       @Override 
       public void onFailure(@NonNull Exception e) { 

        // trying to define that if the action has failed , stop. 
        shouldRun = false; 
        Log.e(TAG, "Fail! " + e); 
       } 
      }); 


     } catch (Exception e) { 
      Log.e(TAG, "Error! " + e); 
      break; 


     } 

     //increment the photoOrder so it will go to the next path. 
     photoOrder++; 
     Log.e(TAG,"value of photoOrder "+photoOrder); 
    } 
} 
} 

日誌 -

Loginfo

我沒有他發送更多的請求之前他得到的答案的一個問題。 我只是需要他停下來時,它得到

StorageException:對象不存在的位置。

我猜必須有一個簡單的方法使用火力讓所有的存儲..

感謝您的幫助!

回答

2

好清單,所以想我能做到,用等待(很多)和notify()後方法。現在

我能得到的ArrayList所有的下載網址我FirebaseStorage照片,其中可以包含未知數量的照片的請注意,這只是因爲我必須在將它們輸入到我的Storge之前重命名它們(1,2,3 ...等)。

對於這個工作,你需要:

  1. 建立一個FirebaseStorage。
    1. 創建一個文件夾(我的稱爲測試)並填充圖像。

我能得到這個logcat的,這正是我想要的 See Log

public static final String TAG = "eyaldebug"; 
public static PathGenerator pathGenerator; 
public static ArrayList<String>photoURLs; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_photopackges); 

    //Initialize the whole process 

    photoURLs = new ArrayList<>(); 

    pathGenerator = new PathGenerator(); 

    new UrlProducer(pathGenerator); 


} 


/** 
* This class contains the GeneratePaths method,which responsible 
* of making new paths. 
* Also we have a simple set - get methods of the booleans. 
*/ 

class PathGenerator { 
    //start photo number 
    int photoNumber = 0; 
    //boolean that indicates if the path has been used already or not. 
    boolean pathIsTaken = false; 
    //our storage path. 
    String path; 

    /** 
    * This method will generate a new path. 
    * while path is taken , wait because we didn't use it yet. 
    * 
    * @param photoNumber 
    */ 

    public synchronized String generatePath(int photoNumber) { 

     while (pathIsTaken) 
     { 
      try {wait();} catch (Exception e) {} 
     } 
     this.photoNumber = photoNumber; 
     path = "test/" + String.valueOf(photoNumber) + ".jpg"; 
     pathIsTaken = true; 
     Log.e("eyaldebug", "path is : " + path); 
     return path; 
    } 

    /** 
    * Simple set method. 
    * @param value 
    */ 

    public synchronized void setPathisSet(boolean value) 
    { 
     this.pathIsTaken = value; 
    } 

    /** 
    * Unfreeze the thread, we call this method after onSucsess. 
    */ 

    public synchronized void unfreeze() 
    { 
     notifyAll(); 
    } 

} 


/** 
* Our URLProducer calls will take the paths,and will 
* send HTTP request to the storage that we'll get a 
* download URL returned. 
* later we'll be using Glide\Picasso to display those images. 
*/ 

class UrlProducer implements Runnable { 

    PathGenerator mPathGenerator; 

    //initialize a String type ArrayList which will contain our URLS. 
    public ArrayList<String>photoURLs = new ArrayList<>(); 

    //constructor that will be called in the activity 
    public UrlProducer(PathGenerator mPathGenerator) { 
     this.mPathGenerator = mPathGenerator; 

     Thread b = new Thread(this, "UrlProducer"); 
     b.start(); 
    } 

    /** 
    * Here we a simple download URL method using FirebaseStorage. 
    * for the documentation for FirebaseStoarge download go to : 
    * 
    * https://firebase.google.com/docs/storage/android/download-files 
    * 
    * IF the task was successful we UNfreeze the threads so it will 
    * keep sending us new URLS. 
    * IF the onFailure was called the stroage is must likely empty and 
    * we should stop trying to get new photos. 
    */ 

    @Override 
    public void run() { 


     int photoNumber =0 ; 

     while (true) { 


      photoNumber ++; 

      try { 
       FirebaseStorage storage = FirebaseStorage.getInstance(); 
       StorageReference ref = storage.getReference(); 


       ref.child(pathGenerator.generatePath(photoNumber)).getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() { 
        @Override 
        public void onSuccess(Uri uri) { 

         Log.e(TAG, "Success! " + uri); 

         //add the URL into the ArrayList 
         photoURLs.add(String.valueOf(uri)); 

         //tell the generate method that the path has been used. 
         pathGenerator.setPathisSet(false); 

         //Unfreeze the thread so it will continue generate new paths. 
         pathGenerator.unfreeze(); 

        } 
       }).addOnFailureListener(new OnFailureListener() { 
        @Override 
        public void onFailure(@NonNull Exception e) { 

         //When onFailure is called shutdown,and output the given ArrayList. 

         Log.e(TAG,"onFailure was called , storage is empty!"); 
         Log.e(TAG,"----------------------------------------"); 
         for(String singleUrl :photoURLs) 
         { 
          Log.e(TAG,""+singleUrl) ; 
         } 
        } 
       }); 


      }catch (Exception e){e.printStackTrace();} 


     } 
    } 

} 
0

嗯,問題是由於電話ref.getDownloadUrl()是異步的。所以當你的第一個onFailure方法被調用時,已經有很多其他的對異步方法的調用,因爲你的循環運行速度更快,並且不會等待前一個調用的響應。

所以我的建議是,你應該將你的URL存儲在firebase RealtimeDatabase中,並獲取這些URL,然後用glide加載它們。

你可以看到文檔,如果你想了解處理的URL https://firebase.google.com/docs/database/android/lists-of-data

+0

好了,感謝您的幫助!我會嘗試使用RealtimeDatabase並將在此處發佈。 –

相關問題