ZduneX25

Programowanie

Recommended Posts

Ktoś coś działa w tym kierunku, ja natrafiłem na małe schody i nie wiem jak je obejść.

 

Kod sprawdzający czy plik istnieje na serwerze zawsze wyrzuca false, a jeżeli skompiluję to w apkę ze starym API (gingerbread) to działa jak powinno. Mam problem z przepisaniem tego kodu by działał na API z kitkata..

 

Dodam, że było ok do czasu kiedy dopisałem sprawdzanie czy plik istnieje przed jego pobraniem, bez sprawdzania działało i na nowszym API.

 

 

 

private void startDownload() {

    String version = Build.USER;

    String device = Build.DEVICE;

        String url = String.format(getResources().getString(R.string.url_down), version, device);

        new DownloadFileAsync().execute(url);

    }

 

I dodałem kod na sprawdzania czy plik istnieje przed pobraniem:

 

private void startDownload() {

    String version = Build.USER;

    String device = Build.DEVICE;

        String url = String.format(getResources().getString(R.string.url_down), version, device);

        boolean bResponse = exists(url);

        if (bResponse==true)

        {

            Toast.makeText(AndroidDownloadFileByProgressBarActivity.this, "Dostępna nowa wersja, pobieranie..." , Toast.LENGTH_SHORT).show();

            new DownloadFileAsync().execute(url);

        }

        else

            Toast.makeText(AndroidDownloadFileByProgressBarActivity.this, "Masz najnowszą dostępną wersję!", Toast.LENGTH_SHORT).show();

        

    }

 

public static boolean exists(String url){

        try {

          HttpURLConnection.setFollowRedirects(false);

          // note : you may also need

          //HttpURLConnection.setInstanceFollowRedirects(false)

 

          HttpURLConnection con =  (HttpURLConnection) new URL(url).openConnection();

          con.setRequestMethod("HEAD");

          return (con.getResponseCode() == HttpURLConnection.HTTP_OK);

         }

        catch (Exception e) {

           e.printStackTrace();

           return false;

        }

      }

 

Log jest taki NetworkOnMainThreadException - Pastebin.com

  • Like 1

Share this post


Link to post
Share on other sites

Mógłbyś pokazać jak wygląda kod po zmianach? Ja osobiście wrzuciłbym do osobnego wątku tylko ten fragment

boolean bResponse = exists(url);
if (bResponse==true)
{
    Toast.makeText(AndroidDownloadFileByProgressBarActivity.this, "Dostępna nowa wersja, pobieranie..." , Toast.LENGTH_SHORT).show();
    new DownloadFileAsync().execute(url);
}
else
    Toast.makeText(AndroidDownloadFileByProgressBarActivity.this, "Masz najnowszą dostępną wersję!", Toast.LENGTH_SHORT).show();

Share this post


Link to post
Share on other sites

Początkowo wrzuciłem własnie to co zacytowałeś, ale wtedy jedno nie potrafiło odnaleźć exists, drugie url, wiec dałem new Thread na całe private void startDownload() i public static boolean exists(String url), wtedy było już ok, skompilowałem i jak klikam Pobierz to 0 reakcji, a w logu tylko informacyjna linijka, że coś kliknąłem, ale jakby przycisk bez funkcji.

post-1167-0-55611600-1417340218_thumb.pn

Share this post


Link to post
Share on other sites

Dodałem i tak jak na początku kiedy brałem wszystko w new Thread - 0 reakcji na pobierz. Log czysty.
 

