0

我正在构建一个与商店有关的客户端服务器 android 应用程序 ,我希望(当用户接近 2 或 3 家商店且他们的数据库在线时)我的应用程序了解他可以连接到其中一个商店的数据库和将它们列在屏幕上。(当我们想要连接到互联网时,可用的 wifi 会发生什么)

我怎样才能做到这一点?
我希望我清楚我在寻找什么。

4

1 回答 1

0

如我错了请纠正我。您正在编写一个可以从服务器/数据库属于商店的服务器访问数据的应用程序?

如果我对您的问题的理解是正确的,请执行以下操作:

  • 创建一个监听连接变化的连接广播
  • 创建一个 GPS 管理器,将当前位置与基于商店位置的位置进行比较
  • 如果在一个或多个商店的范围内并且有可用的连接,请通过 restfull 请求查询服务器,在服务器端,触发查询,查看是否得到任何结果(我不知道是否存在特定查询检查从服务器端代码到数据库的数据库连接)如果得到结果,则表明数据库可用,将结果从服务器发送回客户端,并将数据库/存储列为可用。

我个人会使用 JSON 来处理来自客户端 <-> 服务器的请求。因为它重量轻且易于使用。

编写广播员:BraodcastReciever

例子:

private Context _context;
private State _state;
private boolean _listening;
private String _reason;
private boolean _isFailOver;

private NetworkInfo _networkInfo;

private NetworkInfo _otherNetworkInfo;
private ConnectivityBroadcastReceiver _receiver;
/**
 * The broadcast that listens to connectivity changes(wifi, mobile network etc)
 * */
private class ConnectivityBroadcastReceiver extends BroadcastReceiver {
    /**
     * Called when connectivity state changes
     * 
     * @param Context the context
     * @param Intent the intent containing the information about the change
     * */
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();

        if(!action.equals(ConnectivityManager.CONNECTIVITY_ACTION) || _listening == false) {
            Log.w(TAG, "onReceived() called with " + _state.toString() + " and " + intent);
            return;
        }

        boolean noConnectivity = intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);

        //Set the state according to current connectivity.
        if(noConnectivity) {
            _state = State.NOT_CONNECTED;
        } else {
            _state = State.CONNECTED;
        }

        //If current state is CONNECTED. Start background services, otherwise stop services.
        switch(_state) {
        case CONNECTED:
            //Do stuff when connected
            break;
        case NOT_CONNECTED:
            //Do stuff if not connected
            break;
        }

        _networkInfo = (NetworkInfo)intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
        _otherNetworkInfo = (NetworkInfo)intent.getParcelableExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO);

        _reason = intent.getStringExtra(ConnectivityManager.EXTRA_REASON);
        _isFailOver = intent.getBooleanExtra(ConnectivityManager.EXTRA_IS_FAILOVER, false);

        Log.d(TAG, "onRecieve(): _networkInfo= " + _networkInfo + " _otherNetworkInfo= " + (_otherNetworkInfo == null ? "[none]" : _otherNetworkInfo + 
                " noConn= " + noConnectivity) + " _state= " + _state.toString());
    }
};

我没有发布整个代码。我围绕 ConnectivityBroadcastReceiver 编写了一个包装器。但是使用给定的代码,您应该能够走得足够远。请注意,代码中的 State 是一个包含 3 个值的枚举:CONNECTED、NOT_CONNECTED、UNKNOWN

至于 GPS 管理器:

    /**
 * <h1>GPSManager</h1>
 * 
 * <p>
 * Manager for GPS tracking.
 * Able to enable and disable GPS tracking for the application.
 * </p>
 * */
public class GPSManager {
    public static final String TAG = "LocationFinder";
    private double _lat;
    private double _lon;
    private float _accuracy;
    private Context _context;
    private LocationManager _locManager;
    private LocationListener _locListener;

    private static GPSManager _instance;

    /**
     * Constructor.
     * 
     * @param context The context of the caller.
     * */
    private GPSManager(Context context) {
        this._context = context;
        this._locListener = new LocationTracker();
    }

    /**
     * GPSManager is singleton. Retrieve the shared instance.
     * 
     * @param context The context of the caller.
     * @return GPSManager An instance of the GPSManager class.
     * */
    public static synchronized GPSManager getInstance(Context context) {
        if(_instance == null) {
            _instance = new GPSManager(context);
        }
        return _instance;
    }

