在Android上使用后台服务下载数据-一些一般问题
谈到Android上的后台服务,我有一些理解上的问题。我有一种感觉,对于你们这些有着丰富经验的人来说,我的问题很容易回答,我只需要被指向正确的方向:-) 首先让我解释一下我想要实现的目标: 我想下载带有一组数据的图片(下载url、标题、ID、所有者ID和文件名)。用户通过文本字段输入该数据。用户可以输入该数据集的多个实体,因此所有内容都存储在ArrayList中。例如,URL有一个ArrayList,ID有一个ArrayList。 从长远来看,这些信息不应该来自用户,而是来自服务器。用户界面基本上只是用于调试。 下载完成后,将数据集放入SQLite数据库中 我的目标是拥有一个独立的后台服务,负责下载并在下载完成后立即将数据插入数据库。 因此,从用户输入数据的活动中,我创建了一个意图,并将用户数据作为额外数据添加。第一个问题是:没有额外的ArrayList。这引出了我的第一个问题: 如何在服务/活动之间传递ArrayList? 我读过一些关于包裹的文章,尽管long是一种原始数据类型,但这是一种方法吗 我的第二个问题是,在再次调用服务之前,我无法确定下载是否完成。因此,当再次调用服务时,将再次调用onStartCommand()方法。现在我的服务类如下所示(ArrayList中的数据尚未实现):在Android上使用后台服务下载数据-一些一般问题,android,arraylist,download,queue,background-service,Android,Arraylist,Download,Queue,Background Service,谈到Android上的后台服务,我有一些理解上的问题。我有一种感觉,对于你们这些有着丰富经验的人来说,我的问题很容易回答,我只需要被指向正确的方向:-) 首先让我解释一下我想要实现的目标: 我想下载带有一组数据的图片(下载url、标题、ID、所有者ID和文件名)。用户通过文本字段输入该数据。用户可以输入该数据集的多个实体,因此所有内容都存储在ArrayList中。例如,URL有一个ArrayList,ID有一个ArrayList。 从长远来看,这些信息不应该来自用户,而是来自服务器。用户界面基本
公共类DownloadService扩展服务实现DownloadAlbumPictures.DownloadCompletedListener{
公共最终静态字符串EXTRA\u ALBUMPICTURE\u URL=“ALBUM\u PICTURE\u URL”;
公共最终静态字符串EXTRA\u ALBUMPICTURE\u NAMES=“ALBUM\u PICTURE\u NAMES”;
公共最终静态字符串EXTRA\u ALBUMPICTURE\u TITLES=“ALBUM\u PICTURE\u TITLES”;
私有数组列表;
文件的私有ArrayList名称;
私有ArrayList所有者ID;
私人ArrayList pictureIds;
私有ArrayList AlbumID;
私人ArrayList职位;
私人ArrayList头衔;
私有字符串路径文件;
//下载接口
public void albumPicDownloadCompleted(上下文上下文、Uri、int indexOfCompletedFile){
//初始化
相册图片新相册图片;
//下载数据
long ownerId=0//ownerId.get(indexOfCompletedFile);
long pictureId=0//pictureId.get(indexOfCompletedFile);
int positionInAlbum=0//positions.get(indexOfCompletedFile);
字符串标题=titles.get(indexOfCompletedFile);
字符串pathToPic=uri.toString();
long albumId=0//albumId.get(indexOfCompletedFile);
newAlbumPic=新的AlbumPicture(所有者ID、pictureId、位置栏、标题、路径主题、albumId);
//将图片放入数据库
newAlbumPic.putinodb(本);
}
@凌驾
公共int onStartCommand(Intent Intent、int标志、int startId){
picUrls=intent.getStringArrayListExtra(额外的图片URL);
namesForFiles=intent.getStringArrayListExtra(额外的图片名称);
titles=intent.getStringArrayListExtra(额外的图片标题);
DownloadAlbumPictures dwnldAlbumPics=新下载的AlbumPictures(newPicUrls、newNamesForFiles);
dwnldAlbumPics.execDownload(this);
返回服务。启动\u重新交付\u意图;
}
}
DownloadAlbumPictures.execDownload调用Androids下载管理器。它还为下载完成事件注册广播接收器,然后调用接口函数albumPicDownloadCompleted():
公共类下载相册图片{
公共接口下载CompletedListener{
public void albumPicDownloadCompleted(上下文上下文、Uri、int indexOfCompletedFile);
}
私有数组列表;
文件的私有ArrayList名称;
私有ArrayList下载引用;
私有字符串路径文件;
私有下载CompletedListener dwnldCompletedListener;
公开下载相册图片(ArrayList\u picUrls、ArrayList\u namesForFiles){
picUrls=_picUrls;
namesForFiles=_namesForFiles;
}
公众下载相册图片(){
}
公共布尔执行下载(上下文){
//检查源信息是否可用
if(picUrls==null | | namesForFiles==null)
返回false;
获取图片(上下文);
返回true;
}
public boolean execDownload(上下文上下文、ArrayList\u picUrls、ArrayList\u namesForFiles){
picUrls=_picUrls;
namesForFiles=_namesForFiles;
返回execDownload(上下文);
}
//示例用于下载图片
私有void fetchPics(上下文){
//路径
pathToFiles=CreatePathForalPumpictures();
//侦听器接口
试一试{
dwnldCompletedListener=(DownloadCompletedListener)上下文;
}catch(ClassCastException e){
抛出新的ClassCastException(context.toString()+“必须为AlbumPicture下载实现DownloadCompletedListener。”);
}
//将文件发送到下载管理器并保存引用
//TODO文件类型检查丢失=>安全问题
DownloadFiles DownloadFiles=新的下载文件(picurl、pathToFiles、namesForFiles);
if(downloadFiles.startDownload(上下文)){
downloadReferences=downloadFiles.getDownloadReferences();
}
否则{
downloadReferences=null;
}
//为文件下载完成时添加侦听器
IntentFilter broadcastFilter=新的IntentFilter(DownloadManager.ACTION\u DOWNLOAD\u COMPLETE);
BroadcastReceiver=新的BroadcastReceiver(){
@凌驾
公共void onReceive(上下文、意图){
long reference=intent.getlongtextra(DownloadManager.EXTRA_DOWNLOAD_ID,-1);//获取已完成的
public class DownloadService extends Service implements DownloadAlbumPictures.DownloadCompletedListener {
public final static String EXTRA_ALBUMPICTURE_URLS = "ALBUM_PICTURE_URLS";
public final static String EXTRA_ALBUMPICTURE_NAMES = "ALBUM_PICTURE_NAMES";
public final static String EXTRA_ALBUMPICTURE_TITLES = "ALBUM_PICTURE_TITLES";
private ArrayList<String> picUrls;
private ArrayList<String> namesForFiles;
private ArrayList<Long> ownerIds;
private ArrayList<Long> pictureIds;
private ArrayList<Long> albumIds;
private ArrayList<Integer> positions;
private ArrayList<String> titles;
private String pathToFiles;
// download interface
public void albumPicDownloadCompleted(Context context, Uri uri, int indexOfCompletedFile) {
// init
AlbumPicture newAlbumPic;
// data from download
long ownerId = 0 //ownerIds.get(indexOfCompletedFile);
long pictureId = 0 //pictureIds.get(indexOfCompletedFile);
int positionInAlbum = 0 //positions.get(indexOfCompletedFile);
String title = titles.get(indexOfCompletedFile);
String pathToPic = uri.toString();
long albumId = 0 //albumIds.get(indexOfCompletedFile);
newAlbumPic = new AlbumPicture(ownerId, pictureId, positionInAlbum, title, pathToPic, albumId);
// put picture into DB
newAlbumPic.putIntoDb(this);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
picUrls = intent.getStringArrayListExtra(EXTRA_ALBUMPICTURE_URLS);
namesForFiles = intent.getStringArrayListExtra(EXTRA_ALBUMPICTURE_NAMES);
titles = intent.getStringArrayListExtra(EXTRA_ALBUMPICTURE_TITLES);
DownloadAlbumPictures dwnldAlbumPics = new DownloadAlbumPictures(newPicUrls, newNamesForFiles);
dwnldAlbumPics.execDownload(this);
return Service.START_REDELIVER_INTENT;
}
}
public class DownloadAlbumPictures {
public interface DownloadCompletedListener {
public void albumPicDownloadCompleted(Context context, Uri uri, int indexOfCompletedFile);
}
private ArrayList<String> picUrls;
private ArrayList<String> namesForFiles;
private ArrayList<Long> downloadReferences;
private String pathToFiles;
private DownloadCompletedListener dwnldCompletedListener;
public DownloadAlbumPictures(ArrayList<String> _picUrls, ArrayList<String> _namesForFiles) {
picUrls = _picUrls;
namesForFiles = _namesForFiles;
}
public DownloadAlbumPictures() {
}
public boolean execDownload(Context context) {
// check if source info is available
if (picUrls == null || namesForFiles == null)
return false;
fetchPics(context);
return true;
}
public boolean execDownload(Context context, ArrayList<String> _picUrls, ArrayList<String> _namesForFiles) {
picUrls = _picUrls;
namesForFiles = _namesForFiles;
return execDownload(context);
}
// example use to download pictures
private void fetchPics(Context context) {
// path
pathToFiles = createPathForAlbumPictures();
// listener interface
try {
dwnldCompletedListener = (DownloadCompletedListener) context;
} catch (ClassCastException e) {
throw new ClassCastException(context.toString() + " must implement DownloadCompletedListener for AlbumPicture download.");
}
// sending files to download manager and saving reference
// TODO file type check missing => security issue
DownloadFiles downloadFiles = new DownloadFiles(picUrls, pathToFiles, namesForFiles);
if (downloadFiles.startDownload(context)) {
downloadReferences = downloadFiles.getDownloadReferences();
}
else {
downloadReferences = null;
}
// add listeners for when file download is completed
IntentFilter broadcastFilter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
long reference = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1); // get reference of completed download (if no completed download -1)
// check all downloaded files
for (int i=0; i<downloadReferences.size(); i++) {
if (reference == downloadReferences.get(i)) {
// actual path to file needs to be updated
DownloadManager dwnldmngr = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
Uri uriOfFile = dwnldmngr.getUriForDownloadedFile(reference);
// hand over uri to interface
dwnldCompletedListener.albumPicDownloadCompleted(context, uriOfFile, i); // interface
}
}
}
};
context.registerReceiver(receiver, broadcastFilter);
}
}