העלה קבצים עם Cloud Storage באנדרואיד

Cloud Storage for Firebase מאפשר לך להעלות במהירות ובקלות קבצים ל- Cloud Storage שסופק ומנוהל על ידי Firebase.

העלה קבצים

כדי להעלות קובץ ל-Cloud Storage, תחילה עליך ליצור הפניה לנתיב המלא של הקובץ, כולל שם הקובץ.

Kotlin+KTX

// Create a storage reference from our app
val storageRef = storage.reference

// Create a reference to "mountains.jpg"
val mountainsRef = storageRef.child("mountains.jpg")

// Create a reference to 'images/mountains.jpg'
val mountainImagesRef = storageRef.child("images/mountains.jpg")

// While the file names are the same, the references point to different files
mountainsRef.name == mountainImagesRef.name // true
mountainsRef.path == mountainImagesRef.path // false

Java

// Create a storage reference from our app
StorageReference storageRef = storage.getReference();

// Create a reference to "mountains.jpg"
StorageReference mountainsRef = storageRef.child("mountains.jpg");

// Create a reference to 'images/mountains.jpg'
StorageReference mountainImagesRef = storageRef.child("images/mountains.jpg");

// While the file names are the same, the references point to different files
mountainsRef.getName().equals(mountainImagesRef.getName());    // true
mountainsRef.getPath().equals(mountainImagesRef.getPath());    // false

לאחר שיצרת הפניה מתאימה, אתה קורא לשיטת putBytes() , putFile() או putStream() כדי להעלות את הקובץ ל-Cloud Storage.

אינך יכול להעלות נתונים עם הפניה לשורש של דלי ה-Cloud Storage שלך. ההפניה שלך חייבת להפנות לכתובת אתר בת.

העלה מנתונים בזיכרון

שיטת putBytes() היא הדרך הפשוטה ביותר להעלות קובץ ל-Cloud Storage. putBytes() לוקח byte[] ומחזיר UploadTask שאתה יכול להשתמש בו כדי לנהל ולנטר את מצב ההעלאה.

Kotlin+KTX

// Get the data from an ImageView as bytes
imageView.isDrawingCacheEnabled = true
imageView.buildDrawingCache()
val bitmap = (imageView.drawable as BitmapDrawable).bitmap
val baos = ByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos)
val data = baos.toByteArray()

var uploadTask = mountainsRef.putBytes(data)
uploadTask.addOnFailureListener {
    // Handle unsuccessful uploads
}.addOnSuccessListener { taskSnapshot ->
    // taskSnapshot.metadata contains file metadata such as size, content-type, etc.
    // ...
}

Java

// Get the data from an ImageView as bytes
imageView.setDrawingCacheEnabled(true);
imageView.buildDrawingCache();
Bitmap bitmap = ((BitmapDrawable) imageView.getDrawable()).getBitmap();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] data = baos.toByteArray();

UploadTask uploadTask = mountainsRef.putBytes(data);
uploadTask.addOnFailureListener(new OnFailureListener() {
    @Override
    public void onFailure(@NonNull Exception exception) {
        // Handle unsuccessful uploads
    }
}).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
    @Override
    public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
        // taskSnapshot.getMetadata() contains file metadata such as size, content-type, etc.
        // ...
    }
});

מכיוון ש- putBytes() מקבל byte[] , זה דורש מהאפליקציה שלך להחזיק את כל התוכן של קובץ בזיכרון בבת אחת. שקול להשתמש putStream() או putFile() כדי להשתמש בפחות זיכרון.

העלה מזרם

שיטת putStream() היא הדרך המגוונת ביותר להעלות קובץ ל-Cloud Storage. putStream() לוקח InputStream ומחזיר UploadTask שאתה יכול להשתמש בו כדי לנהל ולנטר את מצב ההעלאה.

Kotlin+KTX

val stream = FileInputStream(File("path/to/images/rivers.jpg"))

uploadTask = mountainsRef.putStream(stream)
uploadTask.addOnFailureListener {
    // Handle unsuccessful uploads
}.addOnSuccessListener { taskSnapshot ->
    // taskSnapshot.metadata contains file metadata such as size, content-type, etc.
    // ...
}

Java

