调试Android服务

时间:2017-05-24 19:26:39

标签: android debugging

我试图在Android中调试服务。 我已将行Debug.waitForDebugger();放在此方法中:

@Override
protected void onHandleIntent(Intent intent)
{
    Debug.waitForDebugger();
    Utilities.displayAlertDialog("on handle intent", this);

    SharedPreferences sp = getSharedPreferences(getString(clyky.cartracker.R.string.sharedPreferencesName), Context.MODE_PRIVATE);
    int userID = sp.getInt("id_user", SplashActivity.DEFAULT_USER_ID);

    if (userID != SplashActivity.DEFAULT_USER_ID)
    {
        sendRequest(userID);
    }
    else
    {
        stopSelf();
    }
}

我在第2行(Utilities.displayAlertDialog("on handle intent", this);)放置了一个断点,但是从未到达此断点。 我正在设备上调试我的应用,而且我正在使用Android Studio。

修改

这是我的整个服务类。它从数据库中检索一些信息,并将所有信息放入ArrayList

public class RetrieveVehicleListService extends IntentService
{
    private static final int NOTIFICATION_ID = 1;
    private NotificationManager mNotificationManager;
    private NotificationCompat.Builder builder;
    private ArrayList<Vehicle> vehicles;

    private void parseVehiclesFromMap(ArrayList vehicles)
    {
        for (int i = 0; i < vehicles.size(); i++)
        {
            final Vehicle v = new Vehicle();
            HashMap vehicleMap = (HashMap) vehicles.get(i);

            v.setPlate(vehicleMap.get("plate").toString());
            v.setKm(vehicleMap.get("km") == null ? null : Integer.parseInt(vehicleMap.get("km").toString()));
            v.setFuelQuantity(Double.parseDouble(vehicleMap.get("fuel_quantity").toString()));
            v.setEffectiveFuelEconomy(Double.parseDouble(vehicleMap.get("fuel_economy").toString()));
            v.setInsuranceDate(vehicleMap.get("insurance_date") == null ? null : new LocalDate(vehicleMap.get("insurance_date").toString()));
            v.setMatriculationDate(new LocalDate(vehicleMap.get("matriculation_date").toString()));
            v.setLatitude(vehicleMap.get("latitude") == null ? null : Double.parseDouble(vehicleMap.get("latitude").toString()));
            v.setLongitude(vehicleMap.get("longitude") == null ? null : Double.parseDouble(vehicleMap.get("longitude").toString()));
            v.setFuelType(FuelType.fromInt(Integer.parseInt(vehicleMap.get("id_fuel").toString())));

            this.vehicles.add(v);
        }
    }

    private void sendRequest(int userID)
    {
        Response.Listener<String> listener = new Response.Listener<String>()
        {
            @Override
            public void onResponse(String response)
            {
                try
                {
                    HashMap json = new ObjectMapper().readValue(response, HashMap.class);
                    String errorCode = json.get("error_code").toString();

                    switch (errorCode)
                    {
                        case "0":
                            parseVehiclesFromMap((ArrayList) json.get("vehicles"));
                            break;
                        default:
                            // TODO gestire
                            break;
                    }
                }
                catch (IOException e)
                {
                    // TODO gestire
                    e.printStackTrace();
                }
            }
        };

        VehicleListRequest request = new VehicleListRequest(String.valueOf(userID), listener, null);
        RequestQueue queue = Volley.newRequestQueue(this);
        queue.add(request);
    }

    @Override
    protected void onHandleIntent(Intent intent)
    {
        Debug.waitForDebugger();
        Utilities.displayAlertDialog("on handle intent", this);

        SharedPreferences sp = getSharedPreferences(getString(clyky.cartracker.R.string.sharedPreferencesName), Context.MODE_PRIVATE);
        int userID = sp.getInt("id_user", SplashActivity.DEFAULT_USER_ID);

        if (userID != SplashActivity.DEFAULT_USER_ID)
        {
            sendRequest(userID);
        }
        else
        {
            stopSelf();
        }
    }

    public RetrieveVehicleListService()
    {
        super("RetrieveVehicleList");
        vehicles = new ArrayList<>();
    }
}

这是我的BroadcastReceiver,在互联网连接可用时运行我的RetrieveVehiclesListService