    /**
     * Start tracking GPS locations.
     * */
    public void startGpsTracking() {
        _locManager = (LocationManager)_context.getSystemService(Context.LOCATION_SERVICE);
        _locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 
                0, 0, _locListener);
    }

    /**
     * Stop tracking GPS locations.
     * */
    public void stopGpsTracking() {
        _locManager.removeUpdates(_locListener);
        _locManager = null;
    }

    /**
     * Retrieve the latitude from the GPSManager.
     * 
     * @return double The latitude.
     * */
    public double getLatitude() {
        return _lat;
    }

    /**
     * Retrieve the longitude from the GPSManager.
     * 
     * @return double The longitude.
     * */
    public double getLongitude() {
        return _lon;
    }

    /**
     * Check if the GPSManager has a fix on a location.
     * 
     * @return boolean True if GPSManager has a fix, otherwise false.
     * */
    public boolean hasFix() {
        if(_lat != 0 && _lon != 0)
            return true;
        else
            return false;
    }

    /**
     * Retrieve the accuracy of the fix.
     * 
     * @return float The accuracy.
     * */
    public float getAccuracy() {
        return _accuracy;
    }

    /**
     * Retrieve the last known location.
     * 
     * @return Location The last known location.
     * */
    public Location getLastLocation() {
        return _locManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
    }

    /**
     * <h1>LocationTracker</h1>
     * 
     * <p>Tracks the location for the GPSManager.</p>
     * */
    private class LocationTracker implements LocationListener {
        /** (non-Javadoc)
         * @see android.location.LocationListener#onLocationChanged(android.location.Location)
         */
        @Override
        public void onLocationChanged(Location location) {      
            _lat = location.getLatitude();
            _lon = location.getLongitude();
            _accuracy = location.getAccuracy();
        }

        /** (non-Javadoc)
         * @see android.location.LocationListener#onProviderDisabled(java.lang.String)
         */
        @Override
        public void onProviderDisabled(String provider) {
            Log.d(TAG, "Gps Disabled");     
        }

        /** (non-Javadoc)
         * @see android.location.LocationListener#onProviderEnabled(java.lang.String)
         */
        @Override
        public void onProviderEnabled(String provider) {
            Log.d(TAG, "Gps Enabled");  
        }

        /** (non-Javadoc)
         * @see android.location.LocationListener#onStatusChanged(java.lang.String, int, android.os.Bundle)
         */
        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {};
    };
}

根据您自己的需要扩展它。gps 管理器中的大多数代码都是不言自明的。

而对于其余的东西,有很多不同的方法,你必须自己查一下。

作为对您评论的回答,我将向您展示我对 webrequest 的实现。我个人使用 apache-mime4j-0.6.jar 和 httpmime-4.0.1.jar。

WebService _service = new WebService();
    @Override
    protected String doInBackground(String... arg0) {
        try {
            MultipartEntity multipart = new MultipartEntity();
            multipart.addPart("username", new StringBody(_inputName));
            multipart.addPart("password", new StringBody(_inputPass));

            _service.post(QfConfig.RESTFUL_LOGIN_URL, multipart);

            long response = _service.getLongResponse();

            if(response != 0) {
                _pgUserId = response;
                _onlineValidated = true;
            }
        } catch(Exception e) {
            e.printStackTrace();
        }
        return null;
    }

我不知道您是要 POST 还是 GET。上面的示例使用 POST。我创建了一个 MultipartEntity,并向其中添加了 2 个部分。多部分将作为 POST 值的名称为 username 的表单发送到服务器,名称为 username 的帖子的 VALUE 为 new StringBody(_inputName)。

对于我的 WebService 类中的帖子部分:

public void post(String url, MultipartEntity postData) {
    HttpClient client = null;
    HttpPost post = null;
    HttpResponse httpResponse = null;
    HttpEntity entity = null;
    InputStream _inStream = null;

    try {
        client = new DefaultHttpClient();
        post = new HttpPost();
        URI uri = URI.create(url);
        post.setURI(uri);
        post.setEntity(postData);
        //Execute the HttpPost request and store the response in httpResponse.
        httpResponse = client.execute(post);
        //Set the response code from the request's responst.
        setResponseCode(httpResponse.getStatusLine().getStatusCode());
        //Retrieve the entity from the response.
        entity = httpResponse.getEntity();

        if(entity != null) {
            //Retrieve the content from the entity.
            _inStream = entity.getContent();
            //Convert the InputStream to String and set the String response to the returned value.
            setStringResponse(IOUtility.convertStreamToString(_inStream));
            //Close the InputStream.
            Log.d(TAG, getStringResponse());
        }   

        //try to create a numeric value of the response result and store it if so
        if(GeneralUtil.isNumeric(getStringResponse())) {
            setLongResponse(Long.parseLong(getStringResponse()));
        }

        Log.d(TAG, httpResponse.getStatusLine().getReasonPhrase());
    } catch(Exception e) {
        e.printStackTrace();
        setResponseCode(0);
        setLongResponse(0);
        setStringResponse("");
    } finally {
        try {
            _inStream.close();
        } catch (Exception ignore) {}
    }
}

我通过 https 工作,这更复杂,所以我把这些东西排除在外。我在这里所做的是,创建一个新的 httpClient 和 HttpPost,设置 URI(如果是 post),将多部分数据添加到 post.setEntity() 然后执行请求并将响应保存在 HttpResponse 对象中。

然后,我检索实体并将其保存为 HttpEntity,以了解从何处获取响应内容。可以是 JSON 字符串、数字,基本上可以是任何你想要的。然后我设置了一些方法来帮助我通过 getter 和 setter 轻松检索结果。

对于 HttpGet 更简单,您只需要传递一个 url ,而不是 HttpPost 对象,您创建一个 HttpGet 对象,将 url 传递给它, _client.execute([HttpGet object]) 并以相同的方式检索结果。

在 php 脚本中,您可以直接使用 $_POST['username'] 这将给出您在上面代码中的 StringBody 中设置的用户名值。

使用 get,我建议发送一个 url(带或不带参数,然后将 JSON 字符串作为结果发送回 get 请求。

如果您需要更多帮助,请告诉我。我认为这是我能做到的。我无法显示 php 方面,因为我使用的是自行设计的框架。

于 2012-05-18T09:56:46.107 回答