InputStream stream = new FileInputStream(new File("path/to/images/rivers.jpg"));

uploadTask = mountainsRef.putStream(stream);
uploadTask.addOnFailureListener(new OnFailureListener() {
    @Override
    public void onFailure(@NonNull Exception exception) {
        // Handle unsuccessful uploads
    }
}).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
    @Override
    public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
        // taskSnapshot.getMetadata() contains file metadata such as size, content-type, etc.
        // ...
    }
});

העלה מקובץ מקומי

ניתן להעלות קבצים מקומיים למכשיר, כגון תמונות וסרטונים מהמצלמה, בשיטת putFile() . putFile() לוקח File ומחזיר UploadTask שבו אתה יכול להשתמש כדי לנהל ולנטר את מצב ההעלאה.

Kotlin+KTX

var file = Uri.fromFile(File("path/to/images/rivers.jpg"))
val riversRef = storageRef.child("images/${file.lastPathSegment}")
uploadTask = riversRef.putFile(file)

// Register observers to listen for when the download is done or if it fails
uploadTask.addOnFailureListener {
    // Handle unsuccessful uploads
}.addOnSuccessListener { taskSnapshot ->
    // taskSnapshot.metadata contains file metadata such as size, content-type, etc.
    // ...
}

Java

Uri file = Uri.fromFile(new File("path/to/images/rivers.jpg"));
StorageReference riversRef = storageRef.child("images/"+file.getLastPathSegment());
uploadTask = riversRef.putFile(file);

// Register observers to listen for when the download is done or if it fails
uploadTask.addOnFailureListener(new OnFailureListener() {
    @Override
    public void onFailure(@NonNull Exception exception) {
        // Handle unsuccessful uploads
    }
}).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
    @Override
    public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
        // taskSnapshot.getMetadata() contains file metadata such as size, content-type, etc.
        // ...
    }
});

קבל כתובת אתר להורדה

לאחר העלאת קובץ, אתה יכול לקבל כתובת URL להורדת הקובץ על ידי קריאה לשיטת getDownloadUrl() ב- StorageReference :

Kotlin+KTX

val ref = storageRef.child("images/mountains.jpg")
uploadTask = ref.putFile(file)

val urlTask = uploadTask.continueWithTask { task ->
    if (!task.isSuccessful) {
        task.exception?.let {
            throw it
        }
    }
    ref.downloadUrl
}.addOnCompleteListener { task ->
    if (task.isSuccessful) {
        val downloadUri = task.result
    } else {
        // Handle failures
        // ...
    }
}

Java

final StorageReference ref = storageRef.child("images/mountains.jpg");
uploadTask = ref.putFile(file);

Task<Uri> urlTask = uploadTask.continueWithTask(new Continuation<UploadTask.TaskSnapshot, Task<Uri>>() {
    @Override
    public Task<Uri> then(@NonNull Task<UploadTask.TaskSnapshot> task) throws Exception {
        if (!task.isSuccessful()) {
            throw task.getException();
        }

        // Continue with the task to get the download URL
        return ref.getDownloadUrl();
    }
}).addOnCompleteListener(new OnCompleteListener<Uri>() {
    @Override
    public void onComplete(@NonNull Task<Uri> task) {
        if (task.isSuccessful()) {
            Uri downloadUri = task.getResult();
        } else {
            // Handle failures
            // ...
        }
    }
});

הוסף מטא נתונים של קובץ

אתה יכול גם לכלול מטא נתונים בעת העלאת קבצים. מטא נתונים זה מכיל מאפייני מטא נתונים טיפוסיים של קבצים כגון name , size ו- contentType (המכונה בדרך כלל סוג MIME). שיטת putFile() מסיקה אוטומטית את סוג MIME מסיומת File , אך אתה יכול לעקוף את הסוג שזוהה אוטומטית על ידי ציון contentType במטא נתונים. אם אינכם מספקים contentType ו-Cloud Storage לא יכול להסיק ברירת מחדל מסיומת הקובץ, Cloud Storage משתמש application/octet-stream . עיין בסעיף השתמש במטא נתונים של קבצים למידע נוסף על מטא נתונים של קבצים.

Kotlin+KTX

// Create file metadata including the content type
var metadata = storageMetadata {
    contentType = "image/jpg"
}

