# Alle Daten gehen verloren, wenn die Displaysperre aktiviert wird?



## bruce85 (16. Nov 2012)

Hallo,
ich habe folgendes Problem,
wenn sich die Displaysperre am Handy aktiviert, dann gehen alle Daten verloren, z.B. einen Download, der gerade läuft u.s.w.

In der onDraw Methode wird auch immer wieder erneut public Panel(Context context) aufgerufen, wenn die Displaysperre aktiviert wurde und ich es wieder deaktiviere.

z.B. wird in der Methode public Panel(Context context) einen DialogBox geöffnet, beende ich diesen Dialog und aktiviere mal die Displaysperre und deaktiviere es wieder, dann öffnet sich der DialogBox wieder erneut.

Kann man das Problem irgendwie lösen?

Ich bedanke mich schonmal im Voraus.

MfG


----------



## bruce85 (17. Nov 2012)

Weiss denn niemand ne lösung?

Ich teste z.B. meine App am Handy, bei onCreate() wird ein ProgressDialog aufgerufen und etwas gedownloadet, z.B. Datei 1 von 2 wird heruntergeladen, jetzt aktiviert sich z.B. die Bildschirmsperre, die ich dann natürlich wieder deaktiviere und dann ladet es nicht mehr weiter und stattessen steht dann Datei 1 von 0 wird heruntergeladen und der ProgressBar ist eingefrohren.

Oder wenn z.B. eine Datei gedownloadet wurde und der Progressdialog sich dann wieder schließt und ich dann mal die Bildschirmsperre aktiviere und wieder deaktiviere, ist der ProgressDialog wieder geöffnet, was nicht sein darf.

Ich weiss echt nicht, wie ich das Problem beheben kann, in google finde ich auch nix zu diesem Thema.

Ich wäre euch sehr dankbar, wenn mir da jemand Weiterhelfen könnte.

MfG


----------



## Robokopp (17. Nov 2012)

Die oncreate wird jedes mal wenn du die displaysperre deaktivierst erneut aufgerufen


----------



## bruce85 (17. Nov 2012)

Danke Dir.

Kann man das nicht irgendwie verhindern das es erneut geladen wird?
Da ich ein ProgressDialog bei onCreate() erstelle und es sonst immer wieder erneut erstellt wird und das alte überschreibt und dann geht garnix mehr mit dem downloaden, also der Download fortschritt wird dann nicht mehr im ProgressDialog dargestellt.

MfG


----------



## mjdv (17. Nov 2012)

Am besten nutzt du einen Service, oder du nutzt die Download API welche es glaube ich ab 2.3 gibt


----------



## Stroker89 (17. Nov 2012)

onCreate wird nur aufgerufen, wenn deine App Destroyed wurde...

siehe dazu auch den Android Lifecycle:







Falls du verhindern möchtest dass deine Daten verloren gehen falls der GC entscheidet deine App zu löschen kannst du es hiermit versuchen (Post von einem stackoverflow Benutzer):

```
@Override
public void onSaveInstanceState(Bundle outState){
    iGameContent.saveGame(outState);
}
```

Save all your needed data into outState, and in the onCreate method, check if its a new instance or saved instance, like this:


```
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.game);

    if (savedInstanceState!=null){
        iGameContent.loadGame(savedInstanceState);
    }else{
        // Normal initialization
    }
}
```
An example of the save/load to a Bundle is the following:


```
public void loadGame(Bundle aBundle){
    iBadsHit = aBundle.getInt("iBadsHits",0);
}

public void saveGame(Bundle aBundle){
aBundle.putInt("iBadsHit", iBadsHit);
}
```


----------



## bruce85 (17. Nov 2012)

Vielen Dank.

Irgendwie klappt das nicht so ganz, ich hab mal zum test versucht den AsynkTask bei onDestroy zu beenden:

```
@Override
public void onDestroy(){
   super.onDestroy();
   if( aTask != null){
       if(aTask.getStatus().equals( AsyncTask.Status.RUNNING)){
           aTask.cancel(true);
       }
   }
}
private void startDownload() {
    aTask = (DownloadFileAsync) new DownloadFileAsync().execute();
}
```

irgendwie hat es kene wirkung.
Woran könnte das liegen?

MfG


----------



## Stroker89 (17. Nov 2012)

Ist dein AsyncTask eventuell schon fertig bevor onDestroy aufgerufen wird? 

Gruß


----------



## bruce85 (17. Nov 2012)

Nein, das ist so:
Ich lade über ein ProgressDialog einige dateien herunter und wenn ich mal die Bildschirmsperre aktiviert hatte und wieder deaktiviere, dann ladet es trotztdem im  hintergrund weiter aber der ProgressDialog zeigt es dann nicht mehr richtig an, es ist sozusagen stehen geblieben im ProgressDialog.
Der Fortschritt geht nicht mehr weiter, aber es ladet trotzdem im hintergrund weiter runter.


