Невозможно создать экземпляр службы, отправляющей данные в firebase.

Моя служба перестает работать после того, как я запустил приложение. Журнал показывает ошибку времени выполнения, в которой говорится, что следующие строки

java.lang.RuntimeException: Unable to instantiate service com.example.hp.newtrial.Service_Location: java.lang.NullPointerException

Код для действия и услуги является общим. Манифест также предоставляется для справки.

Я в основном пытаюсь загружать данные в firestore через определенные промежутки времени, но эта ошибка продолжает появляться.

Мой основной код активности, который вызывает услугу

    package com.example.hp.newtrial;

import android.Manifest;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.FirebaseApp;
import com.google.firebase.firestore.DocumentReference;
import com.google.firebase.firestore.FirebaseFirestore;

import java.util.HashMap;
import java.util.Map;

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity_Log";
    private LocalBroadcastManager manager;
    private BroadcastReceiver receiver;
    double latitude, longitude;
    //Location location;
    //private Service_Location service_location;
    //creating class
    //public MyBroadcastReceiver myBroadcastReceiver;
    EditText nameUser;
    Button click;
    String userName;
    // Access a Cloud Firestore instance from your Activity
    String reference_id;
    Intent intents;
    FirebaseFirestore db;
    ServiceConnection mServiceConn;

    @Override
    protected void onStart() {
        super.onStart();

        FirebaseApp.initializeApp(this);
    }


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);


        setContentView(R.layout.activity_main);
        FirebaseApp.initializeApp(this);
        //  service_location = new Service_Location();
        db = FirebaseFirestore.getInstance();

        nameUser = findViewById(R.id.usrName);
        click = findViewById(R.id.button_3);

        Log.d(TAG, "Main Activity");
        try {
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)) {
                    ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
                } else {
                    ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
                }
            }
        } catch (Exception e) {
            Log.d(TAG, "Error: ", e);
        }

        //to start the service . . . .
        try {
            intents = new Intent(MainActivity.this, Service_Location.class);
            //bindService(intents, mServiceConn, BIND_AUTO_CREATE);
            startService(intents);
        } catch (Exception e) {
            Log.d(TAG, String.valueOf(e));
        }
        /*try {
            LocalBroadcastManager.getInstance(this).registerReceiver(receiver, new IntentFilter("Location"));
            receiver = new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    String action = intent.getAction();
                    Bundle b = intent.getExtras();
                    if (b != null) {
                        latitude = b.getDouble("latitude");
                        longitude = b.getDouble("longitude");
                    }
                    Log.d("MainActivity", "Latitude: " + latitude + " Longitude:" + longitude);
                    Toast.makeText(MainActivity.this, "Location: Latitude: " + latitude + " Longitude: " + latitude, Toast.LENGTH_LONG).show();
                }
            };
        } catch (Exception e) {
            Log.d("MainActivity", String.valueOf(e));

        }*/

        click.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //to Firebase . . . .
                try {
                    userName = String.valueOf(nameUser.getText());
                    Map<String, Object> data = new HashMap<>();
                    data.put("UserName", userName);
                    Map<String, Object> data2 = new HashMap<>();
                    data.put("UserName", "Akshansh");

                    db.collection("Users").add(data).addOnSuccessListener(new OnSuccessListener<DocumentReference>() {
                        @Override
                        public void onSuccess(DocumentReference documentReference) {
                            //Getting the reference id . . . .
                            reference_id = documentReference.getId();
                            intents.putExtra("Reference_id", reference_id);
                            startService(intents);
                            Log.d(TAG, documentReference.getId());
                            Log.d(TAG, "On Success Listener :: document Added . .. . ");
                        }
                    }).addOnFailureListener(new OnFailureListener() {
                        @Override
                        public void onFailure(@NonNull Exception e) {
                            Log.d(TAG, "On Failure Listener some trouble");
                        }
                    });
                } catch (Exception e) {
                    Log.d(TAG, "Error " + String.valueOf(e));
                }
            }
        });
    }       
}

А вот код моего сервиса

package com.example.hp.newtrial;

import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.Service;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.IInterface;
import android.os.Parcel;
import android.os.RemoteException;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.FirebaseApp;
import com.google.firebase.firestore.DocumentReference;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.WriteBatch;

import java.io.FileDescriptor;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

public class Service_Location extends Service implements com.google.android.gms.location.LocationListener, GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener {

    LocationRequest mLocationRequest;
    GoogleApiClient mGoogleApiClient;
    public static Location mCurrentLocation;
    long BACKGROUND_INTERVAL = 5000;
    Context context;
    String TAG = "Service_Location";
    Intent send = new Intent("Location");

    Handler handler;
    String reference_id;
    IBinder binder;
    //Firebase Reference . . . .

    private FirebaseFirestore db;
    private DocumentReference documentReference;
    //We'll try to use batch to perform what we need . . . .
    WriteBatch batch = Objects.requireNonNull(db).batch();

    public Service_Location() {
        super();
    }