// Upload the file and metadata
uploadTask = storageRef.child("images/mountains.jpg").putFile(file, metadata)

Java

// Create file metadata including the content type
StorageMetadata metadata = new StorageMetadata.Builder()
        .setContentType("image/jpg")
        .build();

// Upload the file and metadata
uploadTask = storageRef.child("images/mountains.jpg").putFile(file, metadata);

נהל העלאות

בנוסף להתחלת העלאות, אתה יכול להשהות, להמשיך ולבטל העלאות באמצעות השיטות pause() , resume() ו- cancel() . אירועי השהייה וחידוש מעוררים שינויים במצב pause progress בהתאמה. ביטול העלאה גורם לכשל בהעלאה עם שגיאה המציינת שההעלאה בוטלה.

Kotlin+KTX

uploadTask = storageRef.child("images/mountains.jpg").putFile(file)

// Pause the upload
uploadTask.pause()

// Resume the upload
uploadTask.resume()

// Cancel the upload
uploadTask.cancel()

Java

uploadTask = storageRef.child("images/mountains.jpg").putFile(file);

// Pause the upload
uploadTask.pause();

// Resume the upload
uploadTask.resume();

// Cancel the upload
uploadTask.cancel();

עקוב אחר התקדמות ההעלאה

אתה יכול להוסיף מאזינים כדי להתמודד עם הצלחה, כישלון, התקדמות או הפסקות במשימת ההעלאה שלך:

סוג מאזין שימוש אופייני
OnProgressListener מאזין זה נקרא מעת לעת עם העברת נתונים וניתן להשתמש בו כדי לאכלס מחוון העלאה/הורדה.
OnPausedListener מאזין זה נקרא בכל פעם שהמשימה מושהית.
OnSuccessListener מאזין זה נקרא כאשר המשימה הושלמה בהצלחה.
OnFailureListener מאזין זה נקרא בכל פעם שההעלאה נכשלה. זה יכול לקרות עקב פסק זמן ברשת, כשלי הרשאה או אם תבטל את המשימה.

OnFailureListener נקרא עם מופע Exception . מאזינים אחרים נקראים עם אובייקט UploadTask.TaskSnapshot . אובייקט זה הוא תצוגה בלתי ניתנת לשינוי של המשימה בזמן התרחשות האירוע. UploadTask.TaskSnapshot מכיל את המאפיינים הבאים:

תכונה סוּג תיאור
getDownloadUrl String כתובת URL שניתן להשתמש בה כדי להוריד את האובייקט. זוהי כתובת אתר ציבורית שלא ניתן לנחש אותה ניתן לשתף עם לקוחות אחרים. ערך זה מאוכלס לאחר השלמת ההעלאה.
getError Exception אם המשימה נכשלה, הסיבה לכך תהיה חריגה.
getBytesTransferred long המספר הכולל של בתים שהועברו כשצולמה תמונת מצב זו.
getTotalByteCount long המספר הכולל של בתים שצפוי להעלות.
getUploadSessionUri String URI שניתן להשתמש בו כדי להמשיך במשימה זו באמצעות קריאה נוספת ל-putFile.
getMetadata StorageMetadata לפני שהעלאה מסתיימת, אלו המטא נתונים הנשלחים לשרת. לאחר סיום ההעלאה, אלו המטא נתונים המוחזרים על ידי השרת.
getTask UploadTask המשימה שיצרה תמונת מצב זו. השתמש במשימה זו כדי לבטל, להשהות או לחדש את ההעלאה.
getStorage StorageReference StorageReference המשמש ליצירת ה- UploadTask .

מאזיני אירועי UploadTask מספקים דרך פשוטה ועוצמתית לנטר אירועי העלאה.

Kotlin+KTX

// Observe state change events such as progress, pause, and resume
// You'll need to import com.google.firebase.storage.component1 and
// com.google.firebase.storage.component2
uploadTask.addOnProgressListener { (bytesTransferred, totalByteCount) ->
    val progress = (100.0 * bytesTransferred) / totalByteCount
    Log.d(TAG, "Upload is $progress% done")
}.addOnPausedListener {
    Log.d(TAG, "Upload is paused")
}

Java