private void startDownload() {
    	String version = Build.USER;
    	String device = Build.DEVICE;
        final String url = String.format(getResources().getString(R.string.url_down), version, device);
        Thread thread = new Thread(new Runnable(){
            @Override
            public void run() {
                try {
                	boolean bResponse = exists(url);
                    if (bResponse==true)
                    {
                        Toast.makeText(AndroidDownloadFileByProgressBarActivity.this, "Dostępna nowa wersja, pobieranie..." , Toast.LENGTH_SHORT).show();
                        new DownloadFileAsync().execute(url);
                    }
                    else
                        Toast.makeText(AndroidDownloadFileByProgressBarActivity.this, "Masz najnowszą dostępną wersję!", Toast.LENGTH_SHORT).show();
                    
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });

        thread.start(); 
        
    }

EDIT:

Dobra mam, wystarczyło w onCreate dodać:

      StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
              .permitAll().build();
      StrictMode.setThreadPolicy(policy);
 
      startDownload();

Share this post


Link to post
Share on other sites

Mam taką zmienną:

String device = Build.DEVICE;

chciałbym do niej dopisać coś takiego:

if (device == "cancro") {
     device = "MI4-MI3W";
     }

Chodzi o to, żeby do linku url w przypadku cancro pobierał plik mający z nazwie MI4-MI3W, jak to ogarnąć?

Share this post


Link to post
Share on other sites

Dzięki zrobione:

 

String device = Build.DEVICE;
     if (device.equalsIgnoreCase("cancro")) {
        device = "MI4-MI3W";
     }
     else if (device.equalsIgnoreCase("aries")) {
     device = "MI2";
  }
     else if (device.equalsIgnoreCase("dior")) {
      device = "NOTE_LTEW";
   }

Share this post


Link to post
Share on other sites

Mam takie coś:

final Dialog dialog = new Dialog(this,
                R.style.Theme_Light_Dialog);
        dialog.setTitle(R.string.job_done);
        dialog.setContentView(R.layout.dialog_done);
potem:

<style name="Theme.Light.Dialog" parent="@android:style/Theme.DeviceDefault.Light.Dialog">
        <item name="android:windowTitleStyle">@style/Widget.DialogTitle</item>
</style>
<style name="Widget.DialogTitle" parent="@android:style/Widget">
        <item name="android:gravity">center</item>
        <item name="android:textSize">14.5sp</item>
        <item name="android:textStyle">bold</item>
        <item name="android:textColor">#cc000000</item>
</style>
czyli ustawiłem własny styl na tytuł okienka i działa kolor, rozmiar, styl, ale wyśrodkowanie nie chce w żadnej sposób ruszyć (non-stop napis po lewej), jakieś pomysły?

Share this post


Link to post
Share on other sites

title nie jest w textview ;) takie coś to można w plikach xml w /layout, chociaż powinno też i działać w stylach, ale nie działa i tu problem..

Share this post


Link to post
Share on other sites

Tak, to wiem, tylko gdzieś czytałem, że samo gravity działa tylko w textView, a w tym linku było podane, że może pomóc linijka z:

android:textAlignment="gravity"

Share this post


Link to post
Share on other sites

Tylko taką opcje to ja mogę dopisać do xml w layout, a ja muszę to zrobić na pliku styles, bo tytułu nie ustawiasz w xml tylko jawą przez dialog.setTitle(R.string.job_done);

EDIT:

Dobra dodałem: dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); i ustawiłem sobie w dialog.setContentView(R.layout.dialog_done); tytuł jako textview..

Share this post


Link to post
Share on other sites

A może "start|center"? Kiedyś coś takiego dałem do styles.

Wysłane z MI4

Share this post


Link to post
Share on other sites

Miałem jeszcze problem, bo czytał mi niebieską linijkę w tym title i jak przeniosłem to do layout to jest idealnie (załącznik).

post-1167-0-09417100-1417960217_thumb.pn

Share this post


Link to post
Share on other sites

Mam jeszcze problem ze stylem dialogu podczas pobierania plików:

 

mProgressDialog = new ProgressDialog(this,android.R.style.Theme_Holo_Dialog);
chodzi o to, że chciałbym użyć styl bezpośrednio z frameworku com.miui.sdk (miui.apk), jest to możliwe w eclipse (na smali potrafię to zrobić tylko nie jest to wygodne przy robieniu swojej apki)?

Share this post


Link to post
Share on other sites

@SmallCutePenguin
 

próbuję zrobić mechanizm aktualizacji, który porówna versionCode z mojej (uruchomionej) aplikacji z versionCode z pliku na serwerze http://91.205.75.29//zdunex25/wip/test.txt i w momencie kiedy wersja na serwerze będzie nowsza > to uruchomi się jakaś tam akcja, zdeklarować wersję było banalnie łatwo, gorzej z newVersion (z serwera)

