上篇博文中点击打开链接,我们实现了网络图片的下载,那么在本篇博文中,我们对其进行一些功能的简单扩展,当我们下载图片完成后,
发送下载完成的消息到通知栏,当我们点击消息时,弹出一个Activity来显示我们之前下载的图片。这里就需要加入定义通知栏的功能,还有就是
从sdcard读取文件显示到Activity的功能。
对于前面的下载的实现和上篇博文是一样的,接下来我们加入一些新的功能,我们直接从代码中了解下功能的具体实现吧。
MainActivity:同样是传个网址给Service用于图片的解析。
package com.example.text08;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void download(View view) {
Intent intent = new Intent(this, MyService.class);
intent.putExtra("path", "https://www.baidu.com/img/bd_logo1.png");
startService(intent);
}
}
然后是在Service的子类中得到传来的网址并进行图片的解析:
package com.example.text08;
import com.example.http.ExternalStorageUtils;
import com.example.http.HttpUtils;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationCompat.Builder;
import android.util.Log;
public class MyService extends Service {
private String fileName;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
final String path = intent.getStringExtra("path");
new Thread(new Runnable() {
@Override
public void run() {
// 判断网络状态
if (HttpUtils.isNetWorkConn(MyService.this)) {
// 把网址中的信息存放到字节数组中
byte[] data = HttpUtils.getByteArray(path);
// 得到写入sdcard的文件名
fileName = path.substring(path.lastIndexOf("/") + 1);
// 判断字节数组中是否有数据
if (data != null && data.length != 0) {
// 调用写入文件的方法,把字节数组写入文件中
boolean flag = ExternalStorageUtils
.writeExternalStorageRoot(fileName, data,
MyService.this);
if (flag) {
Log.i("main", "图片保存到sdcard成功");
// 调用发送通知的方法
sendNotification();
} else {
Log.i("main", "图片保存到sdcard失败");
}
} else {
Log.i("main", "图片下载失败");
}
} else {
Log.i("main", "网络连接异常");
}
// 停止服务
stopSelf();
}
}).start();
return super.onStartCommand(intent, flags, startId);
}
// 定义发送通知的方法
private void sendNotification() {
NotificationCompat.Builder builder = new NotificationCompat.Builder(
MyService.this);
// 设置通知栏标题
builder.setContentTitle("图片下载");
// 设置通知栏内容
builder.setContentText("图片保存到sdCard成功");
// 设置图标
builder.setSmallIcon(R.drawable.ic_launcher);
builder.setWhen(System.currentTimeMillis());
// 定义一个Intent对象
Intent intent = new Intent(MyService.this, SecondActivity.class);
intent.putExtra("fileName", fileName);
// 定义延迟意图,发出去一点就执行
PendingIntent pendingIntent = PendingIntent.getActivity(MyService.this,
1, intent, PendingIntent.FLAG_ONE_SHOT);
// 将延迟意图给Builder构建器
builder.setContentIntent(pendingIntent);
// 获取通知管理器
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// 发送通知
manager.notify(0, builder.build());
}
}
接下来是HttpUtils工具类:
package com.example.http;
import java.io.IOException;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import android.content.Context;
import android.content.Entity;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
public class HttpUtils {
// 获取网路连接状态
public static boolean isNetWorkConn(Context context) {
boolean flag = false;
ConnectivityManager manager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = manager.getActiveNetworkInfo();
if (info != null) {
return info.isConnected();
}
return flag;
}
// 得到字节数组
public static byte[] getByteArray(String path) {
HttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet(path);
try {
HttpResponse res = client.execute(get);
if (res.getStatusLine().getStatusCode() == 200) {
return EntityUtils.toByteArray(res.getEntity());
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
接下来是用于读写sdcard文件的工具类:
package com.example.http;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Environment;
import android.util.Log;
public class ExternalStorageUtils {
// 判断sdCard是否可用
public static boolean isSdcardUseful() {
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
return true;
}
return false;
}
// 存储内容
public static boolean writeExternalStorageRoot(String name, byte[] data,
Context context) {
if (isSdcardUseful()) {
// 获取sdCard的根目录
File sdFile = Environment.getExternalStorageDirectory();
// 创建文件的抽象路径
File file = new File(sdFile, name);
// 向文件中写数据
try {
FileOutputStream fos = new FileOutputStream(file);
fos.write(data, 0, data.length);
fos.flush();
fos.close();
// 返回true
return true;
} catch (Exception e) {
e.printStackTrace();
}
} else {
Log.i("main", "sdCard不可用");
}
return false;
}
// 读取外部存储中根目录的文件
public static byte[] readExternalStorageRoot(String fileName) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
if (isSdcardUseful()) {
File sdFile = Environment.getExternalStorageDirectory();
File file = new File(sdFile, fileName);
if (file.exists()) {
// 读取文件
try {
FileInputStream fis = new FileInputStream(file);
byte[] buffer = new byte[1024];
int len = 0;
while ((len = fis.read(buffer)) != -1) {
baos.write(buffer, 0, len);
baos.flush();
}
fis.close();
return baos.toByteArray();
} catch (Exception e) {
e.printStackTrace();
}
} else {
Log.i("main", "文件不存在");
}
}
return null;
}
// 直接获取Bitmap的形式返回
public static Bitmap readExternalStorageRootToBitmap(String fileName) {
Bitmap bitmap = null;
if (isSdcardUseful()) {
File file = new File(Environment.getExternalStorageDirectory(),
fileName);
bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
}
return bitmap;
}
}
然后是再创建一个Activity,当点击通知消息时用于实现跳转并显示从sdcard读取到的图片:
package com.example.text08;
import com.example.http.ExternalStorageUtils;
import android.app.Activity;
import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.widget.ImageView;
/**
* 获取通知中传递的文件名--》根据名称区根目录中找到对应的文件--》读取外部存储的文件--》byte[]--->Bitmap-->ImageView
*
* @author Administrator
*
*/
public class SecondActivity extends Activity {
private ImageView iv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second);
iv = (ImageView) findViewById(R.id.iv);
// 获取通知中传递的文件的名称
Intent intent = getIntent();
String fileName = intent.getStringExtra("fileName");
// 调用读取sdcard内容的方法
Bitmap bitmap = ExternalStorageUtils
.readExternalStorageRootToBitmap(fileName);
iv.setImageBitmap(bitmap);
// 取消通知
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager.cancel(0);
}
}
最后,同样是在清单文件中配置并加上对应权限:
<service android:name="com.example.text08.MyService" >
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
好了,我们看一下运行结果吧: