0

わかりました、私はここで本当に混乱しています。ここで、何が起こっているのかを簡単に要約します。

  1. GPD を介してユーザーの場所を取得します
  2. 最初の IF ステートメントでは、アダプターにフィードする "opzioni" と "images" を収集しますが、後でスクリプト内でデータを収集できる 3 番目の配列も必要です。

  3. データベース内の要素の座標を収集します

  4. ユーザーとデータベース要素の間の DISTANCE を返す AsyncTask を実行します。
  5. DISTANCE 値は、distance Array 内に配置され、ループが 5 回実行されます。

今私が抱えている問題は、アダプターが呼び出される前に「opzioni」と「画像」の両方が収集され、すべての AsyncTask の後にのみ距離データにアクセスできることです。

ListView を更新できません。

これがソースです

package com.example.myapp;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

import org.json.JSONException;
import org.json.JSONObject;


//import com.example.nevianoapp.NevianoMapsV2.DownloadTask;
//import com.example.nevianoapp.NevianoMapsV2.ParserTask;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.PolylineOptions;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class CategoryMenu extends Activity implements AdapterView.OnItemClickListener, LocationListener {

    ListView l;
    String[] opzioni;
    int[] images;
    String[] distance;
    String category;
    LatLng myPos;
    LatLng dest;
    String distanceAsync;
    int nextIndex = 0;
    NewAdapter adapter;
    List<List<HashMap<String, String>>> test;


    DatabaseHandler db = new DatabaseHandler(this);


    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.category_menu_layout);

         // Getting LocationManager object from System Service LOCATION_SERVICE
        LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);

        // Creating a criteria object to retrieve provider
        Criteria criteria = new Criteria();

        // Getting the name of the best provider
        String provider = locationManager.getBestProvider(criteria, true);

        // Getting Current Location From GPS
        Location location = locationManager.getLastKnownLocation(provider);

        myPos = new LatLng(location.getLatitude(), location.getLongitude());


        Toast.makeText(this, String.valueOf(location.getLatitude())+ " " + String.valueOf(location.getLongitude()), Toast.LENGTH_SHORT).show();

        //for(int x = 1; x < 6; x = x+1) {
        if(getIntent().getIntExtra("str1", 0) == 0){
            opzioni = new String[5];
            images = new int[5];
            distance = new String[5];

            for (int x = 0; x < 5; x = x+1){
            opzioni[x] = db.getCultura(x+1, "cultura").getName();
            images[x] = (R.drawable.cultura);
            dest = new LatLng(db.getCultura(x+1, "cultura").getCoordLat(), db.getCultura(x+1, "cultura").getCoordLong());

            String url = getDirectionsUrl(myPos, dest);
            DownloadTask downloadTask = new DownloadTask();
            downloadTask.execute(url);

            }
        }
        if(getIntent().getIntExtra("str1", 0) == 1){
            opzioni = new String[13];
            images = new int[13];
            for (int x = 0; x < 13; x = x+1){
            opzioni[x] = db.getCultura(x+1, "ristoranti").getName();
            images[x] = (R.drawable.ristoranti);
            }
        }
        if(getIntent().getIntExtra("str1", 0) == 2){
            opzioni = new String[17];
            images = new int[17];
            for (int x = 0; x < 17; x = x+1){
            opzioni[x] = db.getCultura(x+1, "alberghi").getName();
            images[x] = (R.drawable.itinerari);
            }
        }


        l=(ListView) findViewById(R.id.listView2);

        NewAdapter adapter = new NewAdapter(this, opzioni, images, distance);
        l.setAdapter(adapter);
        l.setOnItemClickListener(this); 




    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.category_menu, menu);
        return true;
    }

    @Override
    public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
        Intent i = new Intent(this, informazioni.class);
        category = getIntent().getStringExtra("category");
        i.putExtra("str1", arg2);
        i.putExtra("category", category);

        Toast.makeText(this, "hey " + arg2, Toast.LENGTH_SHORT).show();// TODO Auto-generated method stub

        startActivity(i);

    }

     private String getDirectionsUrl(LatLng origin,LatLng dest){

            // Origin of route
            String str_origin = "origin="+origin.latitude+","+origin.longitude;

            // Destination of route
            String str_dest = "destination="+dest.latitude+","+dest.longitude;

            // Sensor enabled
            String sensor = "sensor=false";

            // Building the parameters to the web service
            String parameters = str_origin+"&"+str_dest+"&"+sensor;

            // Output format
            String output = "json";

            // Building the url to the web service
            String url = "https://maps.googleapis.com/maps/api/directions/"+output+"?"+parameters;

            return url;
        }

        /** A method to download json data from url */
        private String downloadUrl(String strUrl) throws IOException{
            String data = "";
            InputStream iStream = null;
            HttpURLConnection urlConnection = null;
            try{
                URL url = new URL(strUrl);

                // Creating an http connection to communicate with url
                urlConnection = (HttpURLConnection) url.openConnection();

                // Connecting to url
                urlConnection.connect();

                // Reading data from url
                iStream = urlConnection.getInputStream();

                BufferedReader br = new BufferedReader(new InputStreamReader(iStream));

                StringBuffer sb  = new StringBuffer();

                String line = "";
                while( ( line = br.readLine())  != null){
                    sb.append(line);
                }

                data = sb.toString();

                br.close();

            }catch(Exception e){
                Log.d("Exception while downloading url", e.toString());
            }finally{
                iStream.close();
                urlConnection.disconnect();
            }
            return data;
        }

        /** A class to download data from Google Directions URL */
        private class DownloadTask extends AsyncTask<String, Void, String>{

            // Downloading data in non-ui thread
            @Override
            protected String doInBackground(String... url) {

                // For storing data from web service
                String data = "";

                try{
                    // Fetching the data from web service
                    data = downloadUrl(url[0]);
                }catch(Exception e){
                    Log.d("Background Task",e.toString());
                }
                return data;
            }

            @Override
            protected void onPostExecute(String result) {
                super.onPostExecute(result);

                ParserTask parserTask = new ParserTask();

                // Invokes the thread for parsing the JSON data
                parserTask.execute(result);
            }
            // Executes in UI thread, after the execution of
            // doInBackground()

}

        private class ParserTask extends AsyncTask<String, Integer, List<List<HashMap<String,String>>> >{




            // Parsing the data in non-ui thread
            @Override
            protected List<List<HashMap<String, String>>> doInBackground(String... jsonData) {

                JSONObject jObject;
                List<List<HashMap<String, String>>> routes = null;

                try{
                    jObject = new JSONObject(jsonData[0]);
                    DirectionsJSONParser parser = new DirectionsJSONParser();

                    // Starts parsing data
                    routes = parser.parse(jObject);
                }catch(Exception e){
                    e.printStackTrace();
                }
                return routes;
            }

            // Executes in UI thread, after the parsing process
            @Override
            protected void onPostExecute(List<List<HashMap<String, String>>> result) {
                List<HashMap<String, String>> path = result.get(0);
                HashMap<String, String> point = path.get(0);


                        distanceAsync = point.get("distance");
                        distance[nextIndex] = distanceAsync;
                        ++nextIndex;
                        test.clear();
                        test.addAll(result);
                        adapter.notifyDataSetChanged();
            }
        }