public class NetworkWatcher extends BroadcastReceiver
{
    @Override
    public void onReceive(Context context, Intent intent)
    {
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo info = cm.getActiveNetworkInfo();
        Intent retrieveVehicleList = new Intent(context, RetrieveVehicleListService.class);

        if (info != null)
        {
            if (info.isConnected())
            {
                if (!Utilities.vehicleFileExists(context))
                {
                    context.startService(retrieveVehicleList);
                }
            }
            else
            {
                context.stopService(retrieveVehicleList);
            }
        }
    }
}

这是我的清单:

<?xml version="1.0" encoding="utf-8"?>
<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    package="clyky.cartracker">

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

    <!--
         TODO crediti per le icone:
        <div>Icons made by <a href="http://www.flaticon.com/authors/dave-gandy" title="Dave Gandy">Dave Gandy</a> from <a href="http://www.flaticon.com" title="Flaticon">www.flaticon.com</a> is licensed by <a href="http://creativecommons.org/licenses/by/3.0/" title="Creative Commons BY 3.0" target="_blank">CC 3.0 BY</a></div>
        per la freccia in giù che espande il layout nella LoginActivity
        <div>Icons made by <a href="http://www.flaticon.com/authors/dave-gandy" title="Dave Gandy">Dave Gandy</a> from <a href="http://www.flaticon.com" title="Flaticon">www.flaticon.com</a> is licensed by <a href="http://creativecommons.org/licenses/by/3.0/" title="Creative Commons BY 3.0" target="_blank">CC 3.0 BY</a></div>
        per la freccia in su
        <div>Icons made by <a href="http://www.flaticon.com/authors/madebyoliver" title="Madebyoliver">Madebyoliver</a> from <a href="http://www.flaticon.com" title="Flaticon">www.flaticon.com</a> is licensed by <a href="http://creativecommons.org/licenses/by/3.0/" title="Creative Commons BY 3.0" target="_blank">CC 3.0 BY</a></div>
        per il lucchetto
        <a href="https://icons8.com/icon/17577/Car-Rental">Car rental icon credits</a>
        per l'icona della macchina
    -->
    <application
        android:name=".AppGlobal"
        android:allowBackup="true"
        android:icon="@mipmap/ic_app_icon"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".activities.RegistrationActivity">
        </activity>
        <activity android:name=".activities.LoginActivity">
        </activity>
        <activity android:name=".activities.VehicleListActivity">
        </activity>
        <activity android:name=".activities.VehicleDetailsActivity">
        </activity>
        <activity android:name=".activities.AddVehicleActivity">
        </activity>
        <!--
             The API key for Google Maps-based APIs is defined as a string resource
             Note that the API key is linked to the encryption key used to sign the APK.
             You need a different API key for each encryption key, including the release key that is used to
             sign the APK for publishing.
             You can define the keys for the debug and release targets in src/debug/ and src/release/. 
        -->
        <meta-data
            android:name="com.google.android.geo.API_KEY"
            android:value="@string/google_maps_key"/>

        <activity
            android:name=".activities.SplashActivity"
            android:theme="@style/SplashTheme">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
        <activity android:name=".activities.MainActivity">
        </activity>
        <activity android:name=".activities.DrivingLicenseActivity">
        </activity>
        <receiver
            android:name=".services.NetworkWatcher"
            android:enabled="true"
            android:exported="false">
        </receiver>
        <service
            android:name=".services.RetrieveVehicleListService"
            android:exported="false">
        </service>
    </application>
</manifest>

2 个答案:

答案 0 :(得分:0)

连接更改操作:

  1. 如果要检测更改网络连接,请使用:

    <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />

  2. 如果要检测WiFi状态更改使用:

    <action android:name="android.net.wifi.WIFI_STATE_CHANGED" />

  3. 按以下方式更改您的收到:

    <receiver  android:name=".services.NetworkWatcher">
               <intent-filter>
                  <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
               </intent-filter>
    </receiver>
    

答案 1 :(得分:0)

您应该从<receiver>中完全删除AndroidManifest.xml代码,因为从Nougat(Android 7 API 24)开始,您将无法在接收方中接收连接更改事件{{3} },因为here

您可以在应用程序运行时仅在您的主UI线程上收听CONNECTIVITY_ACTION,并以编程方式注册BroadCastReceiver在前台,这可能是一个好的或坏的解决方案在你的用例上。

我建议您阅读此答案:new limitations to background services并在提供的解决方案中选择一个或多个组合:

  1. https://stackoverflow.com/a/39880860/2910520(API 21以后)
  2. JobScheduler(为此,用户需要安装Google Play服务)
  3.   

    Evernote发布了一个已经切换到该设备可用的最佳实现的库,我建议你不要从头开始使用它:   GcmNetworkManager