Android - AlarmManager不在设备上触发api 29。

问题描述 投票:0回答:1

我正在开发一个安卓应用程序,目的是获取手机的位置。我使用AlarmManager来反复触发BroadcastReceiver来获取坐标。当我用api 23在虚拟设备上运行时,一切正常。但是当我尝试用api 29在虚拟设备上运行时,警报没有被触发,什么都没有发生。当我在真实设备(小米)上使用api 29运行应用程序时,同样的错误行为也会发生。下面是所有实现的代码。谁能帮我解决这个问题?

谢谢你的帮助

build.gradle (:app)

apply plugin: 'com.android.application'

android {
    compileSdkVersion 29
    buildToolsVersion "29.0.3"

    defaultConfig {
        applicationId "br.com.detectx.android.locator"
        minSdkVersion 23
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: "libs", include: ["*.jar"])
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    implementation 'br.com.detectx.android:celulatronco-android:1.0.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'

}

AndroidManifest.xml

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

    <uses-permission android:name="android.permission.INTERNET" android:required="true"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" android:required="true"/>
    <uses-permission android:name="android.permission.READ_PHONE_STATE" android:required="true"/>
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" android:required="true"/>
    <uses-permission android:name="android.permission.WAKE_LOCK"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" android:required="true"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" android:required="true"/>
    <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" android:required="true"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        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>


        <receiver android:name="br.com.detectx.android.locator.receiver.GPSReciver">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
            </intent-filter>
        </receiver>

    </application>

</manifest>

LocationTracker.java

public class LocationTracker extends Service implements LocationListener {

    public static final String TAG = "LocationTracker";
    private static final long MIN_TIME_BW_UPDATES = 60000;
    private final Context mContext;
    private Location location = null;
    private double latitude;
    private double longitude;

    public LocationTracker(Context context) {
        this.mContext = context;
        Log.e("Get", "GPS");
        updateLocation();
    }

    public void onCreate() {
        super.onCreate();
    }

    public int onStartCommand(Intent intent, int flags, int startId) {
        return Service.START_NOT_STICKY;
    }

    public void updateLocation() {
        try {
            LocationManager locationManager = (LocationManager) this.mContext.getSystemService(Context.LOCATION_SERVICE);
            boolean gpsEnabled = locationManager.isProviderEnabled("gps");
            boolean networkEnabled = locationManager.isProviderEnabled("network");
            if (!gpsEnabled && !networkEnabled) {
                Log.i(TAG, "no network provider is enabled");
            } else {
                if (networkEnabled) {
                    if (ActivityCompat.checkSelfPermission(this.mContext, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this.mContext, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                        Log.e(TAG, "Not allowed to ACCESS_FINE_LOCATION");
                        return;
                    }
                    locationManager.requestLocationUpdates("network", MIN_TIME_BW_UPDATES, 30.0f, this);
                    Log.d("Network", "G");
                    if (locationManager != null) {
                        this.location = locationManager.getLastKnownLocation("network");
                        if (this.location != null) {
                            this.latitude = this.location.getLatitude();
                            this.longitude = this.location.getLongitude();
                        }
                    }
                } else if (gpsEnabled) {
                    if (this.location == null) {
                        locationManager.requestLocationUpdates("gps", MIN_TIME_BW_UPDATES, 30.0f, this);
                        Log.d("GPS Enabled", "GPS Enabled");
                        if (locationManager != null) {
                            this.location = locationManager.getLastKnownLocation("gps");
                            if (this.location != null) {
                                this.latitude = this.location.getLatitude();
                                this.longitude = this.location.getLongitude();
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public double getLatitude() {
        Location location = this.location;
        if (location != null) {
            this.latitude = location.getLatitude();
        }
        return this.latitude;
    }

    public double getLongitude() {
        Location location = this.location;
        if (location != null) {
            this.longitude = location.getLongitude();
        }
        return this.longitude;
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onLocationChanged(Location location) {
        this.latitude = location.getLatitude();
        this.longitude = location.getLongitude();
    }

    @Override
    public void onStatusChanged(String s, int i, Bundle bundle) {

    }

    @Override
    public void onProviderEnabled(String s) {

    }

    @Override
    public void onProviderDisabled(String s) {

    }

}

GPSReciver.java

public class GPSReciver extends BroadcastReceiver {

    private static final String TAG = "GPSReciver";

    @Override
    public void onReceive(Context context, Intent intent) {
        LocationTracker gps = new LocationTracker(context);
        String slat = String.valueOf(gps.getLatitude());
        String slon = String.valueOf(gps.getLongitude());
        Log.i(TAG, String.format("lat: %s", slat));
        Log.i(TAG, String.format("lon: %s", slon));
        if (!slat.equals("0.0") && !slon.equals("0.0")) {
            //TODO
        }


    }
}

MainActivity.java

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";

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

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_PHONE_STATE}, ConstantsApp.PERMISSIONS_REQUEST_READ_PHONE_STATE);
        }

    }

@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {
        case ConstantsApp.PERMISSIONS_REQUEST_READ_PHONE_STATE: {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, ConstantsApp.PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION);
            } else {
                finish();
            }
            return;
        }
        case ConstantsApp.PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION: {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, ConstantsApp.PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
            } else {
                finish();
            }
            return;
        }
        case ConstantsApp.PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION: {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                if (Build.VERSION.SDK_INT < 29) {
                    AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
                    alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), (long) 300000, PendingIntent.getBroadcast(this, 0, new Intent(this, GPSReciver.class), 0));
                } else {
                    ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_BACKGROUND_LOCATION}, ConstantsApp.PERMISSIONS_REQUEST_ACCESS_BACKGROUND_LOCATION);
                }
            } else {
                finish();
            }
            return;
        }
        case ConstantsApp.PERMISSIONS_REQUEST_ACCESS_BACKGROUND_LOCATION: {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
                alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), (long) 300000, PendingIntent.getBroadcast(this, 0, new Intent(this, GPSReciver.class), 0));
            } else {
                finish();
            }
            return;
        }
    }
}

}

android broadcastreceiver alarmmanager android-location android-alarms
1个回答
0
投票

对于API 29+,你需要一个新的权限来在后台访问位置。

从文档中。

如果您的应用以Android 10(API级别29)或更高版本为目标,还要检查ACCESS_BACKGROUND_LOCATION。

参考资料

© www.soinside.com 2019 - 2024. All rights reserved.