App stopping while using the Location API

0

This code would be used when the user pressed a button, its latitude and longitude were found and later sent to a server. But the app crashes when it starts, remembering that I got this code from a post here in SOpt.

The error you give is this:

Process: com.example.elvisriboli.locationapi, PID: 13138
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.elvisriboli.locationapi/com.example.elvisriboli.locationapi.MainActivity}: java.lang.IllegalStateException: blockingConnect must not be called on the UI thread
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2201)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2250)
    at android.app.ActivityThread.access$900(ActivityThread.java:141)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1213)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:136)
    at android.app.ActivityThread.main(ActivityThread.java:5072)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:609)
    at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.IllegalStateException: blockingConnect must not be called on the UI thread
    at com.google.android.gms.common.internal.zzx.zza(Unknown Source)
    at com.google.android.gms.common.api.internal.zzj.blockingConnect(Unknown Source)
    at com.example.elvisriboli.locationapi.MainActivity.onCreate(MainActivity.java:46)
    at android.app.Activity.performCreate(Activity.java:5249)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2165)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2250)
    at android.app.ActivityThread.access$900(ActivityThread.java:141)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1213)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:136)
    at android.app.ActivityThread.main(ActivityThread.java:5072)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:609)
    at dalvik.system.NativeStart.main(Native Method)

MY CODE

Manifest

<?xml version="1.0" encoding="utf-8"?>

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

Main Activity

public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {

    private GoogleApiClient mGoogleApiClient;

    Button btLocalizacao;
    double lat, longi;

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



        btLocalizacao = (Button) findViewById(R.id.btLocalizacao);

        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addOnConnectionFailedListener(this)
                .addConnectionCallbacks(this)
                .addApi(LocationServices.API)
                .build();
        mGoogleApiClient.blockingConnect();

        btLocalizacao.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (GetLocalization(MainActivity.this)) {
                    if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                        // TODO: Consider calling
                        return;
                    }
                    Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
                    if (location != null) {
                        lat = location.getLatitude();
                         longi =   location.getLongitude();
                    } else {
                        showSettingsAlert();
                    }
                }
            }
        });
    }

    @Override
    protected void onResume() {
        super.onResume();
        mGoogleApiClient.connect();
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (mGoogleApiClient.isConnected()) {
            mGoogleApiClient.disconnect();
        }
    }
    @Override
    public void onConnected(Bundle bundle) {

    }

    @Override
    public void onConnectionSuspended(int i) {

    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {

    }

    public boolean GetLocalization(Context context) {
        int REQUEST_PERMISSION_LOCALIZATION = 221;
        boolean res = true;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                // TODO: Consider calling
                res = false;
                ActivityCompat.requestPermissions((Activity) context, new String[]{
                                Manifest.permission.ACCESS_FINE_LOCATION},
                        REQUEST_PERMISSION_LOCALIZATION);

            }
        }
        return res;
    }

    public void showSettingsAlert(){
        android.app.AlertDialog.Builder alertDialog = new android.app.AlertDialog.Builder(MainActivity.this);

        // Titulo do dialogo
        alertDialog.setTitle("GPS");

        // Mensagem do dialogo
        alertDialog.setMessage("GPS não está habilitado. Deseja configurar?");

        // On pressing Settings button
        alertDialog.setPositiveButton("Configurar", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog,int which) {
                Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                MainActivity.this.startActivity(intent);
            }
        });

        // on pressing cancel button
        alertDialog.setNegativeButton("Cancelar", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                dialog.cancel();
            }
        });

        // visualizacao do dialogo
        alertDialog.show();
    }
}

Gradle

apply plugin: 'com.android.application'

android {
    compileSdkVersion 24
    buildToolsVersion "24.0.2"

    defaultConfig {
        applicationId "com.example.elvisriboli.locationapi"
        minSdkVersion 18
        targetSdkVersion 24
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:24.2.0'
    compile 'com.google.android.gms:play-services-location:8.4.0'
}
    
asked by anonymous 19.09.2016 / 20:46

2 answers

2

The indicated error is: blockingConnect should not be called in the main activity

Do the following, remove these lines from your onCreate:

 mGoogleApiClient = new GoogleApiClient.Builder(this)
        .addOnConnectionFailedListener(this)
        .addConnectionCallbacks(this)
        .addApi(LocationServices.API)
        .build();
mGoogleApiClient.blockingConnect();

Add in method form, out of onCreate:

protected synchronized void buildGoogleApiClient() {
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
}

Within your onCreate, you leave only these two lines, which will be responsible for connecting with ApiClient and calling the method you added outside of onCreate:

buildGoogleApiClient();
mGoogleApiClient.connect();
    
19.09.2016 / 21:05
0

The blockingConnect () can only be used in a thread other than the UI thread . You can use it for example in the onExecute() of an AsyncTask method.

However, it is recommended to use the connect () and handle the result of the connection in the methods of the interfaces ConnectionCallbacks and OnConnectionFailedListener , to be implemented by your activity .

See documentation for an example of how to do it.

Basically, you build the GoogleApiClient method in oncreate()

 mGoogleApiClient = new GoogleApiClient.Builder(this)
        .addOnConnectionFailedListener(this)
        .addConnectionCallbacks(this)
        .addApi(LocationServices.API)
        .build();

Call method connect() in method onStart()

@Override
protected void onStart() {
    mGoogleApiClient.connect();
    super.onStart();
}

Call disconnect() on onStop()

@Override
protected void onStop() {
    mGoogleApiClient.disconnect();
    super.onStop();
}

Implement the onConnected() method, which will be called when the connection is established. Note: If the targetApi is 23 or higher you will need to verify that you have the permission at runtime.

@Override
public void onConnected(Bundle connectionHint) {

    // Agora que a conexão foi estabelecida pode utilizar o LocationServices para,
    // por exemplo, obter a última localização do dispositivo

    //Nota: Se a targetApi for 23 ou superior terá de verificar se tem a permissão em tempo de execução.
    mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
            mGoogleApiClient);
    ...
    ...

}
    
19.09.2016 / 23:46