Я новичок в программировании Android, и у меня было много проблем с ним. Я наконец-то заставил свое приложение работать в эмуляторе на целевом SDK 28. Но как только я установил apk на свой личный телефон (Nokia TA-1021), сервис открывается, но ни один из запросов не работает, а также никаких уведомлений не появляется. Но если я иду и смотрю на мои «Работающие службы», я вижу, что служба работает. В чем может быть проблема?
* Целью данной услуги является получение местоположения пользователя GPS и отправка данных в базу данных SQL Server
Единственное, что я попробовал, это разрешил все разрешения, которые я мог найти.
Это мейнфест
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.geoape.backgroundlocationexample">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<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.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.READ_PHONE_STATE " />
<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>
<service android:name="com.geoape.backgroundlocationexample.BackgroundService" />
</application>
</manifest>
Это MainActivity
package com.geoape.backgroundlocationexample;
import android.Manifest;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.net.Uri;
import android.os.IBinder;
import android.provider.Settings;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Button;
import android.widget.TextView;
import com.karumi.dexter.Dexter;
import com.karumi.dexter.PermissionToken;
import com.karumi.dexter.listener.PermissionDeniedResponse;
import com.karumi.dexter.listener.PermissionGrantedResponse;
import com.karumi.dexter.listener.PermissionRequest;
import com.karumi.dexter.listener.single.PermissionListener;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
public class MainActivity extends AppCompatActivity {
@BindView(R.id.btn_start_tracking)
Button btnStartTracking;
@BindView(R.id.btn_stop_tracking)
Button btnStopTracking;
@BindView(R.id.txt_status)
TextView txtStatus;
public BackgroundService gpsService;
public boolean mTracking = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
final Intent intent = new Intent(this.getApplication(), BackgroundService.class);
this.getApplication().startService(intent);
// this.getApplication().startForegroundService(intent);
this.getApplication().bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
}
@OnClick(R.id.btn_start_tracking)
public void startLocationButtonClick() {
Dexter.withActivity(this)
.withPermission(Manifest.permission.ACCESS_FINE_LOCATION)
.withListener(new PermissionListener() {
@Override
public void onPermissionGranted(PermissionGrantedResponse response) {
gpsService.startTracking();
mTracking = true;
toggleButtons();
}
@Override
public void onPermissionDenied(PermissionDeniedResponse response) {
if (response.isPermanentlyDenied()) {
openSettings();
}
}
@Override
public void onPermissionRationaleShouldBeShown(PermissionRequest permission, PermissionToken token) {
token.continuePermissionRequest();
}
}).check();
}
@OnClick(R.id.btn_stop_tracking)
public void stopLocationButtonClick() {
mTracking = false;
gpsService.stopTracking();
toggleButtons();
}
private void toggleButtons() {
btnStartTracking.setEnabled(!mTracking);
btnStopTracking.setEnabled(mTracking);
txtStatus.setText( (mTracking) ? "TRACKING" : "GPS Ready" );
}
private void openSettings() {
Intent intent = new Intent();
intent.setAction( Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", BuildConfig.APPLICATION_ID, null);
intent.setData(uri);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
private ServiceConnection serviceConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
String name = className.getClassName();
if (name.endsWith("BackgroundService")) {
gpsService = ((BackgroundService.LocationServiceBinder) service).getService();
btnStartTracking.setEnabled(true);
txtStatus.setText("GPS Ready");
}
}
public void onServiceDisconnected(ComponentName className) {
if (className.getClassName().equals("BackgroundService")) {
gpsService = null;
}
}
};
}
Это класс BackgroundService
package com.geoape.backgroundlocationexample;
import android.Manifest;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationManager;
import android.os.BatteryManager;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.os.StrictMode;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.NotificationCompat;
import android.telephony.PhoneStateListener;
import android.telephony.SignalStrength;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.widget.Toast;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
public class BackgroundService extends Service {
private final LocationServiceBinder binder = new LocationServiceBinder();
private final String TAG = "BackgroundService";
private LocationListener mLocationListener;
private LocationManager mLocationManager;
private NotificationManager notificationManager;
private final int LOCATION_INTERVAL = 500;
private final int LOCATION_DISTANCE = 10;
private final int REQUEST_PERMISSION_PHONE_STATE=1;
TelephonyManager TelephonManager;
myPhoneStateListener pslistener;
int SignalStrength = 0;
String signalstr = "";
@Override
public IBinder onBind(Intent intent) {
return binder;
}
class myPhoneStateListener extends PhoneStateListener {
@Override
public void onSignalStrengthsChanged(SignalStrength signalStrength) {
super.onSignalStrengthsChanged(signalStrength);
SignalStrength = signalStrength.getGsmSignalStrength();
SignalStrength = (2 * SignalStrength) - 113;
if (SignalStrength > -70 && SignalStrength < -50) {
signalstr = "Excellent";
} else if (SignalStrength > -90 && SignalStrength < -70) {
signalstr = "Good";
} else if (SignalStrength > -90 && SignalStrength < -100) {
signalstr = "Poor";
} else {
signalstr = "No Signal";
}
}
}
public Connection connectionclass(String user, String password, String database, String server) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
Connection connection = null;
String ConnectionURL = null;
try {
Class.forName("net.sourceforge.jtds.jdbc.Driver");
// ConnectionURL = "jdbc:jtds:sqlserver://" + server + database + ";username=" + user+ ";password=" + password + ";";
ConnectionURL = "jdbc:jtds:sqlserver://" + server + ":1433;"
+ "databaseName=" + database + ";user=" + user + ";password="
+ password + ";";
connection = DriverManager.getConnection(ConnectionURL);
} catch (SQLException se) {
Log.e("error here 1 : ", se.getMessage());
} catch (ClassNotFoundException e) {
Log.e("error here 2 : ", e.getMessage());
} catch (Exception e) {
Log.e("error here 3 : ", e.getMessage());
}
return connection;
}
private class LocationListener implements android.location.LocationListener
{
Connection con, con1, con2;
Connection con4, con5, con6;
Connection con7, con8, con9;
Boolean isSuccess = false;
String ip = "payslip.lk";
String db = "googleMap";
String un = "sa";
String pass = "Abc@1234";
String z = "tt";
private Location lastLocation = null;
private final String TAG = "LocationListener";
private Location mLastLocation;
public LocationListener(String provider)
{
mLastLocation = new Location(provider);
}
@Override
public void onLocationChanged(Location location)
{
mLastLocation = location;
Log.i(TAG, "LocationChanged: "+location);
//Double z = location.getLatitude();
//Toast.makeText(BackgroundService.this,z.toString(), Toast.LENGTH_LONG).show();
try {
con = connectionclass(un, pass, db, ip);
con1 = connectionclass(un, pass, db, ip);
con2 = connectionclass(un, pass, db, ip);
con4 = connectionclass(un, pass, db, ip);
con5 = connectionclass(un, pass, db, ip);
con6 = connectionclass(un, pass, db, ip);
con7 = connectionclass(un, pass, db, ip);
con8 = connectionclass(un, pass, db, ip);
con9 = connectionclass(un, pass, db, ip);
// Connect to database
if (con == null) {
z = "Check Your Internet Access!";
Toast.makeText(BackgroundService.this, z.toString(), Toast.LENGTH_LONG).show();
} else {
z = "Internet Available";
Toast.makeText(BackgroundService.this, z.toString(), Toast.LENGTH_LONG).show();
if (ActivityCompat.checkSelfPermission(BackgroundService.this, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
z = "Inside IF!";
Toast.makeText(BackgroundService.this, z.toString(), Toast.LENGTH_LONG).show();
String query1 = "Select * from location where serial_no='" + Build.getSerial() + "'";
Statement stq1=con.createStatement();
ResultSet rs = stq1.executeQuery(query1);
String last_lat=""; String last_long="";
int waiting_sec=0;
String last_seq="";
Toast.makeText(BackgroundService.this , "update" , Toast.LENGTH_LONG).show();
if(rs.next())
{
double differ_lat=0;
double differ_long=0;
DecimalFormat df = new DecimalFormat("0.00000");
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
DateFormat timeFormat = new SimpleDateFormat("HH:mm:ss");
Date date = new Date();
z = "Near the Update ";
Toast.makeText(BackgroundService.this, z.toString(), Toast.LENGTH_LONG).show();
String query = "Update location set longtitude = '"+ location.getLatitude()+"" +"',latitude ='"+ location.getLongitude()+"',date='"+dateFormat.format(date)+"',time='"+timeFormat.format(date).toString()+"' where serial_no='"+ Build.getSerial() +"' ";
Statement stmt = con1.createStatement();
stmt.executeUpdate(query);
con1.close();
Integer i=0;
String query4="Select TOP 1 * from loc_history where serial_no='"+ Build.getSerial() +"' and date='"+dateFormat.format(date)+"' order by time desc ";
Statement stq4=con8.createStatement();
ResultSet rs4 = stq4.executeQuery(query4);
if(rs4.next())
{
last_lat = rs4.getString("co_lat").toString();
last_long = rs4.getString("co_long").toString();
last_seq = rs4.getString("seq_no").toString();
i=Integer.parseInt(rs4.getString("seq_no").toString());
waiting_sec=Integer.parseInt(rs4.getString("waiting_ss").toString());
++i;
// String[] degree_lastLat = last_lat.split("[.]");
//String[] degree_lastLong = last_long.split("[.]");
//String[] degree_locationLat = df.format(location.getLatitude()).split("[.]");
//String[] degree_locationLong = df.format(location.getLongitude()).split("[.]");
// Toast.makeText(SensorService.this , degree_locationLat[1].substring(0,2) , Toast.LENGTH_LONG).show();
// Toast.makeText(SensorService.this , "-"+degree_lastLat[1].substring(0,2) , Toast.LENGTH_LONG).show();
//Toast.makeText(SensorService.this ,degree_lastLong[1].substring(0,2) , Toast.LENGTH_LONG).show();
//Toast.makeText(SensorService.this , "- -"+degree_locationLong[1].substring(0,2) , Toast.LENGTH_LONG).show();
// Toast.makeText(SensorService.this ,Double.parseDouble(last_lat)+"--" +Double.parseDouble(df.format(location.getLatitude())), Toast.LENGTH_LONG).show();
differ_lat = Double.parseDouble(last_lat) - Double.parseDouble(df.format(location.getLatitude())) ;
// Toast.makeText(SensorService.this ,df.format(differ_lat)+"" , Toast.LENGTH_LONG).show();
differ_long = Double.parseDouble(last_long) - Double.parseDouble(df.format(location.getLongitude())) ;
// int differ_long = Integer.parseInt(degree_lastLong[1].concat(""))- Integer.parseInt(degree_locationLong[1].concat(""));
// Toast.makeText(SensorService.this ,"- -"+df.format(differ_long) , Toast.LENGTH_LONG).show();
}else{
differ_lat = 1;
differ_long = 1;
}
if(differ_lat <0){
differ_lat= -differ_lat;
}
if(differ_long <0){
differ_long= -differ_long;
}
// if(degree_lastLat[1].substring(0,2).equals(degree_locationLat[1].substring(0,2)) && degree_lastLong[1].substring(0,2).equals(degree_locationLong[1].substring(0,2))){
if(differ_lat < 0.00100 && differ_long < 0.00100){
++waiting_sec;
String query2 = "Update loc_history set waiting_ss ='"+ waiting_sec +"' where serial_no='"+ Build.getSerial() +"' and seq_no='"+last_seq+"' and date='"+dateFormat.format(date)+"'";
Statement stmt1 = con9.createStatement();
stmt1.executeUpdate(query2);
con9.close();
}else {
Intent batteryIntent = registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
int level = batteryIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
// int scale = batteryIntent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
String query3 = "insert into loc_history values ('" + i + "','" + df.format(location.getLongitude()) + "" + "','" + df.format(location.getLatitude()) + "" + "','" + dateFormat.format(date) + "','" + timeFormat.format(date).toString() + "','" + Build.getSerial() + "" + "','" + level + "','" + SignalStrength + "','" + signalstr + "','0') ";
Statement stmt5 = con5.createStatement();
stmt5.executeUpdate(query3);
con5.close();
Toast.makeText(BackgroundService.this, "Insert Loc history", Toast.LENGTH_LONG).show();
}
}else{
Integer i=0;
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
DateFormat timeFormat = new SimpleDateFormat("HH:mm:ss");
Date date = new Date();
z="Insert";
Toast.makeText(BackgroundService.this , z.toString(), Toast.LENGTH_LONG).show();
String query4="Select TOP 1 * from loc_history where serial_no='"+ Build.getSerial() +"' and date='"+dateFormat.format(date)+"' order by time desc ";
Statement stq4=con7.createStatement();
ResultSet rs4 = stq4.executeQuery(query4);
if(rs4.next())
{
i=Integer.parseInt(rs4.getString("seq_no").toString());
++i;
}
// Toast.makeText(FirstService.this , i, Toast.LENGTH_LONG).show();
try {
String query = "insert into location values ('"+ location.getLatitude()+"" +"','"+ location.getLongitude()+"" +"','"+ Build.getSerial()+"" +"','"+""+"','"+ dateFormat.format(date) +"','"+ timeFormat.format(date).toString() +"','"+"1"+"','"+"1"+"','"+"1"+"','"+"1"+"','"+"1"+"') ";
Statement stmt = con2.createStatement();
stmt.executeUpdate(query);
con2.close();
}catch (Exception ex)
{
Toast.makeText(BackgroundService.this ,"1"+ ex.toString() , Toast.LENGTH_LONG).show();
}
try{
Intent batteryIntent = registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
int level = batteryIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
DecimalFormat df = new DecimalFormat("0.00000");
String query2 = "insert into loc_history values ('"+ i +"','"+ df.format(location.getLongitude())+"" +"','"+ df.format(location.getLatitude()) +"" +"','"+ dateFormat.format(date) +"','"+ timeFormat.format(date).toString() +"','"+ Build.getSerial() +"" +"','"+ level +""+"','"+SignalStrength+"','"+signalstr+"','0') ";
Statement stmt2 = con4.createStatement();
stmt2.executeUpdate(query2);
con4.close();
}catch (Exception ex)
{
Toast.makeText(BackgroundService.this , "catch 2"+ex.toString() , Toast.LENGTH_LONG).show();
}
}
con.close();
} /*else {
ActivityCompat.requestPermissions(PhoneStateListener.this, new String[]{Manifest.permission.READ_PHONE_STATE}, 225);
}*/
}
return;
}
catch (Exception ex)
{
Toast.makeText(BackgroundService.this , "catch 3"+ex.toString() , Toast.LENGTH_LONG).show();
isSuccess = false;
z = ex.getMessage();
Toast.makeText(BackgroundService.this , z.toString() , Toast.LENGTH_LONG).show();
}
}
@Override
public void onProviderDisabled(String provider)
{
Log.e(TAG, "onProviderDisabled: " + provider);
}
@Override
public void onProviderEnabled(String provider)
{
Log.e(TAG, "onProviderEnabled: " + provider);
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras)
{
Log.e(TAG, "onStatusChanged: " + status);
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
super.onStartCommand(intent, flags, startId);
return START_NOT_STICKY;
}
@Override
public void onCreate()
{
Log.i(TAG, "onCreate");
startForeground(1, getNotification());
}
@Override
public void onDestroy()
{
super.onDestroy();
if (mLocationManager != null) {
try {
mLocationManager.removeUpdates(mLocationListener);
} catch (Exception ex) {
Log.i(TAG, "fail to remove location listners, ignore", ex);
}
}
}
private void initializeLocationManager() {
if (mLocationManager == null) {
mLocationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
}
}
public void startTracking() {
initializeLocationManager();
mLocationListener = new LocationListener(LocationManager.GPS_PROVIDER);
try {
mLocationManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE, mLocationListener );
} catch (java.lang.SecurityException ex) {
// Log.i(TAG, "fail to request location update, ignore", ex);
} catch (IllegalArgumentException ex) {
// Log.d(TAG, "gps provider does not exist " + ex.getMessage());
}
}
public void stopTracking() {
this.onDestroy();
}
private Notification getNotification() {
NotificationChannel channel = new NotificationChannel("1", "My Channel", NotificationManager.IMPORTANCE_HIGH);
NotificationManager notificationManager = getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
Notification.Builder builder = new Notification.Builder(getApplicationContext(), "1").setAutoCancel(true);
return builder.build();
}
public class LocationServiceBinder extends Binder {
public BackgroundService getService() {
return BackgroundService.this;
}
}
}
Это класс ServiceRestart
package com.geoape.backgroundlocationexample;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class SensorRestart extends BroadcastReceiver {
private static final String TAG = SensorRestart.class.getSimpleName();
@Override
public void onReceive(Context context, Intent intent) {
Log.i(TAG, "Service Stops, let's restart again.");
if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
Intent serviceIntent = new Intent(context, BackgroundService.class);
context.startForegroundService(serviceIntent);
}else{
context.startForegroundService(new Intent(context, BackgroundService.class));
}
}}
* Извините, что я не могу предоставить log cat, так как я разрабатываю это приложение на удаленном ПК, поэтому я должен вручную установить apk