Reputation: 15
I am making an app which reads the SMS from the phone and sends SMS from a particular sender to a server. I want to have to app run in background using Service but its not working. The app is crashing when I try to start the Service.
(If I play some music using Mediaplayer the Service works fine but I think there is some problem with the method calling when I try to run sendingData() when the Service starts)
Here are the relevant code :
MainActivity.java
package com.example.texter;
import android.content.ContentResolver;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Handler;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
public class MainActivity extends AppCompatActivity {
private static MainActivity inst;
ArrayList<String> smsMessagesList = new ArrayList<String>();
ListView smsListView;
ArrayAdapter arrayAdapter;
Timer timer;
static String smssender;
Button stopButton;
Button startButton;
static String content;
public static MainActivity instance() {
return inst;
}
@Override
public void onStart() {
super.onStart();
inst = this;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
smsListView = (ListView) findViewById(R.id.SMSlist);
startButton = (Button) findViewById(R.id.button2);
stopButton = (Button) findViewById(R.id.stopbtn);
arrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, smsMessagesList);
smsListView.setAdapter(arrayAdapter);
// Todo : If Permission Is Not GRANTED
if(ContextCompat.checkSelfPermission(getBaseContext(), "android.permission.READ_SMS") == PackageManager.PERMISSION_GRANTED) {
// Todo : If Permission Granted Then Show SMS
refreshSmsInbox();
} else {
// Todo : Then Set Permission
final int REQUEST_CODE_ASK_PERMISSIONS = 123;
ActivityCompat.requestPermissions(MainActivity.this, new String[]{"android.permission.READ_SMS"}, REQUEST_CODE_ASK_PERMISSIONS);
Toast.makeText(this, "Please allow permissions to read SMS", Toast.LENGTH_SHORT).show();
}
timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
Intent intent = new Intent(MainActivity.this, MainActivity.class);
overridePendingTransition(0, 0); //to avoid blinking on refresh
startActivity(intent);
overridePendingTransition(0, 0);
}
}, 10000);
}
public void refreshSmsInbox() {
ContentResolver contentResolver = getContentResolver();
Cursor smsInboxCursor = contentResolver.query(Uri.parse("content://sms/inbox"), null, null, null, null);
int indexBody = smsInboxCursor.getColumnIndex("body");
int indexAddress = smsInboxCursor.getColumnIndex("address");
if (indexBody < 0 || !smsInboxCursor.moveToFirst()) return;
arrayAdapter.clear();
do {
String str = "SMS From: " + smsInboxCursor.getString(indexAddress) +
"\n" + smsInboxCursor.getString(indexBody) + "\n";
arrayAdapter.add(str);
} while (smsInboxCursor.moveToNext());
smsInboxCursor.moveToFirst();
if (smsInboxCursor.getString(indexAddress).equalsIgnoreCase("JX-JioSvc")) {
//NOW SEND TO SERVER
Toast.makeText(MainActivity.this,"Yes, JX-JioSvc", Toast.LENGTH_SHORT).show();
content = smsInboxCursor.getString(indexBody);
this.sendingData();
}
else {
Toast.makeText(MainActivity.this, "No, JX-JioSvc", Toast.LENGTH_SHORT).show();
}
}
public void updateList(final String smsMessage) {
arrayAdapter.insert(smsMessage, 0);
arrayAdapter.notifyDataSetChanged();
}
public void sendingData() {
String url = "---IP HERE---";
StringRequest stringRequest = new StringRequest(Request.Method.POST, url,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
Toast.makeText(MainActivity.this, response.trim(), Toast.LENGTH_LONG).show();
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(MainActivity.this, error.toString(), Toast.LENGTH_LONG).show();
}
}) {
@Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("data", content);
return params;
}
};
RequestQueue requestQueue = Volley.newRequestQueue(MainActivity.this);
requestQueue.add(stringRequest);
}
public void startService(View view) {
startService(new Intent(this, Service.class));
}
public void stopService(View view) {
stopService(new Intent(this, Service.class));
}
}
Service.java
package com.example.texter;
import android.content.Intent;
import android.os.IBinder;
import android.widget.Toast;
import androidx.annotation.Nullable;
public class Service extends android.app.Service {
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "Service Started", Toast.LENGTH_SHORT).show();
MainActivity object = new MainActivity();
object.sendingData();
return START_STICKY;
}
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
}
}
Upvotes: 0
Views: 70
Reputation: 2722
We should not create a MainActivity object to call API.Instead create a Local broadcast from Main Activity and register for broadcast.When you want to call API,just send broadcast to MainActivity to trigger API.For creating local broadcast,you can check below link.
How to use LocalBroadcastManager?
Upvotes: 1