PackageManager manager = this.getPackageManager();
PackageInfo test = null;
        try {
            test = manager.getPackageInfo(this.getPackageName(), 0);
        } catch (NameNotFoundException e1) {
            e1.printStackTrace();
        }
if (newVersion > test.versionCode ) {
/* Post a Handler for the UI to pick up and open the Dialog */
    Toast.makeText(PrimaryActivity.this, "Nowa wersja", Toast.LENGTH_SHORT).show();
} 

nie jestem żadnym znawcą dlatego proszę o jakiś prosty przykład

 

 

próbowałem tego, ale bez efektu: http://csnipp.com/s/226/-Check-for-Updates-Once-a-Day

Share this post


Link to post
Share on other sites

Kod jest dobry. Problem występuje po stronie pliku test.txt. Sprawdź w jakim kodowaniu go zapisałeś bo parser nie jest w stanie sparsować stringa "1" na liczbę. Jeśli w tym samym kodzie odwołam się do serwera wklej.org to kod zadziała poprawnie.

import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Handler;
import android.os.Looper;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
import android.widget.Toast;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;


public class MainActivity extends ActionBarActivity {

    private TextView hello;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        hello = (TextView) findViewById(R.id.hello_world);

        new Thread(new Runnable() {
            @Override
            public void run() {
                final int versionFromServer = checkVersionOnServer();
                final int localVersion = getAppVersion();

                final String message;
                if (versionFromServer > localVersion) {
                    message = "New version is available!";
                } else {
                    message = "You are using the newest version.";
                }

                new Handler(Looper.getMainLooper())
                        .post(new Runnable() {
                            @Override
                            public void run() {
                                hello.setText(String.format("Local version: %d | Server version: %d",
                                        localVersion, versionFromServer));
                                Toast.makeText(MainActivity.this, message, Toast.LENGTH_SHORT)
                                        .show();
                            }
                        });
            }
        }).start();
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        return super.onOptionsItemSelected(item);
    }

    private int checkVersionOnServer()
    {
        int version = -1;
        URLConnection connection;
        BufferedReader bufferedInputStream;

        try {
            //URL url = new URL("http://91.205.75.29//zdunex25/wip/test.txt");
            URL url = new URL("http://wklej.org/hash/72c3e6287be/txt/");
            connection = url.openConnection();
            bufferedInputStream = new BufferedReader(
                    new InputStreamReader(connection.getInputStream(), "UTF-8")
            );

            String input = bufferedInputStream.readLine().trim();
            // Log.d("VERSION", String.format("{%s}", input));
            version = Integer.parseInt(input);

            bufferedInputStream.close();
        } catch (Throwable t) {
            t.printStackTrace();
        }

        return version;
    }

    private int getAppVersion()
    {
        PackageManager manager = this.getPackageManager();
        PackageInfo packageInfo = null;
        try {
            packageInfo = manager.getPackageInfo(this.getPackageName(), 0);
        } catch (PackageManager.NameNotFoundException e1) {
            e1.printStackTrace();
        }
        return packageInfo.versionCode;
    }
}
  • Like 1

Share this post


Link to post
Share on other sites

Korzystałem z domyślnie wygenerowanego projektu w Android Studio i miałem tam kontrolkę TextView z id hello_world. Ty jej pewnie nie masz i dlatego dostajesz NullPointerException.

Share this post


Link to post
Share on other sites

Faktycznie nie przypisałem id to textview :oops: . Super, działa, a co do mojego pliku to próbowałem ANSI i UTF-8, teraz jest w UTF-8.

Share this post


Link to post
Share on other sites

@SmallCutePenguin wrzuciłem plik na 3 różne serwery (sprawdziłem wszystkie kodowania) z żadnego nie chce odczytać wersji, jak zrobiłem małe zmiany:

try {
            URL url = new URL("http://91.205.75.29//zdunex25/wip/version.txt");

            BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
            String input;
            while ((input = in.readLine().trim()) != null) {
            	version = Integer.parseInt(input);	
            }
            in.close();
        }

