ArrayList在构造函数中正确分配,但在Android Studio服务中外面时为NULL
我似乎无法弄清楚为什么每当我尝试将mainActivity
收到的阵列列表分配给背景服务sensorService
中的公共阵列>。 这是我的构造函数,
public SensorService(ArrayList<String> contactListNumber) {
contactNumbers=contactListNumber;
Log.d(TAG, "Inside Constructor");
Log.d(TAG, "SensorService: Phone Numbers = "+contactListNumber);
Log.d(TAG, "SensorService: Input Arraylist Size = "+contactListNumber.size());
Log.d(TAG, "SensorService: Assigned Arraylist Size = "+contactNumbers.size());
setPhoneNumberArray(contactListNumber);
}
我什至尝试调用一种方法,但是它仍然给我带来相同的结果,因为它正确地分配了contactnumbers
,但是当我尝试在OnCreate内调用它时,我会得到NullPoInterExcept。
这是我创建服务的mainActivity
意图
SensorService sensorService = new SensorService(Contact_Number);
Intent intent = new Intent(this, sensorService.getClass());
if(!isMyServiceRunning(sensorService.getClass())){
startService(intent);
//intent.putExtra("ContactNumberList", Contact_Number);
Toast.makeText(this, "Starting Service", Toast.LENGTH_SHORT).show();
}
,这是我的完整sensorService
。
public class SensorService extends Service {
private SensorManager mSensorManager;
private Sensor mAccelerometer;
private ShakeDetector mShakeDetector;
public ArrayList<String> contactNumbers;
public SensorService() {
}
public SensorService(ArrayList<String> contactListNumber) {
contactNumbers=contactListNumber;
Log.d(TAG, "Inside Constructor");
Log.d(TAG, "SensorService: Phone Numbers = "+contactListNumber);
Log.d(TAG, "SensorService: Input Arraylist Size = "+contactListNumber.size());
Log.d(TAG, "SensorService: Assigned Arraylist Size = "+contactNumbers.size());
setPhoneNumberArray(contactListNumber);
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
return START_STICKY;
}
@Override
public void onCreate() {
//contactNumbers=MainActivity.Contact_Numbers;
super.onCreate();
// start the foreground service
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
startMyOwnForeground();
else
startForeground(1, new Notification());
// ShakeDetector initialization
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mShakeDetector = new ShakeDetector();
Log.d(TAG, "SensorService: Assigned Arraylist Size Outside Constructor = "+contactNumbers.size());
mShakeDetector.setOnShakeListener(new ShakeDetector.OnShakeListener() {
@SuppressLint("MissingPermission")
@Override
public void onShake(int count) {
// check if the user has shacked
// the phone for 3 time in a row
//if (count == 3)
if (count == 1) {
// vibrate the phone
vibrate();
Log.d(TAG, "onShake: Vibrate Activated");
// create FusedLocationProviderClient to get the user location
FusedLocationProviderClient fusedLocationClient = LocationServices.getFusedLocationProviderClient(getApplicationContext());
Log.d("Check: ", "Sending Message");
// use the PRIORITY_BALANCED_POWER_ACCURACY
// so that the service doesn't use unnecessary power via GPS
// it will only use GPS at this very moment
fusedLocationClient.getCurrentLocation(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY, new CancellationToken() {
@Override
public boolean isCancellationRequested() {
return false;
}
@NonNull
@Override
public CancellationToken onCanceledRequested(@NonNull OnTokenCanceledListener onTokenCanceledListener) {
return null;
}
}).addOnSuccessListener(new OnSuccessListener<Location>() {
@Override
public void onSuccess(Location location) {
// check if location is null
// for both the cases we will
// create different messages
Log.d("Check: ", "MESSAGE SENT");
if (location != null) {
// get the SMSManager
SmsManager smsManager = SmsManager.getDefault();
// get the list of all the contacts in Database
DatabaseHelper db = new DatabaseHelper(SensorService.this);
ArrayList<String> Contact_id, Contact_Name, Contact_Number;
ArrayList<String> phonenumber = new ArrayList<String>();
Log.d(TAG, "onSuccess: contactlistnumber size = "+contactNumbers.size());
String[] phoneNumberList = new String[contactNumbers.size()];
phoneNumberList = contactNumbers.toArray(phoneNumberList);
Log.d(TAG, "onSuccess: Item 1 = "+phoneNumberList[0]);
for(int i = 0; i < phoneNumberList.length ; i++){
Log.d("Number is",(String)phoneNumberList[i]);
}
//phonenumber = (ArrayList<String>)getIntent().getSerializableExtra("ContactNumberList");
// send SMS to each contact
for (String c : phoneNumberList) {
String message = "Hey, I am in DANGER, i need help. Please urgently reach me out. Here are my coordinates.\n " + "http://maps.google.com/?q=" + location.getLatitude() + "," + location.getLongitude();
smsManager.sendTextMessage(c, null, message, null, null);
}
} else {
String message = "I am in DANGER, i need help. Please urgently reach me out.\n" + "GPS was turned off.Couldn't find location. Call your nearest Police Station.";
SmsManager smsManager = SmsManager.getDefault();
DatabaseHelper db = new DatabaseHelper(SensorService.this);
List<ContactInfo> list = (List<ContactInfo>) db.getEveryone();
String[] phoneNumberList = new String[contactNumbers.size()];
phoneNumberList = contactNumbers.toArray(phoneNumberList);
for (String c : phoneNumberList) {
smsManager.sendTextMessage(c, null, message, null, null);
}
}
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.d("Check: ", "OnFailure");
String message = "I am in DANGER, i need help. Please urgently reach me out.\n" + "GPS was turned off.Couldn't find location. Call your nearest Police Station.";
SmsManager smsManager = SmsManager.getDefault();
DatabaseHelper db = new DatabaseHelper(SensorService.this);
List<ContactInfo> list = (List<ContactInfo>) db.getEveryone();
String[] phoneNumberList = new String[contactNumbers.size()];
phoneNumberList = contactNumbers.toArray(phoneNumberList);
for (String c : phoneNumberList){
smsManager.sendTextMessage(c, null, message, null, null);
}
}
});
}
}
});
// register the listener
mSensorManager.registerListener(mShakeDetector, mAccelerometer, SensorManager.SENSOR_DELAY_UI);
}
// method to vibrate the phone
public void vibrate() {
final Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
VibrationEffect vibEff;
// Android Q and above have some predefined vibrating patterns
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
vibEff = VibrationEffect.createPredefined(VibrationEffect.EFFECT_DOUBLE_CLICK);
vibrator.cancel();
vibrator.vibrate(vibEff);
} else {
vibrator.vibrate(500);
}
}
// For Build versions higher than Android Oreo, we launch
// a foreground service in a different way. This is due to the newly
// implemented strict notification rules, which require us to identify
// our own notification channel in order to view them correctly.
@RequiresApi(Build.VERSION_CODES.O)
private void startMyOwnForeground() {
String NOTIFICATION_CHANNEL_ID = "example.permanence";
String channelName = "Background Service";
NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_MIN);
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
assert manager != null;
manager.createNotificationChannel(chan);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
Notification notification = notificationBuilder.setOngoing(true)
.setContentTitle("You are protected.")
.setContentText("We are there for you")
// this is important, otherwise the notification will show the way
// you want i.e. it will show some default notification
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setPriority(NotificationManager.IMPORTANCE_MIN)
.setCategory(Notification.CATEGORY_SERVICE)
.build();
startForeground(2, notification);
}
@Override
public void onDestroy() {
// create an Intent to call the Broadcast receiver
Intent broadcastIntent = new Intent();
broadcastIntent.setAction("restartservice");
broadcastIntent.setClass(this, ReactivateService.class);
this.sendBroadcast(broadcastIntent);
super.onDestroy();
}
public void setPhoneNumberArray(ArrayList numbers) {
contactNumbers=numbers;
//Log.d(TAG, "setPhoneNumberArray: contactnumbers size = "+contactNumbers.size());
}
}
如果有人能告诉我为什么会发生这种情况,真的会很感激。
I cannot seem to figure out as to why whenever I try to assign an arraylist I recieved from the MainActivity
to a public arraylist of a background service SensorService
in the service's constructor.
This is my constructor
public SensorService(ArrayList<String> contactListNumber) {
contactNumbers=contactListNumber;
Log.d(TAG, "Inside Constructor");
Log.d(TAG, "SensorService: Phone Numbers = "+contactListNumber);
Log.d(TAG, "SensorService: Input Arraylist Size = "+contactListNumber.size());
Log.d(TAG, "SensorService: Assigned Arraylist Size = "+contactNumbers.size());
setPhoneNumberArray(contactListNumber);
}
I even tried invoking a method but it still gives me the same results where it assigns the contactNumbers
correctly but when I try to invoke it inside onCreate I get an NullPointerException.
This is the MainActivity
Intent where I create the service
SensorService sensorService = new SensorService(Contact_Number);
Intent intent = new Intent(this, sensorService.getClass());
if(!isMyServiceRunning(sensorService.getClass())){
startService(intent);
//intent.putExtra("ContactNumberList", Contact_Number);
Toast.makeText(this, "Starting Service", Toast.LENGTH_SHORT).show();
}
And this is my complete SensorService
.
public class SensorService extends Service {
private SensorManager mSensorManager;
private Sensor mAccelerometer;
private ShakeDetector mShakeDetector;
public ArrayList<String> contactNumbers;
public SensorService() {
}
public SensorService(ArrayList<String> contactListNumber) {
contactNumbers=contactListNumber;
Log.d(TAG, "Inside Constructor");
Log.d(TAG, "SensorService: Phone Numbers = "+contactListNumber);
Log.d(TAG, "SensorService: Input Arraylist Size = "+contactListNumber.size());
Log.d(TAG, "SensorService: Assigned Arraylist Size = "+contactNumbers.size());
setPhoneNumberArray(contactListNumber);
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
return START_STICKY;
}
@Override
public void onCreate() {
//contactNumbers=MainActivity.Contact_Numbers;
super.onCreate();
// start the foreground service
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
startMyOwnForeground();
else
startForeground(1, new Notification());
// ShakeDetector initialization
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mShakeDetector = new ShakeDetector();
Log.d(TAG, "SensorService: Assigned Arraylist Size Outside Constructor = "+contactNumbers.size());
mShakeDetector.setOnShakeListener(new ShakeDetector.OnShakeListener() {
@SuppressLint("MissingPermission")
@Override
public void onShake(int count) {
// check if the user has shacked
// the phone for 3 time in a row
//if (count == 3)
if (count == 1) {
// vibrate the phone
vibrate();
Log.d(TAG, "onShake: Vibrate Activated");
// create FusedLocationProviderClient to get the user location
FusedLocationProviderClient fusedLocationClient = LocationServices.getFusedLocationProviderClient(getApplicationContext());
Log.d("Check: ", "Sending Message");
// use the PRIORITY_BALANCED_POWER_ACCURACY
// so that the service doesn't use unnecessary power via GPS
// it will only use GPS at this very moment
fusedLocationClient.getCurrentLocation(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY, new CancellationToken() {
@Override
public boolean isCancellationRequested() {
return false;
}
@NonNull
@Override
public CancellationToken onCanceledRequested(@NonNull OnTokenCanceledListener onTokenCanceledListener) {
return null;
}
}).addOnSuccessListener(new OnSuccessListener<Location>() {
@Override
public void onSuccess(Location location) {
// check if location is null
// for both the cases we will
// create different messages
Log.d("Check: ", "MESSAGE SENT");
if (location != null) {
// get the SMSManager
SmsManager smsManager = SmsManager.getDefault();
// get the list of all the contacts in Database
DatabaseHelper db = new DatabaseHelper(SensorService.this);
ArrayList<String> Contact_id, Contact_Name, Contact_Number;
ArrayList<String> phonenumber = new ArrayList<String>();
Log.d(TAG, "onSuccess: contactlistnumber size = "+contactNumbers.size());
String[] phoneNumberList = new String[contactNumbers.size()];
phoneNumberList = contactNumbers.toArray(phoneNumberList);
Log.d(TAG, "onSuccess: Item 1 = "+phoneNumberList[0]);
for(int i = 0; i < phoneNumberList.length ; i++){
Log.d("Number is",(String)phoneNumberList[i]);
}
//phonenumber = (ArrayList<String>)getIntent().getSerializableExtra("ContactNumberList");
// send SMS to each contact
for (String c : phoneNumberList) {
String message = "Hey, I am in DANGER, i need help. Please urgently reach me out. Here are my coordinates.\n " + "http://maps.google.com/?q=" + location.getLatitude() + "," + location.getLongitude();
smsManager.sendTextMessage(c, null, message, null, null);
}
} else {
String message = "I am in DANGER, i need help. Please urgently reach me out.\n" + "GPS was turned off.Couldn't find location. Call your nearest Police Station.";
SmsManager smsManager = SmsManager.getDefault();
DatabaseHelper db = new DatabaseHelper(SensorService.this);
List<ContactInfo> list = (List<ContactInfo>) db.getEveryone();
String[] phoneNumberList = new String[contactNumbers.size()];
phoneNumberList = contactNumbers.toArray(phoneNumberList);
for (String c : phoneNumberList) {
smsManager.sendTextMessage(c, null, message, null, null);
}
}
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.d("Check: ", "OnFailure");
String message = "I am in DANGER, i need help. Please urgently reach me out.\n" + "GPS was turned off.Couldn't find location. Call your nearest Police Station.";
SmsManager smsManager = SmsManager.getDefault();
DatabaseHelper db = new DatabaseHelper(SensorService.this);
List<ContactInfo> list = (List<ContactInfo>) db.getEveryone();
String[] phoneNumberList = new String[contactNumbers.size()];
phoneNumberList = contactNumbers.toArray(phoneNumberList);
for (String c : phoneNumberList){
smsManager.sendTextMessage(c, null, message, null, null);
}
}
});
}
}
});
// register the listener
mSensorManager.registerListener(mShakeDetector, mAccelerometer, SensorManager.SENSOR_DELAY_UI);
}
// method to vibrate the phone
public void vibrate() {
final Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
VibrationEffect vibEff;
// Android Q and above have some predefined vibrating patterns
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
vibEff = VibrationEffect.createPredefined(VibrationEffect.EFFECT_DOUBLE_CLICK);
vibrator.cancel();
vibrator.vibrate(vibEff);
} else {
vibrator.vibrate(500);
}
}
// For Build versions higher than Android Oreo, we launch
// a foreground service in a different way. This is due to the newly
// implemented strict notification rules, which require us to identify
// our own notification channel in order to view them correctly.
@RequiresApi(Build.VERSION_CODES.O)
private void startMyOwnForeground() {
String NOTIFICATION_CHANNEL_ID = "example.permanence";
String channelName = "Background Service";
NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_MIN);
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
assert manager != null;
manager.createNotificationChannel(chan);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
Notification notification = notificationBuilder.setOngoing(true)
.setContentTitle("You are protected.")
.setContentText("We are there for you")
// this is important, otherwise the notification will show the way
// you want i.e. it will show some default notification
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setPriority(NotificationManager.IMPORTANCE_MIN)
.setCategory(Notification.CATEGORY_SERVICE)
.build();
startForeground(2, notification);
}
@Override
public void onDestroy() {
// create an Intent to call the Broadcast receiver
Intent broadcastIntent = new Intent();
broadcastIntent.setAction("restartservice");
broadcastIntent.setClass(this, ReactivateService.class);
this.sendBroadcast(broadcastIntent);
super.onDestroy();
}
public void setPhoneNumberArray(ArrayList numbers) {
contactNumbers=numbers;
//Log.d(TAG, "setPhoneNumberArray: contactnumbers size = "+contactNumbers.size());
}
}
would really appreciate if anyone could tell me why this is happening.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我发现我的错误。
对于任何其他试图做到这一点的人。
我犯了一个非常近视的错误,因为不将arraylist
contactnumbers
为静态。这就是以前的样子。
public ArrayList&lt; string&gt; 当我添加静态关键字时,ContactNumbers;
最后。这样它看起来像
静态public ArrayList&lt; string&gt; ContactNumbers;
。其他一切似乎都可以纠正。由于我现在可以在服务内部获得
Contactnumbers
的值。I found my mistake.
For anyone else trying to do this.
I made the very shortsighted mistake of not declaring the Arraylist
contactNumbers
as static.This is what it looked like before.
public ArrayList<String> contactNumbers;
In the end when I added the static keyword. such that it looks like
static public ArrayList<String> contactNumbers;
.Everything else seems to work corrrectly. Since I could now get the value of
contactNumbers
inside of the service.