```
@Override
    public void onDestroy(){
       super.onDestroy();
       mProgressDialog.setView(null);
       if( aTask != null){
           if(aTask.getStatus().equals( AsyncTask.Status.RUNNING)){
               aTask.cancel(true);
           }
       }
    }
    
    @Override
    protected Dialog onCreateDialog(int id) {
        switch (id) {
		case DIALOG_DOWNLOAD_PROGRESS:
			mProgressDialog = new ProgressDialog(NippelActivity.this);
			mProgressDialog.setMessage("Datei (1/"+downloadAnz+") wird heruntergeladen...");
			mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
			mProgressDialog.setCancelable(false);
			mProgressDialog.show();
			return mProgressDialog;
		default:
			return null;
        }
    }
    
    private void startDownload() {
        aTask = (DownloadFileAsync) new DownloadFileAsync().execute();
    }

    class DownloadFileAsync extends AsyncTask<String, String, String> {
    	private Exception exception;
    	@Override
    	protected void onPreExecute() {
    		super.onPreExecute();
    		showDialog(DIALOG_DOWNLOAD_PROGRESS);
    	}

    	@Override
    	protected String doInBackground(String... aurl) {
    		int count;

    		try {
    			for (int i=0; i<videoAnz; i++) {
            		if (videos[i].download == 1) {
            			try {
	            			downloadNr = downloadNr + 1;
			    			URL url = new URL("http://meineseite.de/test/"+videos[i].dUrl);
			    			URLConnection conexion = url.openConnection();
			    			conexion.connect();
			
			    			int lenghtOfFile = conexion.getContentLength();
			    			Log.d("ANDRO_ASYNC", "Lenght of file: " + lenghtOfFile);
			
			    			InputStream input = new BufferedInputStream(url.openStream());
			    			OutputStream output = new FileOutputStream("/sdcard/"+videos[i].dOrt);
			
			    			byte data[] = new byte[1024];
			
			    			long total = 0;
			
			    			while ((count = input.read(data)) != -1) {
			    				total += count;
			    				publishProgress(""+(int)((total*100)/lenghtOfFile));
			    				output.write(data, 0, count);
			    			}
	            			videos[i].download = 0;
			    			//postInvalidate();
			    			output.flush();
			    			output.close();
			    			input.close();
            			} catch (Exception e) {
            	            this.exception = e;
            	            return null;
            	        }
            		}
    			}
    		} catch (Exception e) {}
    			return null;

    	}
    	protected void onProgressUpdate(String... progress) {
    		 Log.d("ANDRO_ASYNC",progress[0]);
    		 mProgressDialog.setProgress(Integer.parseInt(progress[0]));
    		 mProgressDialog.setMessage("Datei ("+downloadNr+"/"+downloadAnz+") wird heruntergeladen...");
    	}

    	@Override
    	protected void onPostExecute(String unused) {
    		dismissDialog(DIALOG_DOWNLOAD_PROGRESS);
    	}
    }
```

und in der Methode onCreate starte ich den Task über ein AlertDialog:

```
startDownload();
```

Wie könnte man das ganze einfach wieder löschen, wenn die Bildschirmsperre mal aktiviert wurde?

Vielen Dank schonmal.

MfG


----------



## Stroker89 (17. Nov 2012)

Hmm ich würde den Download an deiner Stelle auch über einen LocalService und dort den Download über einen Thread oder AsyncTask machen und bei Fortschritt den Broadcast zu der Activity schicken.

Mache gerade etwas ähnliches.
Wenn du den AsyncTask benutzt im Service, ist die Kommunikation ein bisschen leichter, da du direkt von dort aus den Broadcast schicken kannst. Wenn du einen eigenen Thread nehmen möchtest, müsstest du noch die passenden MessageHandler implementieren.
Letzteren Fall benutze ich gerade.

Gruß


----------



## bruce85 (17. Nov 2012)

Vielen Dank.

Leider bin ich noch nicht so fit bei der Programmierung von Java-Android und weiss nicht, wie ich das machen könnte.

Gibt es Vielleicht gute Tutorials, indem das beschrieben ist?

MfG


----------



## bruce85 (17. Nov 2012)

Ich habe jetzt etwas gefunden:
java - Download a file with Android, and showing the progress in a ProgressDialog - Stack Overflow

Das scheint mir einbisschen kompliziert zu sein.

Ich habe mein Code etwas umgeändert, wie es auf der Seite zusehen ist ohne Service und habe mir überlegt, sobald onDestroy aufgerufen wurde, den Thread einfach sauber zu entfernen, nur wie könnte man das fehlerfrei machen?