class NewAdapter extends ArrayAdapter<String>{
    Context context;
    int[] images;
    String[] title;
    String[] subTitle;

    NewAdapter(Context c, String[] opzioni, int[] imgs, String[] distanza){
        super(c, R.layout.single_row, R.id.descrizione, opzioni);
        this.context = c;
        this.images = imgs;
        this.title = opzioni;
        this.subTitle = distanza;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent){
        LayoutInflater inflater=(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View row = inflater.inflate(R.layout.single_row, parent, false);

        ImageView myImage = (ImageView) row.findViewById(R.id.imageView);
        TextView myOptions = (TextView) row.findViewById(R.id.descrizione);
        TextView mySubTitle = (TextView) row.findViewById(R.id.subTitle);

        myImage.setImageResource(images[position]);
        myOptions.setText(title[position]);
        mySubTitle.setText(subTitle[position]);


        return row;
    }




}

@Override
public void onLocationChanged(Location arg0) {
    // TODO Auto-generated method stub

}


}

そしてこれがログです

10-15 17:40:47.677: E/AndroidRuntime(5237): FATAL EXCEPTION: main
10-15 17:40:47.677: E/AndroidRuntime(5237): java.lang.NullPointerException
10-15 17:40:47.677: E/AndroidRuntime(5237):     at com.example.nevianoapp.CategoryMenu$ParserTask.onPostExecute(CategoryMenu.java:298)
10-15 17:40:47.677: E/AndroidRuntime(5237):     at com.example.nevianoapp.CategoryMenu$ParserTask.onPostExecute(CategoryMenu.java:1)
10-15 17:40:47.677: E/AndroidRuntime(5237):     at android.os.AsyncTask.finish(AsyncTask.java:631)
10-15 17:40:47.677: E/AndroidRuntime(5237):     at android.os.AsyncTask.access$600(AsyncTask.java:177)
10-15 17:40:47.677: E/AndroidRuntime(5237):     at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
10-15 17:40:47.677: E/AndroidRuntime(5237):     at android.os.Handler.dispatchMessage(Handler.java:99)
10-15 17:40:47.677: E/AndroidRuntime(5237):     at android.os.Looper.loop(Looper.java:137)
10-15 17:40:47.677: E/AndroidRuntime(5237):     at android.app.ActivityThread.main(ActivityThread.java:5103)
10-15 17:40:47.677: E/AndroidRuntime(5237):     at java.lang.reflect.Method.invokeNative(Native Method)
10-15 17:40:47.677: E/AndroidRuntime(5237):     at java.lang.reflect.Method.invoke(Method.java:525)
10-15 17:40:47.677: E/AndroidRuntime(5237):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
10-15 17:40:47.677: E/AndroidRuntime(5237):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
10-15 17:40:47.677: E/AndroidRuntime(5237):     at dalvik.system.NativeStart.main(Native Method)

