安卓工作室应用程序只是说获取位置并被困在那里



我正在创建一个速度表应用程序,但是一旦我运行代码,我看到的只是一个加载栏,上面写着"获取位置"。我注意到,如果我转到应用程序管理器并授予应用程序访问位置的权限,则没有问题。所以我想我的问题可能与请求许可有关。此外,移动后,我注意到我的速度一直在上升。 这是代码: 安卓清单.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.rrithvik.speedometer2">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.LOCATION_HARDWARE"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<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">
android:name=".MainActivity"
android:label="@string/app_name"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".LocationService"></service>
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
</application>
</manifest>

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/black"
android:orientation="vertical">
<ImageView
android:id="@+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:src="@mipmap/ic_launcher"
android:visibility="gone" />
<TextView
android:id="@+id/distancetext"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="100dp"
android:gravity="center"
android:singleLine="true"
android:text="Total Distance:"
android:textColor="@android:color/white"
android:textSize="25sp"
android:textStyle="bold" />
<TextView
android:id="@+id/speedtext"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="150dp"
android:gravity="center"
android:singleLine="true"
android:text="Instantaneous Speed:"
android:textColor="@android:color/white"
android:textSize="18sp" />
<TextView
android:id="@+id/timetext"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="190dp"
android:gravity="center"
android:singleLine="true"
android:text="Total Time:"
android:textColor="@android:color/white"
android:textSize="17sp" />

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:orientation="horizontal">
<Button
android:id="@+id/start"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="bottom"
android:background="@android:color/white"
android:paddingBottom="0dp"
android:text="Start Calculating" />
<Button
android:id="@+id/pause"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:layout_weight="1"
android:background="@android:color/white"
android:text="Pause"
android:visibility="gone" />
<Button
android:id="@+id/stop"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:layout_marginLeft="2dp"
android:layout_weight="1"
android:background="@android:color/white"
android:text="Stop"
android:visibility="gone" />
</LinearLayout>
</FrameLayout>

主要活动.java

package com.rrithvik.speedometer2;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.ComponentName;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
LocationService myService;
static boolean status;
LocationManager locationManager;
static TextView dist, time, speed;
Button start, pause, stop;
static long startTime, endTime;
ImageView image;
static ProgressDialog locate;
static int p = 0;
private ServiceConnection sc = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
LocationService.LocalBinder binder = (LocationService.LocalBinder) service;
myService = binder.getService();
status = true;
}
@Override
public void onServiceDisconnected(ComponentName name) {
status = false;
}
};
void bindService() {
if (status == true)
return;
Intent i = new Intent(getApplicationContext(), LocationService.class);
bindService(i, sc, BIND_AUTO_CREATE);
status = true;
startTime = System.currentTimeMillis();
}
void unbindService() {
if (status == false)
return;
Intent i = new Intent(getApplicationContext(), LocationService.class);
unbindService(sc);
status = false;
}
@Override
protected void onResume() {
super.onResume();
}
@Override
protected void onStart() {
super.onStart();
}

@Override
protected void onDestroy() {
super.onDestroy();
if (status == true)
unbindService();
}
@Override
public void onBackPressed() {
if (status == false)
super.onBackPressed();
else
moveTaskToBack(true);
}

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

dist = (TextView) findViewById(R.id.distancetext);
time = (TextView) findViewById(R.id.timetext);
speed = (TextView) findViewById(R.id.speedtext);
start = (Button) findViewById(R.id.start);
pause = (Button) findViewById(R.id.pause);
stop = (Button) findViewById(R.id.stop);
image = (ImageView) findViewById(R.id.image);
start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//The method below checks if Location is enabled on device or not. If not, then an alert dialog box appears with option
//to enable gps.
checkGps();
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
return;
}

if (status == false)
//Here, the Location Service gets bound and the GPS Speedometer gets Active.
bindService();
locate = new ProgressDialog(MainActivity.this);
locate.setIndeterminate(true);
locate.setCancelable(false);
locate.setMessage("Getting Location...");
locate.show();
start.setVisibility(View.GONE);
pause.setVisibility(View.VISIBLE);
pause.setText("Pause");
stop.setVisibility(View.VISIBLE);

}
});
pause.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (pause.getText().toString().equalsIgnoreCase("pause")) {
pause.setText("Resume");
p = 1;
} else if (pause.getText().toString().equalsIgnoreCase("Resume")) {
checkGps();
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
//Toast.makeText(this, "GPS is Enabled in your devide", Toast.LENGTH_SHORT).show();
return;
}
pause.setText("Pause");
p = 0;
}
}
});