MfG


----------



## Stroker89 (17. Nov 2012)

Das ist gar nicht kompliziert sondern ein super Beispiel 

Ein Service ist verhält sich ähnlich wie eine Activity, nur ohne UI.

Kommuniziert wird über einen Broadcast. Die sendende Seite schickt einen Broadcast und die empfangende Seite hat einen BroadcastReceiver mit der die Daten empfangen werden können.
Lies dich doch mal ein bisschen in Services ein  
Sobald du es einmal begriffen hast ist es gar nicht mehr schwer 

Gruß


----------



## bruce85 (17. Nov 2012)

Danke Dir.
Ich habe aber gelesen, dass das ab Android 3.? funktioniert und möchte es auch ab 2.1 verwenden.
Naja ich werd mich damit mal auseinandersetzen und vielen Dank.

MfG


----------



## Stroker89 (17. Nov 2012)

Ich verwende 2.2 und alles passt ;-)


----------



## bruce85 (17. Nov 2012)

Naja ich hab so langsam die Lust verloren, schon den ganzen tag sitze ich an einem Problem und es will einfach nicht funktionieren.

Das dumme daran ist, wenn die downloads fertig sind, wird ja wie gewohnt der ProgressDialog beendet, das klappt auch, nur wenn mal die Bildschirmsperre aktiviert wurde und wieder deaktiviert, dann ist der ProgressDialog wieder geöffnet und ich muss die App wieder neu starten.
Ich finde es eifach Du** wieso onCreate wieder erneut aufgerufen wird, anstatt das es einfach ganz normal weiter geht.

Naja, ich denke ich werd das dann wohl aufgeben, hat ja keinen Sinn irgendwie meine ganze Zeit nur für ein kleines Problem zu investieren.

Trotzdem vielen Dank.

MfG


----------



## Stroker89 (18. Nov 2012)

Machs doch einfach über einen Service dann ist alles gut


----------



## bruce85 (18. Nov 2012)

Habe ich, ich hab die Seite etwas studiert und es jetzt in meiner App eingebaut, klappt alles fehlerfrei, nur downloadet er nichts, es scheint so als würde der Service überhaupt nicht starten.

Hier mal der Code wie ich den Service starte:

```
Bundle extras = new Bundle();
Groundy.execute(TestActivity.this, DownloadResolver.class, new DownloadReceiver(), extras);

mProgressDialog = new ProgressDialog(TestActivity.this);
mProgressDialog.setMessage("Video ("+downloadNr+"/"+downloadAnz+") wird heruntergeladen...");
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.setCancelable(false);
mProgressDialog.show();
```

und hier sollte die Datei heruntergeladen werden:

```
public class DownloadService extends IntentService {
    public static final int UPDATE_PROGRESS = 8344;
    public DownloadService() {
        super("DownloadService");
    }
    @Override
    protected void onHandleIntent(Intent intent) {
    	System.out.println("Test");
        ResultReceiver receiver = (ResultReceiver) intent.getParcelableExtra("receiver");
        try {
        	for (int i=0; i<TestActivity.videoAnz; i++) {
        		if (TestActivity.videos[i].download == 1) {
        			TestActivity.downloadNr = TestActivity.downloadNr + 1;
		            URL url = new URL("http://testseite.de/data/"+TestActivity.videos[i].dUrl);
		            URLConnection connection = url.openConnection();
		            connection.connect();
		            // this will be useful so that you can show a typical 0-100% progress bar
		            int fileLength = connection.getContentLength();
		
		            // download the file
		            InputStream input = new BufferedInputStream(url.openStream());
		            OutputStream output = new FileOutputStream("/sdcard/"+TestActivity.videos[i].dOrt);
		
		            byte data[] = new byte[1024];
		            long total = 0;
		            int count;
		            while ((count = input.read(data)) != -1) {
		                total += count;
		                // publishing the progress....
		                Bundle resultData = new Bundle();
		                resultData.putInt("progress" ,(int) (total * 100 / fileLength));
		                receiver.send(UPDATE_PROGRESS, resultData);
		                output.write(data, 0, count);
		            }
		            TestActivity.videos[i].download = 0;
		            output.flush();
		            output.close();
		            input.close();
        		}
        	}
        } catch (IOException e) {
            e.printStackTrace();
        }

        Bundle resultData = new Bundle();
        resultData.putInt("progress" ,100);
        receiver.send(UPDATE_PROGRESS, resultData);
    }
}
```

Der ProgressBar bleibt unverändert und der Download wird auch nicht ausgeführt.
Ich hab zum test versucht etwas in die Console auszugeben, ob überhaupt der Teil ausgeführt wird, leider kein ergebnis.