    //Google Api Connection . . .
    @SuppressLint("RestrictedApi")
    @Override
    public void onCreate() {
        super.onCreate();
        //initializing app
        FirebaseApp.initializeApp(this);
        db = FirebaseFirestore.getInstance();
        try {
            Log.d(TAG, "onCreate()");
            LocationManager locationManager = (LocationManager) this.getSystemService(LOCATION_SERVICE);
            assert locationManager != null;
            boolean isGPSenabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);

            if (!isGPSenabled) {
                showSettingDialog();
            }
        } catch (Exception e) {
            Log.d(TAG, String.valueOf(e));
        }
        //show error dialog if GoolglePlayServices not available
        try {
            if (isGooglePlayServicesAvailable()) {
                mLocationRequest = new LocationRequest();
                mLocationRequest.setInterval(BACKGROUND_INTERVAL);
                mLocationRequest.setFastestInterval(BACKGROUND_INTERVAL);
                mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
                //mLocationRequest.setSmallestDisplacement(10.0f);  /* min dist for location change, here it is 10 meter */
                mGoogleApiClient = new GoogleApiClient.Builder(this)
                        .addApi(LocationServices.API)
                        .addConnectionCallbacks(this)
                        .addOnConnectionFailedListener(this)
                        .build();

                mGoogleApiClient.connect();
            }
        } catch (Exception e) {
            Log.d(TAG, String.valueOf(e));
        }
        handler = new Handler(getMainLooper());
    }

    private void showSettingDialog() {
        AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);

        alertDialog.setTitle("GPS is setting");

        alertDialog.setMessage("GPS not enabled!!!");

        alertDialog.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                startActivity(intent);
            }
        });

        alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                dialogInterface.cancel();
            }
        });
        alertDialog.show();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "Data received from intent Reference_id:" + intent.getStringExtra("Reference_id"));
        reference_id = intent.getStringExtra("Reference_id");
        return START_STICKY;
    }

    private boolean isGooglePlayServicesAvailable() {
        Log.d(TAG, "isGooglePlayServicesAvailable()");
        int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
        return ConnectionResult.SUCCESS == status;
    }

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

    //Location Listener. . .
    @Override
    public void onLocationChanged(final Location location) {
        try {
            if (reference_id != null) {
                documentReference = db.collection("Users").document(reference_id);
                //update(location);
                //now trying with batch. . .
                updateBatch(location);
            }
            Log.d(TAG, "OnLocationChanged()");
            Log.d(TAG, "Latitude: " + location.getLatitude() + " Longitude: " + location.getLongitude());

        } catch (Exception e) {
            Log.d(TAG, String.valueOf(e));
        }


        handler.post(new Runnable() {
            @Override
            public void run() {
                //Toast.makeText(getApplicationContext(), "this helps", Toast.LENGTH_LONG).show();
            }
        });
    }

    private void updateBatch(Location location) {
        Log.d(TAG, "inside updateBatch");
        try {
            LatLng lng = new LatLng(location.getLatitude(), location.getLongitude());
            Map<String, LatLng> map = new HashMap<>();
            map.put("Location", lng);
            batch.update(documentReference, "Location", map);
        } catch (Exception e) {
            Log.d(TAG, String.valueOf(e));
        }
    }

    private void update(Location location) {
        Log.d(TAG, "Updating Location");
        LatLng lng = new LatLng(location.getLatitude(), location.getLongitude());
        Map<String, LatLng> map = new HashMap<>();
        map.put("Location", lng);

        documentReference.set(map).addOnSuccessListener(new OnSuccessListener<Void>() {
            @Override
            public void onSuccess(Void aVoid) {
                Log.d("Location", "Added Successfully. . ");
            }
        }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                Log.d("Location", "Failed ");
            }
        });
    }

    /
    //Google API Client

    public void onConnected(Bundle bundle) {
        Log.d(TAG, "On_Connected()");
        startLocationUpdates();
    }

    protected void startLocationUpdates() {
        try {
            PendingResult<Status> pendingResult = LocationServices.FusedLocationApi.requestLocationUpdates(
                    mGoogleApiClient, mLocationRequest, (com.google.android.gms.location.LocationListener) this);
        } catch (Exception e) {
            Log.d("Service", String.valueOf(e));
        }
    }

    @Override
    public void onConnectionSuspended(int i) {

    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {

    }
}

Манифест:

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

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

    <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>

        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />

        <service android:name=".Service_Location" />

    </application>

</manifest>

Я не понимаю, что делать дальше. . . Любое рабочее предложение приемлемо

вы неправильно запрашиваете разрешение времени выполнения, и вам необходимо добавить код службы запуска в другое условие разрешения времени выполнения.

Mohammed Farhan 11.04.2018 13:48
0
1
283
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Попробуйте запросить разрешения во время выполнения вот так. Сначала добавьте разрешение времени выполнения в onCreate()

private static final int LOCATION_PERMISSI0N = 2002;

    if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
            != PackageManager.PERMISSION_GRANTED)
    {
        ActivityCompat.requestPermissions(this,
                new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, LOCATION_PERMISSI0N);
    }
    else
    {
        startService();
    }

теперь вне метода onCreate() добавьте этот метод startService()

public void startService()
{
    try {
        Intent intents = new Intent(MainActivity.this, Service_Location.class);
        //bindService(intents, mServiceConn, BIND_AUTO_CREATE);
        startService(intents);
    } catch (Exception e) {
        Log.d(TAG, String.valueOf(e));
    }
}

обработать предоставленное разрешение, переопределив этот метод вне onCreate()

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)
{
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    switch (requestCode)
    {
        case LOCATION_PERMISSI0N:
        {
            if (grantResults.length > 0)
            {
                boolean course_location = grantResults[0] == PackageManager.PERMISSION_GRANTED;
                if (course_location)
                {
                    startService();
                }
                else
                {
                    Log.d("locationpermissions","Location Permission Denied");
                }
            }
            break;
        }

    }
}

это должно запустить вашу службу ..

Другие вопросы по теме