誰かが同じ問題を抱えていましたか?私は本当に苦労しています

ありがとうございました

4

3 に答える 3

0

この問題を解決できるかどうかわかりません。とにかく、今日私はあなたが望むことをする方法を見つけました.

  1. まず、Activity をパラメーターとして受け取る AsyncTask にコンストラクター メソッドを作成する必要があります。このコンストラクターでは、受け取ったアクティビティでコンテキストを設定します。
  2. AsyncTask を呼び出すアクティビティで、ビュー内のデータを更新するパブリック メソッドを作成します。
  3. AsyncTask クラスには、AsyncTask を呼び出すすべてのアクティビティの特定のインスタンスが必要です (ただし、すべてを初期化する必要はありません)。
  4. doInBackground() メソッドでは、実行後に使用するデータでオブジェクトを初期化する必要があります。
  5. onPostExecute() メソッドでは、タスクを呼び出したアクティビティを確認し、新しいデータをビューに設定する必要があります。

見る:

public class AnyActivity extends Activity {
    TextView txView;

    //onCreate...
    //onPause...
    //onResume...

    public updateData(Object object) {
    //update the data in the UI
    }
}


public class WSCallSoap extends AsyncTask<Object, Integer, Boolean> {

    AnyActivity anyActivity;
    Activity activity;
    DataModelClass dmc;
    private ProgressDialog dialog = null;

    public WSCallSoap (Activity activity){
        this.activity = activity;
        Context context = activity;
        dialog = new ProgressDialog(context);
    }

    public void onPreExecute(){
        this.dialog.setMessage("Sending");
        this.dialog.show();
    }

    public boolean doInBackground(Object... params){
        dmc = ... //initialize the object and do wherever you need
    }

    public void onPostExecute(boolean success) {

        if (dialog.isShowing()) {
            dialog.dismiss();
        }

        if (activity.class == AnyActivity.class) {
            anyActivity.updateData(dmc);
        }
    }

}
于 2013-10-18T23:37:19.087 に答える
0

現在、ParserTaskクラスで次の問題があります。

1.test clear を呼び出すかリストに要素を追加する前に Listを初期化するのを忘れる

2.adapter内部に同じ名前のアダプタの別のインスタンスを作成しているため、 初期化されていないインスタンスを使用していonCreateます。

adapter = new NewAdapter(this, opzioni, images, distance); //<<
l.setAdapter(adapter);
l.setOnItemClickListener(this);
于 2013-10-15T16:56:53.340 に答える
0

@Michael Corleone、数日前に同様の問題がありました。問題は、AsyncTask を呼び出すときに、メイン コードがまだ実行されていることです。

これを「解決」するために、私は通常、2 つのアクティビティと AsyncTask クラスを使用します。

したがって、私の最初のアクティビティは startActivityForResult() を呼び出します。

2 番目のアクティビティは、ProgressDialog とその他のデータを AsyncTask に送信します。次に、doInBackground() の実行後に onPostExecute() が呼び出され、ProgressDialog を閉じて、2 番目のアクティビティの RESULT を「OK」または「CANCELED」に設定します。どちらの場合も、ProgressDialog を閉じて、2 番目のアクティビティを終了します。

最初のアクティビティは 2 番目の結果を受け取り、必要な場所で実行します。お役に立てば幸いです。

于 2013-10-15T17:02:03.123 に答える