Android: 如何从服务中调用方法
Android: How to call a method from a Service
我正在制作一个应用程序,它从 phone 读取短信并将短信从特定发件人发送到服务器。我想使用服务在后台应用 运行,但它不起作用。当我尝试启动服务时,应用程序崩溃了。
(如果我使用 Mediaplayer 播放一些音乐,服务工作正常,但我认为当我尝试 运行 sendingData() 服务启动时调用的方法存在一些问题)
相关代码如下:
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();
}
}
我们不应该创建 MainActivity 对象来调用 API.Instead 从 Main 创建本地广播 Activity 并注册要调用的 broadcast.When API,发送广播到MainActivity即可触发API.For创建本地广播,可查看下方link.
How to use LocalBroadcastManager?
我正在制作一个应用程序,它从 phone 读取短信并将短信从特定发件人发送到服务器。我想使用服务在后台应用 运行,但它不起作用。当我尝试启动服务时,应用程序崩溃了。
(如果我使用 Mediaplayer 播放一些音乐,服务工作正常,但我认为当我尝试 运行 sendingData() 服务启动时调用的方法存在一些问题)
相关代码如下:
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();
}
}
我们不应该创建 MainActivity 对象来调用 API.Instead 从 Main 创建本地广播 Activity 并注册要调用的 broadcast.When API,发送广播到MainActivity即可触发API.For创建本地广播,可查看下方link.
How to use LocalBroadcastManager?