Die folgende rechte habe ich gesetzt:
[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" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application.......................................
<service android:name=".DownloadService"/>
<service android:name="com.codeslap.groundy.GroundyService"/>[/XML]

Woran könnte das Problem liegen?

*Edit:* Bei DownloadResolver meldet er eine URL Exception:

```
package com.codeslap.groundy;

import java.io.File;
import java.io.IOException;

public class DownloadResolver extends CallResolver {

    public static final String PARAM_URL = "com.groundy.sample.param.url";

    @Override
    protected void updateData() {
        try {
            File dest = new File(getContext().getFilesDir(), "downloaded_file.ext");
            String url = getParameters().getString(PARAM_URL);
            GroundyUtils.downloadFile(getContext(), url, dest, GroundyUtils.fromResolver(this));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    protected void prepareResult() {
        setResultCode(Groundy.STATUS_FINISHED);
    }
}
```

2 Sachen sind mir jetzt noch unklar:

```
PARAM_URL und downloaded_file.ext
```
Welche Url sollte ich angeben und was hat die Variable dest aufsich?

MfG


----------



## schlingel (18. Nov 2012)

> Groundy.execute(TestActivity.this, DownloadResolver.class, new DownloadReceiver(), extras);


Was verbirgt sich hinter execute?


----------



## bruce85 (18. Nov 2012)

Danke Dir.

Ich habe mein Beitrag oben editiert und erhalte jetzt eine URL Exception, das diese URL nicht gefunden werden kann.

Ich habe die Groundy library heruntergeladen und hier ist die execute vorhanden:

```
package com.codeslap.groundy;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.ResultReceiver;

public class Groundy {
    public static final String KEY_PARAMETERS = "com.codeslap.groundy.key.paramaters";
    public static final String KEY_RESULT = "com.codeslap.groundy.key.result";
    public static final String KEY_ERROR = "com.codeslap.groundy.key.error";
    public static final String KEY_RECEIVER = "com.codeslap.groundy.key.receiver";
    public static final String KEY_PROGRESS = "com.codeslap.groundy.key.progress";

    public static final int STATUS_FINISHED = 200;
    public static final int STATUS_ERROR = 232;
    public static final int STATUS_RUNNING = 224;
    public static final int STATUS_PROGRESS = 225;
    public static final int STATUS_CONNECTIVITY_FAILED = 8433;

    /**
     * Queue a call resolver to be executed
     *
     * @param context  needed to start the service
     * @param resolver call resolver implementation
     * @param receiver result receiver to report results back
     * @param extras   the application code
     */
    public static void queue(Context context, Class<? extends CallResolver> resolver, ResultReceiver receiver,
                             Bundle extras) {
        startApiService(context, receiver, resolver, extras, false);
    }

    /**
     * Execute this call resolver asynchronously
     *
     * @param context  needed to start the service
     * @param resolver call resolver implementation
     * @param receiver result receiver to report results back
     * @param extras   the application code
     */
    public static void execute(Context context, Class<? extends CallResolver> resolver, ResultReceiver receiver,
                               Bundle extras) {
        startApiService(context, receiver, resolver, extras, true);
    }

    private static void startApiService(Context context, ResultReceiver receiver,
                                        Class<? extends CallResolver> resolver, Bundle params, boolean async) {
        Intent intent = new Intent(context, GroundyService.class);
        if (async) {
            intent.putExtra(GroundyIntentService.EXTRA_ASYNC, async);
        }
        intent.setAction(resolver.getName());
        if (params != null) {
            intent.putExtra(KEY_PARAMETERS, params);
        }
        intent.putExtra(KEY_RECEIVER, receiver);
        context.startService(intent);
    }
}
```

*Edit:* Hier die fehlermeldung, die ich bekomme:

```
11-18 13:10:07.237: W/System.err(636): java.lang.RuntimeException: java.net.MalformedURLException: Protocol not found: URL
```
MfG


----------



## bruce85 (18. Nov 2012)

Das funktioniert ja jetzt, nur bekomme ich eine URL Exception beim starten des Service.


bruce85 hat gesagt.:


> Bei DownloadResolver meldet er eine URL Exception:
> 
> ```
> package com.codeslap.groundy;
> ...



Die 2 Dinge sind mir jetzt noch unklar:

```
public static final String PARAM_URL = "com.groundy.sample.param.url";
File dest = new File(getContext().getFilesDir(), "downloaded_file.ext");
```

Was muss ich dort genau angeben?
Weil die Download Url von den dateien, die ich downloaden möchte, habe ich ja im DownloadService.java drin und ich weiss nicht, was das hier aufsich hat.

Danke schonmal.

MfG


----------



## bruce85 (18. Nov 2012)

Ich hab das jetzt einigermaßen hinbekommen.

MfG


----------