to czyta z wklej.org dobrze (jak i poprzednio), a z mojego dalej nie radzi sobie z numerkiem:

06-11 18:00:40.149: E/AndroidRuntime(29837): java.lang.NumberFormatException: Invalid int: "2"

tylko nie wiem czy to 'dobry' znak, że widzi te 2 z version.txt, a nie potrafi go wczytać..

 

 

EDIT:

 

nie wiem czy to trim() szwankuje czy co, bo zamieniłem go na .substring(0,1) i wtedy wywala "", a jak daję .substring(0,2) to wywala "2" czyli jakby coś było przed numerem

Share this post


Link to post
Share on other sites

Oczywiście, że tam coś jest ponieważ ściągasz cały plik (razem z jakimiś jego metadanymi) a nie samą jego zawartość.

Dodaj sobie taką funkcję

private String removeUnsupportedCharacters(String input) {
    StringBuilder builder = new StringBuilder();
    for (int i = 0; i < input.length(); ++i) {
        if (Character.isDigit(input.charAt(i))) {
            builder.append(input.charAt(i));
        } else {
            Log.e("FORMAT_ERROR", String.format("Unsupported character! '%s'", input.charAt(i)));
        }
    }
    return builder.toString();
}

I użyj jej w ten sposób

version = Integer.parseInt(removeUnsupportedCharacters(input));

Dzięki temu w stringu zostaną tylko te znaki, które są cyfrą.

  • Like 1

Share this post


Link to post
Share on other sites

Właśnie trafiłem w sieci na charAt szukając rozwiązania, dzięki wielkie za pomoc.


Jeszcze ostatnia rzecz, jak przenoszę:

<TextView android:id="@+id/hello_world"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_margin="15dp"
        android:gravity="center_horizontal" />

main.xml do dialog_update.xml i wali znowu nullpointerexception jakby wcale nie było użyte to id  :???:

Share this post


Link to post
Share on other sites

A używasz findViewById w kontekście dialog_update.xml czy main.xml?

PS. Zamiast fill_parent używaj match_parent, to w sumie to samo ale fill_parent jest oznaczony jako przestarzały i może zostać usunięty w przyszłych wersjach Androida.

Share this post


Link to post
Share on other sites

dialog_update.xml, bo do main.xml przypisałem tylko na początku by to przetestować.

 

EDIT:

 

wyczytałem gdzieś, że musi być nad dialog.setContentView(R.layout.dialog_update); i tak dałem, a to był błąd, dałem pod i śmiga

Share this post


Link to post
Share on other sites

@SmallCutePenguin nowy problem, chcę zapisać ilość kliknięć przycisku do pliku tekstowego na telefonie, ale póki co testuję sam licznik uruchomień całej apki:

private SharedPreferences prefs;
private SharedPreferences.Editor editor;
private int totalCount;
prefs = getPreferences(Context.MODE_PRIVATE);
editor = prefs.edit();
totalCount = prefs.getInt("counter", 0);
totalCount++;
editor.putInt("counter", totalCount);
editor.commit();
int count = totalCount;
String string = count + "";
writeToFile(string);
private void writeToFile(String data) {
        try {
            OutputStreamWriter outputStreamWriter = new OutputStreamWriter(openFileOutput("counter.txt", Context.MODE_APPEND));
            outputStreamWriter.write(data);
            outputStreamWriter.close();
        }
        catch (IOException e) {
            Log.e("Exception", "File write failed: " + e.toString());
        } 
    }
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

problem w tym, że log czysty, a plik się nie zapisuje 

Share this post


Link to post
Share on other sites

Funkcja openFileOutput zapisuje plik w /data/data/com.twoja.aplikacja/files. Ponadto nie wymaga żadnych dodatkowych uprawnień.

Jeśli chcesz zapisać coś na zewnętrznej pamięci to tu powinieneś znaleźć więcej informacji http://developer.android.com/training/basics/data-storage/files.html#WriteExternalStorage

  • Like 1

Share this post


Link to post
Share on other sites
Guest
This topic is now closed to further replies.