aViShEk ChAkRaBoRtY
aViShEk ChAkRaBoRtY

Reputation: 15

Android: How to call a method from a Service

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

Answers (1)

Tarun Anchala
Tarun Anchala

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

Related Questions