第 1 步:在 Android 清单中声明权限
在您的第一个 Android 项目中要做的第一件事是在“AndroidManifest.xml”文件中声明所需的权限。
对于 Android 从 URL 下载图像,我们需要访问 Internet 以下载文件并读取和写入内部存储以将图像保存到内部存储的权限。
在 AndroidManifest.xml 文件的标签顶部添加以下代码行:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
第 2 步:向用户请求所需的权限
Android 允许每个应用程序在沙盒中运行。如果应用程序需要访问该沙箱之外的某些资源或信息,则需要向用户请求许可。
从 Android 6.0 开始,谷歌希望开发人员在应用程序内向用户请求权限,有关权限的更多详细信息请阅读此内容。
因此,对于 Android 从 URL 下载图像,您需要请求读取存储和写入
为此,我们将使用以下代码行首先检查用户是否已授予所需的权限,如果没有,则我们将请求存储读写权限的权限。
我们正在创建一个方法“Downlaod Image”,您可以在需要下载图像的任何地方简单地调用它。
void DownloadImage(String ImageUrl) {
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 123);
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 123);
showToast("Need Permission to access storage for Downloading Image");
} else {
showToast("Downloading Image...");
//Asynctask to create a thread to downlaod image in the background
new DownloadsImage().execute(ImageUrl);
}
}
现在我们已经请求并被授予用户权限,从 url 开始下载 android 图像,我们将创建一个 AsyncTask,因为您不允许在主线程中运行后台进程。
class DownloadsImage extends AsyncTask<String, Void,Void>{
@Override
protected Void doInBackground(String... strings) {
URL url = null;
try {
url = new URL(strings[0]);
} catch (MalformedURLException e) {
e.printStackTrace();
}
Bitmap bm = null;
try {
bm = BitmapFactory.decodeStream(url.openConnection().getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
//Create Path to save Image
File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES+ "/AndroidDvlpr"); //Creates app specific folder
if(!path.exists()) {
path.mkdirs();
}
File imageFile = new File(path, String.valueOf(System.currentTimeMillis())+".png"); // Imagename.png
FileOutputStream out = null;
try {
out = new FileOutputStream(imageFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try{
bm.compress(Bitmap.CompressFormat.PNG, 100, out); // Compress Image
out.flush();
out.close();
// Tell the media scanner about the new file so that it is
// immediately available to the user.
MediaScannerConnection.scanFile(MainActivity.this,new String[] { imageFile.getAbsolutePath() }, null,new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
// Log.i("ExternalStorage", "Scanned " + path + ":");
// Log.i("ExternalStorage", "-> uri=" + uri);
}
});
} catch(Exception e) {
}
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
showToast("Image Saved!");
}
}
在上面给出的代码行中,创建了一个 URL 和位图,使用 BitmapFactory.decodeStream 下载文件。
创建文件路径以保存图像(我们在 DIRECTORY_PICTURES 中创建了一个名为“AndroidDvlpr”的文件夹)并初始化下载。
下载文件 MediaScannerConnection 后,将调用从文件中读取元数据并将文件添加到媒体内容提供程序,以便用户可以使用图像。
在上面的代码行中,我们还创建了一个方法 showToast() 来显示 Toast。完整代码在这里:
void showToast(String msg){
Toast.makeText(MainActivity.this,msg,Toast.LENGTH_SHORT).show();
}
在这里阅读更多