stop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (status == true)
unbindService();
start.setVisibility(View.VISIBLE);
pause.setText("Pause");
pause.setVisibility(View.GONE);
stop.setVisibility(View.GONE);
p = 0;
}
});
}

//This method leads you to the alert dialog box.
void checkGps() {
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {

showGPSDisabledAlertToUser();
}
}
//This method configures the Alert Dialog box.
private void showGPSDisabledAlertToUser() {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setMessage("Enable GPS to use application")
.setCancelable(false)
.setPositiveButton("Enable GPS",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Intent callGPSSettingIntent = new Intent(
android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(callGPSSettingIntent);
}
});
alertDialogBuilder.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert = alertDialogBuilder.create();
alert.show();
}
}

位置服务.java

package com.rrithvik.speedometer2;
import android.app.Service;
import android.content.Intent;
import android.location.Location;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.support.annotation.Nullable;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import java.text.DecimalFormat;
import java.util.concurrent.TimeUnit;
/**
* Created by rrithvik on 8/16/17.
*/
public class LocationService extends Service implements LocationListener,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
private static final long INTERVAL = 1000 * 2;
private static final long FASTEST_INTERVAL = 1000 * 1;
LocationRequest mLocationRequest;
GoogleApiClient mGoogleApiClient;
Location mCurrentLocation, lStart, lEnd;
static double distance = 0;
double speed;

private final IBinder mBinder = new LocalBinder();
@Nullable
@Override
public IBinder onBind(Intent intent) {
createLocationRequest();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
mGoogleApiClient.connect();
return mBinder;
}
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(INTERVAL);
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}

@Override
public void onConnected(Bundle bundle) {
try {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
} catch (SecurityException e) {
}
}

protected void stopLocationUpdates() {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
distance = 0;
}

@Override
public void onConnectionSuspended(int i) {
}

@Override
public void onLocationChanged(Location location) {
MainActivity.locate.dismiss();
mCurrentLocation = location;
if (lStart == null) {
lStart = mCurrentLocation;
lEnd = mCurrentLocation;
} else
lEnd = mCurrentLocation;
//Calling the method below updates the  live values of distance and speed to the TextViews.
updateUI();
//calculating the speed with getSpeed method it returns speed in m/s so we are converting it into kmph
speed = location.getSpeed() * 18 / 5;
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
public class LocalBinder extends Binder {
public LocationService getService() {
return LocationService.this;
}

}
//The live feed of Distance and Speed are being set in the method below .
private void updateUI() {
if (MainActivity.p == 0) {
distance = distance + (lStart.distanceTo(lEnd) / 1000.00);
MainActivity.endTime = System.currentTimeMillis();
long diff = MainActivity.endTime - MainActivity.startTime;
diff = TimeUnit.MILLISECONDS.toMinutes(diff);
MainActivity.time.setText("Total Time: " + diff + " minutes");
if (speed > 0.0)
MainActivity.speed.setText("Current speed: " + new DecimalFormat("#.##").format(speed) + " km/hr");
else
MainActivity.speed.setText(".......");
MainActivity.dist.setText(new DecimalFormat("#.###").format(distance) + " Km's.");
lStart = lEnd;
}
}

@Override
public boolean onUnbind(Intent intent) {
stopLocationUpdates();
if (mGoogleApiClient.isConnected())
mGoogleApiClient.disconnect();
lStart = null;
lEnd = null;
distance = 0;
return super.onUnbind(intent);
}
}

build.gradle(app(

apply plugin: 'com.android.application'
android {
compileSdkVersion 26
buildToolsVersion "26.0.1"
defaultConfig {
applicationId "com.rrithvik.speedometer2"
minSdkVersion 22
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:26.0.0-alpha1'
compile 'com.google.android.gms:play-services:11.0.4'
testCompile 'junit:junit:4.12'
}

我到处找过,但似乎找不到这个问题的答案。不仅是我,因为我看到许多其他人面临这个问题。

Woth api>= 23 需要在运行时请求权限,通常在第一次启动时,效率更高,在需要之前。

requestPermissions(new String[] {Manifest.permissions.somePermission}

最新更新