// Observe state change events such as progress, pause, and resume
uploadTask.addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
    @Override
    public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
        double progress = (100.0 * taskSnapshot.getBytesTransferred()) / taskSnapshot.getTotalByteCount();
        Log.d(TAG, "Upload is " + progress + "% done");
    }
}).addOnPausedListener(new OnPausedListener<UploadTask.TaskSnapshot>() {
    @Override
    public void onPaused(UploadTask.TaskSnapshot taskSnapshot) {
        Log.d(TAG, "Upload is paused");
    }
});

טיפול בשינויים במחזור החיים של פעילות

העלאות נמשכות ברקע גם לאחר שינויים במחזור החיים של הפעילות (כגון הצגת דו-שיח או סיבוב המסך). כל המאזינים שצירפת יישארו צמודים גם הם. זה עלול לגרום לתוצאות בלתי צפויות אם הם יקראו לאחר הפסקת הפעילות.

אתה יכול לפתור בעיה זו על ידי הרשמה למאזינים שלך עם היקף פעילות כדי לבטל אוטומטית את הרישום שלהם כשהפעילות נפסקת. לאחר מכן, השתמש בשיטת getActiveUploadTasks כאשר הפעילות מתחילה מחדש כדי להשיג משימות העלאה שעדיין פועלות או שהושלמו לאחרונה.

הדוגמה להלן מדגימה זאת ומראה גם כיצד להתמיד בנתיב ההתייחסות לאחסון בשימוש.

Kotlin+KTX

override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState)

    // If there's an upload in progress, save the reference so you can query it later
    outState.putString("reference", storageRef.toString())
}

override fun onRestoreInstanceState(savedInstanceState: Bundle) {
    super.onRestoreInstanceState(savedInstanceState)

    // If there was an upload in progress, get its reference and create a new StorageReference
    val stringRef = savedInstanceState.getString("reference") ?: return

    storageRef = Firebase.storage.getReferenceFromUrl(stringRef)

    // Find all UploadTasks under this StorageReference (in this example, there should be one)

    val tasks = storageRef.activeUploadTasks

    if (tasks.size > 0) {
        // Get the task monitoring the upload
        val task = tasks[0]

        // Add new listeners to the task using an Activity scope
        task.addOnSuccessListener(this) {
            // Success!
            // ...
        }
    }
}

Java

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);

    // If there's an upload in progress, save the reference so you can query it later
    if (mStorageRef != null) {
        outState.putString("reference", mStorageRef.toString());
    }
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);

    // If there was an upload in progress, get its reference and create a new StorageReference
    final String stringRef = savedInstanceState.getString("reference");
    if (stringRef == null) {
        return;
    }
    mStorageRef = FirebaseStorage.getInstance().getReferenceFromUrl(stringRef);

    // Find all UploadTasks under this StorageReference (in this example, there should be one)
    List<UploadTask> tasks = mStorageRef.getActiveUploadTasks();
    if (tasks.size() > 0) {
        // Get the task monitoring the upload
        UploadTask task = tasks.get(0);

        // Add new listeners to the task using an Activity scope
        task.addOnSuccessListener(this, new OnSuccessListener<UploadTask.TaskSnapshot>() {
            @Override
            public void onSuccess(UploadTask.TaskSnapshot state) {
                // Success!
                // ...
            }
        });
    }
}

getActiveUploadTasks מאחזר את כל משימות ההעלאה הפעילות בנקודת ההפניה המסופקת ומתחתיה, כך שייתכן שתצטרך לטפל במספר משימות.

המשך העלאות בכל תהליך התחלות מחדש

אם התהליך שלך ייסגר, כל העלאות שמתבצעות יופסקו. עם זאת, תוכל להמשיך להעלות ברגע שהתהליך יתחיל מחדש על ידי חידוש הפעלת ההעלאה עם השרת. זה יכול לחסוך זמן ורוחב פס על ידי אי התחלת ההעלאה מתחילת הקובץ.

כדי לעשות זאת, התחל להעלות באמצעות putFile . ב- StorageTask שנוצר, התקשר getUploadSessionUri ושמור את הערך שנוצר באחסון מתמשך (כגון SharedPreferences).

Kotlin+KTX

