Jump to content
jelven

[Résolu] Suivi du téléchargement en service

Recommended Posts

Bonjour

Pour mon application j'ai introduis une fonctionnalité qui me permets de télécharger un fichier.

Je me suis aidé avec un tuto, mais avec celui-ci, le téléchargement ne pouvais pas se faire en arrière plan car le code était sur l'activity. J'ai donc créé un service et reprit le code en le modifiant pour qu'il puisse fonctionner avec.

J'ai plus ou moins réussi, le téléchargement fonctionne mais je n'ai pas de suivi avec la progressbar, j'aimerais aussi avoir avoir suivi avec une textview qui afficherais le pourcentage du téléchargement effectué.

Mon problème c'est que je n'arrive pas a géré les broadcast et les intent. je vous demande donc votre aide. SVP !

Pour faciliter la lecture du code, je vous donne directement les fichiers java : http://db.tt/sf03I0N1

Et voici le tuto qui m'a aidé : http://db.tt/b8dmz0dt

Je vous remercie pour vos futur réponse, et je vous demande pardon pour les fautes d'orthographe

Edited by jelven

Share this post


Link to post
Share on other sites

Pour faire communiquer un service et une Activity via broadcast d'Intents, il te suffit, d'un côté (dans le Service), de broadcaster les Intents que tu souhaites, et de l'autre (dans l'Activity) d'avoir un BroadcastReceiver et de l'enregistrer pour qu'il recoive les Intents

Tu peux regarder ce post qui parle exactement de ce sujet

Share this post


Link to post
Share on other sites

pour afficher une progresse bar durant la durée de ton service. ce n'est pas très compliqué, il suffit que ton service ai la référence de ta progressbar ensuite tu peut géré presque comme tu veux.

comment démarre tu ton service?

Share this post


Link to post
Share on other sites

@ Chpil : Merci, j'avais déjà lu ce post et j'ai déjà testé mais le problème ne vien pas de là.

@ Kevin : comme ça :

private static Bundle mExtras;
private Button mStartdownload;
@Override
public void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.start_download);
 if (this.getIntent().getExtras() != null)
  mExtras = this.getIntent().getExtras();
 mStartdownload = (Button) findViewById(R.id.start);
 mStartdownload.setOnClickListener(new Button.OnClickListener() {
  public void onClick(View v) {
buttonStartdownloadClick();
  }
 });
}
protected void buttonStartdownloadClick() {
 if (webConnectionIsOpen())
 {
  Intent serviceIntent = new Intent(mContext, DownloadService.class);
  serviceIntent.putExtra(Keys.KEY_COMMAND_PLAY, true);
  serviceIntent.putExtra(Keys.KEY_TITLE, mExtras.getString(Keys.KEY_TITLE));
  serviceIntent.putExtra(Keys.KEY_FILE_NAME, mExtras.getString(Keys.KEY_FILE_NAME));
  serviceIntent.putExtra(Keys.KEY_FILE_URL, mExtras.getString(Keys.KEY_FILE_URL));
  startService(serviceIntent);
 }
 else
 {
  AlertDialog alertDialog = new AlertDialog.Builder(this).create();
  alertDialog.setTitle("Network Not Connected...");
  alertDialog.setMessage("Please connect to a network and try again");
  alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
  });
  alertDialog.setIcon(R.drawable.icon_k);
  alertDialog.show();
 }
}
private boolean webConnectionIsOpen() {
 ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
 if (cm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE)
.isConnectedOrConnecting()
|| cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI)
.isConnectedOrConnecting())
  return true;
 else
  return false;
}

@ tous : En faite, dans le code de l'activity du tuto il y a ça :

ProgressBar view;

@Override
public void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.main);
	view = (ProgressBar) findViewById(R.id.progress);
}

@Override
public void onProgress(int sent, int length) {
 view.setProgress((int)((float)sent/(float)length*100));
}
@Override
public void onStart(int length) {
 view.setProgress(0);
}

Le problème c'est que view fais référence à la progressbar via :

view = (ProgressBar) findViewById(R.id.progress);

ce qui fais que je ne peux pas tapé ce code dans le service, les 2 code , onProgress et onStart reste donc vide dans le service et il n'y a donc pas de calcul de progression a envoyer a l'activity via broadcast

Pour envoyer les info à l'activity il me faut déjà les créé dans le service, sauf que ça je sais pas faire car je peut pas me référancer à une progress bar via id

Edited by jelven

Share this post


Link to post
Share on other sites

