• Recently, I am making the function of saving pictures and videos. Before, I saved them to the SD card directory, but now I save them to the system album. The process is to read an online image, download the image to the local album through the AndroidDownLoadManager download management class, and then refresh the album through the ContentResolver

    .

  • Problems encountered:

  • Request 1. Android 9.0 network adapter, set in the Manifest Android: usesCleartextTraffic = “true” can solve the problem of AndroidP load network.

  • 2. The download progress is not updated. Configure the download permission in the Manifest.

  • 3. The local album does not refresh. Solution: first dynamic request read and write permission, and then call the system database with broadcast notification interface refresh.

  • 4.MainActivity complete code:

  • public class MainActivity extends AppCompatActivity { private TextView tvSaveImage, tvSaveVideo; private boolean flag = true; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Request permission loadPermission(); initView(); initListener(); } / dynamic requests permission to * * * * / private void loadPermission () {PermissionsUtil. RequestCamera (this, aBoolean - > {}); } private void initView() { tvSaveImage = findViewById(R.id.tv_save_image); tvSaveVideo = findViewById(R.id.tv_save_video); } private void initListener() { tvSaveImage.setOnClickListener(v -> { if (false) { Toast.makeText(MainActivity.this, "Images start downloading ", toast.length_short).show(); flag = false; } else {toast.maketext (mainactivity.this, toast.length_short).show(); } //String url = "https://pic.cnblogs.com/avatar/1142647/20170416093225.png"; //String url = "http://ww3.sinaimg.cn/bmiddle/6e91531djw1e8l3c7wo7xj20f00qo755.jpg"; //String url = "https://ae01.alicdn.com/kf/U29ad1424fd024374bf8ba95a61a60d8ai.jpg"; String url = "https://ae01.alicdn.com/kf/Ua227945b506241af975a9b0a16d6df3bA.jpg"; // Save image downLoadImage(url); }); TvSaveVideo. SetOnClickListener (v - > {the if (false) {Toast. MakeText (MainActivity. This "video download start", Toast.LENGTH_SHORT).show(); flag = false; } else {toast.maketext (mainactivity.this, "video is downloading ", toast.length_short).show(); } downLoadVideo("https://www.w3school.com.cn/example/html5/mov_bbb.mp4"); }); } @param path */ private void downLoadImage(String path) {new Thread(() -> new AndroidDownloadManager(MainActivity.this, path) .setListener(new AndroidDownloadManagerListener() { @Override public void onPrepare() { Log.d("downloadVideo", "onPrepare"); } @override public void onSuccess(String path) {toast.maketext (mainactivity.this," Toast.LENGTH_SHORT).show(); FileUtils.saveImage(MainActivity.this,new File(path)); flag = true; Log.d("downloadVideo", "onSuccess >>>>" + path); } @override public void onFailed(Throwable Throwable) {toast.maketext (mainactivity. this, "下载 页 failed, please download again!" , Toast.LENGTH_SHORT).show(); Log.e("downloadVideo", "onFailed", throwable); flag = true; } }).download()).start(); } @param path */ private void downLoadVideo(String path) {new Thread(() -> new AndroidDownloadManager(MainActivity.this, path) .setListener(new AndroidDownloadManagerListener() { @Override public void onPrepare() { Log.d("downloadVideo", "onPrepare"); } @override public void onSuccess(String path) {toast.maketext (mainactivity.this, "The video was saved to the photo ", Toast.LENGTH_SHORT).show(); FileUtils.saveVideo(MainActivity.this,new File(path)); flag = true; Log.d("downloadVideo", "onSuccess >>>>" + path); } @override public void onFailed(Throwable Throwable) {toast.maketext (mainactivity.this, "mainactivity.maketext (mainactivity.maketext)" , Toast.LENGTH_SHORT).show(); Log.e("downloadVideo", "onFailed", throwable); flag = true; } }).download()).start(); }}Copy the code

    activity_main.xml:

    <? The XML version = "1.0" encoding = "utf-8"? > <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <TextView Android :id="@+id/tv_save_image" Android :layout_width="0dp" Android :layout_height="50dp" android:textSize="16sp" android:textColor="#ffffff" android:gravity="center" android:background="@color/colorPrimary" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toLeftOf="@+id/tv_save_video" app:layout_constraintTop_toTopOf="parent" /> <TextView Android :id="@+id/tv_save_video" Android :layout_width="0dp" Android :layout_height="50dp" android:textSize="16sp" android:textColor="#ffffff" android:gravity="center" android:layout_marginStart="20dp" app:layout_constraintLeft_toRightOf="@+id/tv_save_image" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toBottomOf="parent" app:layout_constraintBottom_toTopOf="parent" android:background="@color/colorPrimary"/> <androidx.constraintlayout.widget.Group android:layout_width="wrap_content" android:layout_height="wrap_content" android:visibility="visible" app:constraint_referenced_ids="tv_save_image,tv_save_video"/> </androidx.constraintlayout.widget.ConstraintLayout>Copy the code
  • 5.FileUtils:

  • /** * @anthor:njb * @date: 2020-04-21 04:36 * @desc: Public class FileUtils {/** * saveImage * @param * @param file */ public static void saveImage(context) context, File file) { ContentResolver localContentResolver = context.getContentResolver(); ContentValues localContentValues = getImageContentValues(context, file, System.currentTimeMillis()); localContentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, localContentValues); Intent localIntent = new Intent("android.intent.action.MEDIA_SCANNER_SCAN_FILE"); final Uri localUri = Uri.fromFile(file); localIntent.setData(localUri); context.sendBroadcast(localIntent); } public static ContentValues getImageContentValues(Context paramContext, File paramFile, long paramLong) { ContentValues localContentValues = new ContentValues(); localContentValues.put("title", paramFile.getName()); localContentValues.put("_display_name", paramFile.getName()); localContentValues.put("mime_type", "image/jpeg"); localContentValues.put("datetaken", Long.valueOf(paramLong)); localContentValues.put("date_modified", Long.valueOf(paramLong)); localContentValues.put("date_added", Long.valueOf(paramLong)); localContentValues.put("orientation", Integer.valueOf(0)); localContentValues.put("_data", paramFile.getAbsolutePath()); localContentValues.put("_size", Long.valueOf(paramFile.length())); return localContentValues; } public static void saveVideo(context, context); Whether the File File) {/ / added to the album ContentResolver localContentResolver = context. GetContentResolver (); ContentValues localContentValues = getVideoContentValues(context, file, System.currentTimeMillis()); Uri localUri = localContentResolver.insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, localContentValues); context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, localUri)); } public static ContentValues getVideoContentValues(Context paramContext, File paramFile, long paramLong) { ContentValues localContentValues = new ContentValues(); localContentValues.put("title", paramFile.getName()); localContentValues.put("_display_name", paramFile.getName()); localContentValues.put("mime_type", "video/mp4"); localContentValues.put("datetaken", Long.valueOf(paramLong)); localContentValues.put("date_modified", Long.valueOf(paramLong)); localContentValues.put("date_added", Long.valueOf(paramLong)); localContentValues.put("_data", paramFile.getAbsolutePath()); localContentValues.put("_size", Long.valueOf(paramFile.length())); return localContentValues; }}Copy the code

    6. File download tools:

    /** * @anthor:njb * @date: 2020-04-21 04:36 * @desc: **/ public class AndroidDownloadManager {private DownloadManager DownloadManager; private Context context; private long downloadId; private String url; private String name; private String path; private AndroidDownloadManagerListener listener; public AndroidDownloadManager(Context context, String url) { this(context, url, getFileNameByUrl(url)); } public AndroidDownloadManager(Context context, String url, String name) { this.context = context; this.url = url; this.name = name; } public AndroidDownloadManager setListener(AndroidDownloadManagerListener listener) { this.listener = listener; return this; } /** * start download */ public void download() {downloadManager.request Request = new downloadManager.request (uri.parse (url)); / / mobile network situation whether to allow roaming request. SetAllowedOverRoaming (false); / / display in the notification bar, the default is according to the request. The setNotificationVisibility (DownloadManager. Request. VISIBILITY_VISIBLE); request.setTitle(name); Request. setDescription(" File downloading......" ); request.setVisibleInDownloadsUi(true); / / set the path of the download File File = new File (context. GetExternalFilesDir (Environment. DIRECTORY_DOWNLOADS), name); request.setDestinationUri(Uri.fromFile(file)); path = file.getAbsolutePath(); If (DownloadManager == null) {DownloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); } // Add the download request to the download queue. If (downloadManager! = null) { if (listener ! = null) { listener.onPrepare(); } downloadId = downloadManager.enqueue(request); Context. registerReceiver(receiver, new IntentFilter(downloadManager.action_download_complete)); Private BroadcastReceiver receiver = new BroadcastReceiver() {@override public void onReceive(Context) context, Intent intent) { DownloadManager.Query query = new DownloadManager.Query(); // Find Query.setFilterByid (downloadId) by downloading the ID; Cursor cursor = downloadManager.query(query); if (cursor.moveToFirst()) { int status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)); Switch (status) {// Download paused case downloadManager. STATUS_PAUSED: break; // Download delay case downloadManager. STATUS_PENDING: break; Case downloadManager. STATUS_RUNNING: break; Case DownloadManager.STATUS_SUCCESSFUL: If (listener! = null) { listener.onSuccess(path); } cursor.close(); context.unregisterReceiver(receiver); break; Case downloadManager. STATUS_FAILED: if (listener! = null) {listener.onFailed(new Exception(" Download failed ")); } cursor.close(); context.unregisterReceiver(receiver); break; }}}}; / / -- -- -- -- -- -- -- -- -- -- -- a private method -- -- -- -- -- -- -- -- -- -- -- - / through the URL for the file name * * * * * * @ @ URL param return * / private static final String getFileNameByUrl(String url) { String filename = url.substring(url.lastIndexOf("/") + 1); filename = filename.substring(0, filename.indexOf("?" ) = = 1? filename.length() : filename.indexOf("?" )); return filename; }}Copy the code
  • public interface AndroidDownloadManagerListener { 

  •  void onPrepare(); 

  •  void onSuccess(String path); 

  •  void onFailed(Throwable throwable); }

  • 7.0 file sharing permission:

  • 8. Finally, put a complete effect drawing: you can see the picture and video to save to the system, and the picture and video can be opened.

  • 9. At present, we have only tested several models of Huawei, Xiaomi, Meizu, Lenovo and so on. There may be problems with some models, friends can test by themselves, AndroidQ has not been adapted, you can add it if you are interested. I’ll add that later.

  • Full project address :gitee.com/jackning_ad…