uploadTask = storageRef.putFile(localFile)
uploadTask.addOnProgressListener { taskSnapshot ->
    sessionUri = taskSnapshot.uploadSessionUri
    if (sessionUri != null && !saved) {
        saved = true
        // A persisted session has begun with the server.
        // Save this to persistent storage in case the process dies.
    }
}

Java

uploadTask = mStorageRef.putFile(localFile);
uploadTask.addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
    @Override
    public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
        Uri sessionUri = taskSnapshot.getUploadSessionUri();
        if (sessionUri != null && !mSaved) {
            mSaved = true;
            // A persisted session has begun with the server.
            // Save this to persistent storage in case the process dies.
        }
    }
});

לאחר שהתהליך שלך יתחיל מחדש עם העלאה מופרעת, התקשר שוב ל-putFile. אבל הפעם עוברים גם את אורי שניצל.

Kotlin+KTX

// resume the upload task from where it left off when the process died.
// to do this, pass the sessionUri as the last parameter
uploadTask = storageRef.putFile(
    localFile,
    storageMetadata { },
    sessionUri,
)

Java

//resume the upload task from where it left off when the process died.
//to do this, pass the sessionUri as the last parameter
uploadTask = mStorageRef.putFile(localFile,
        new StorageMetadata.Builder().build(), sessionUri);

המפגשים נמשכים שבוע. אם תנסה לחדש הפעלה לאחר שפג תוקפו או אם הייתה בה שגיאה, תקבל התקשרות חוזרת נכשלת. באחריותך לוודא שהקובץ לא השתנה בין העלאות.

טיפול בשגיאות

ישנן מספר סיבות לכך שגיאות עלולות להתרחש בהעלאה, כולל הקובץ המקומי אינו קיים, או שלמשתמש אין הרשאה להעלות את הקובץ הרצוי. תוכל למצוא מידע נוסף על שגיאות בקטע טיפול בשגיאות במסמכים.

דוגמה מלאה

דוגמה מלאה להעלאה עם ניטור התקדמות וטיפול בשגיאות מוצגת להלן:

Kotlin+KTX

// File or Blob
file = Uri.fromFile(File("path/to/mountains.jpg"))

// Create the file metadata
metadata = storageMetadata {
    contentType = "image/jpeg"
}

// Upload file and metadata to the path 'images/mountains.jpg'
uploadTask = storageRef.child("images/${file.lastPathSegment}").putFile(file, metadata)

// Listen for state changes, errors, and completion of the upload.
// You'll need to import com.google.firebase.storage.component1 and
// com.google.firebase.storage.component2
uploadTask.addOnProgressListener { (bytesTransferred, totalByteCount) ->
    val progress = (100.0 * bytesTransferred) / totalByteCount
    Log.d(TAG, "Upload is $progress% done")
}.addOnPausedListener {
    Log.d(TAG, "Upload is paused")
}.addOnFailureListener {
    // Handle unsuccessful uploads
}.addOnSuccessListener {
    // Handle successful uploads on complete
    // ...
}

Java

// File or Blob
file = Uri.fromFile(new File("path/to/mountains.jpg"));

// Create the file metadata
metadata = new StorageMetadata.Builder()
        .setContentType("image/jpeg")
        .build();

// Upload file and metadata to the path 'images/mountains.jpg'
uploadTask = storageRef.child("images/"+file.getLastPathSegment()).putFile(file, metadata);

// Listen for state changes, errors, and completion of the upload.
uploadTask.addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
    @Override
    public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
        double progress = (100.0 * taskSnapshot.getBytesTransferred()) / taskSnapshot.getTotalByteCount();
        Log.d(TAG, "Upload is " + progress + "% done");
    }
}).addOnPausedListener(new OnPausedListener<UploadTask.TaskSnapshot>() {
    @Override
    public void onPaused(UploadTask.TaskSnapshot taskSnapshot) {
        Log.d(TAG, "Upload is paused");
    }
}).addOnFailureListener(new OnFailureListener() {
    @Override
    public void onFailure(@NonNull Exception exception) {
        // Handle unsuccessful uploads
    }
}).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
    @Override
    public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
        // Handle successful uploads on complete
        // ...
    }
});

כעת, לאחר שהעלית קבצים, בואו ללמוד כיצד להוריד אותם מ-Cloud Storage.