Alors, j'ai fait le broadcast en ignorant le problème et j'obtien un force close, toujours a cause des 2 code, onProgress et onStart. Je voudrais vous demander de regarder si le code est bon au niveau du podcast et aussi de regarder comment réglé le problème svp.

le lien pour télécharger les codes : http://db.tt/bykOsbV5

Share this post


Link to post
Share on other sites

pourquoi ne passe tu pas la référence de ta progresse bar que tu récupère dans le oncreate() de ton activity quand tu démarre ton service.

ensuite dans ton service tu possède la référence et tu en fait ce que tu veux

Share this post


Link to post
Share on other sites

Très mauvaise idée que de passer une référence d'un élément graphique à un service ! Un service est un composant sans IHM, qui NE doit PAS modifier l'IHM; dans une application, Services et Activities vont avoir des cycles de vie pas forcément synchronisés. Que se passera t'il si, ton Service ayant une référence sur un composant graphique d'une Activity, celle-ci disparaît (parce que l'utilisateur a par ex. cliqué sur Back ou Home) alors que le Service continue a exister ? Ton application plantera, lorsque le service essaiera d'utiliser la référence du composant graphique qui est situé dans une Activity qui n'existe plus !!

@jelven

Il ne manque pas grand-chose pour que ça fonctionne. Dans ton Service, tu n'as plus besoin d'une référence à la ProgressBar; mais là où tu voulais la modifier, il faut que tu broadcast l'intent avec les informations nécessaires. Et dans l'Activity, tu reçois cet Intent et tu peux en extraire les informations pour mettre à jour la ProgressBar

Share this post


Link to post
Share on other sites

effectivement il ne faut pas faire n'importe [color=red]koi[/color]. un truc simple a faire aussi, il suffit de faire un genre de listener de service. l'activity implémentera donc des méthode comme du style dataChanged(). et cette méthode sera appelée depuis le service. il suffira de faire le traitement que l'on souhaite dans cette méthode dans l'activity

mais si il souhaite afficher une progressbar je présume qu'il reste sur la même activity sinon personnelement je fait une notification c'est beaucoup plus simple et cela permet de faire bcp de chose

Share this post


Link to post
Share on other sites

Merci beaucoup, pour vos réponses ! Malheuresement, je vous cache pas que j'ai pas tous compris ^^

@ Chpil : j'ai compris pourquoi ça ne fonctionnerais pas et je crois que j'ai un peut près compris pour l'autre partie de la réponse. Mais je ne sais pas comment faire, Je ne suis qu'un débutant et je n'ai pas beaucoup de connaisance, je cherche a en apprendre plus, donc aurrais tu un tuto (si possible en français) ou en code type a ue donné ?

@ Kevin : Désolé mais pour toi, je n'ai compris que la premiere phrase ^^ Pourrais tu mieux expliquer stp ?

Share this post


Link to post
Share on other sites

reprenons depuis le début et clairement.

ton service. quelle est sa durée de vie. il tourne en fond pendant toute l'application ou tu le démarre et l'arrête dans un activiy et tu l'utilise simplement pour effectué une requête vers le serveur sans bloqué l'activity?

Share this post


Link to post
Share on other sites

Ce que je veut c'est : lancer le service via l'activity et le stoper toujours avec cette activity mais je voudrais que le service puisse durée même si l'activity est coupé. cela me permettra de lancer le téléchargement et de le continué quand je quitterai l'activity.

Share this post


Link to post
Share on other sites

ok alors abandonne l'idée d'une progressdialog et utilise les notifications

Share this post


Link to post
Share on other sites

ok alors abandonne l'idée d'une progressdialog et utilise les notifications

Heu pourquoi abandonner l'idée d'une progressdialog? C'est tout a fait faisable !

Il suffit de faire des "connexion/déconnexion" du service à chaque onResume/onPause de l'activity

Et évidemment, on vérifie si le service est démarré.

Edited by Sylvain-a

Share this post


Link to post
Share on other sites

oui je suis d'acord mais le but d'un service pour moi c'est de faire une tache de fond que l'utilisateur ne sens rend pas compte. donc une notification permet simplement de dire que le service tourne et on peut y mettre ce que l'on veut comme information.

alors que la progressedialog cela bloque l'utilisateur sauf ci celui-ci la quitte donc c'est génant pour l'utilisation. pour moi une progressedialog a plus de sens quand il s'agit d'un thread

Share this post


Link to post
Share on other sites

Personnellement j'aurai plutôt mis une barre de téléchargement ne bloquant pas l'utilisateur mais lui indiquant in-app l'état du téléchargement. (donc pas de progressdialog mais une progressbar intégré à l'activity).

