App stopping when using Location API

Asked

Viewed 76 times

0

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

The mistake 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'
}

2 answers

2

The error indicated 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();
}

Inside 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();

0

The method blockingConnect() may only be used in a thread other than the UI thread.
You can use it for example in the method onExecute() duma Asynctask.

However the recommended is to use the method connect() and deal with the connection result in the interface methods ConnectionCallbacks and OnConnectionFailedListener, to be implemented by its Activity.

See on documentation an example of how to do it.

Basically it’s building the Googleapiclient in the method oncreate()

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

Call the method connect() in the method onStart()

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

Call the disconnect() in the onStop()

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

Implement the method onConnected(), that will be called when the connection is established.
Note: If targetApi is 23 or higher you will need to check if 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);
    ...
    ...

}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.