Après ça dépend aussi de ce que jelven veut faire.

Share this post


Link to post
Share on other sites
Personnellement j'aurai plutôt mis une barre de téléchargement ne bloquant pas l'utilisateur mais lui indiquant in-app l'état du téléchargement. (donc pas de progressdialog mais une progressbar intégré à l'activity).

Après ça dépend aussi de ce que jelven veut faire.

OUI OUI !!! C'EST CE QUE JE VEUX FAIRE !! ^^ une progressbar ! ^^

Comme je vous l'ai expliquer mon service est bon, mon téléchargement aussi et j'ai bien mis une notification pour signaler qu'un téléchargement est en cours (donc le service aussi), mais je n'arrive pas à syncroniser la progressbar avec le téléchargement, pour efectivement avoir un suivi. J'ai compris avec comment géré les broadcast etc ... Mais en ce qui conserne la création de l'information à envoyer via broadcast, je n'y arrive pas, c'est là que je demande votre aide.

Si il y a besoin que je mette le code sur le fofo vous me le dite sinon vous pouver aller voir ce lien pour directement télécharger le code : http://db.tt/bykOsbV5

En faite j'ai l'imprésion que vous n'avez pas lut le code dans le fichier download qui vas avec le service

donc je suis désolé de me répéter.

Au faite, merci pour le lien du tuto, très intérésant comme tuto, mais a moins que je suis nul (ce qui est tous a fais posible) ba j'ai pas trouver comment faire ^^

Je voudrais come même vous remerci de prendre du temps pour mon problème !

Share this post


Link to post
Share on other sites

Comme déjà dit, il ne te manque pas grand chose pour réussir à faire ce que tu veux.

Dans ton service, il te suffit d'emettre l'Intent à destination de ton Receiver de l'Activity depuis la méthode onProgress

 public boolean onProgress(int sent, int length) {
   Intent intent = new Intent(BROADCAST_PROGRESSBAR);
   intent.putExtra(Keys.KEY_PROGRESSBAR, (int)((float)sent/(float)length*100));
   sendBroadcast(intent);
   return false;
 }

Et plus besoin, dans ton Service, de la référence à la ProgressBar, ni du mHandlerSeekbar et du Runnable sendUpdatesToUI

  • Like 1

Share this post


Link to post
Share on other sites

Meci beaucoup, le code fonctionne impec !

Hop ! Résolu

Share this post


Link to post
Share on other sites

Petite question un petit peut HS, j'aimerais maintenant rajouter un suivi du téléchargement avec un système de pourcentage

J'ai crée une text view et dans le onCreate j'ai rajouté

mProgressPercentage = (TextView)findViewById(R.id.progress_percentage);

Puis dans le BroadcastReceiver j'ai fait ça :

private BroadcastReceiver mProgressBarReceiver = new BroadcastReceiver() {
 @Override
 public void onReceive(Context context, Intent seekIntent) {
  int Progress = seekIntent.getIntExtra(Keys.KEY_PROGRESS, 0);
  mProgressBar.setProgress(Progress);
  mProgressPercentage.setText(Progress);
 }
};

J'obtien ensuite un force close....

J'aimerais savoir comment on fait s'il vous plais car visiblement, on fait pas comme ça ^^

Edited by jelven

Share this post


Link to post
Share on other sites

Le problème vient de la ligne 136 de DownloadActivity.

A priori le nom d'une ressource doit être incorrect ou tu as oublié de créer la ressource en question

(A noter : tu sais que tu peux copier coller le code et le logcat directement dans des balises "codes" sur le forum? Ca nous éviterait d'avoir a suivre sur des liens ;))

Share this post


Link to post
Share on other sites

Le problème vien donc de cette ligne :

mProgressPercentage.setText(Progress);

Mais quand tu parle de ressource tu parle de quoi ? Désolé j'ai pas encore appris tous le vocabulaire ^^

Edited by jelven

Share this post


Link to post
Share on other sites

les ressources sont les strings, number, drawable etc contenus dans les fichiers xml (ou images) du dossier res

Ton problème vient du fait que tu utilises setText(int) or le int en question est censé être une ressource.

Pour utiliser le progress dans ton setText tu dois utiliser setText(String) :

setText(String.valueOf(Progress))

(A noter : tu n'as pas appris tout le vocabulaire... mais ça c'est la base :P)

Edited by Sylvain-a

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.






×
×
  • Create New...