我试图在单击按钮后从Service
开始Activity
。但是Service
尚未开始。我的想法是使用Service
将一些数据从Activity
发送到Handler
。
我的AndroidManifest.xml
文件:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.myfirstandroidapp">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true">
<activity android:name=".servicesdemo.CountrySearchActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name="com.myfirstandroidapp.servicesdemo.MyRESTRequestService"
android:enabled="false"
android:exported="false" ></service>
</application>
</manifest>
我的Service
班:
public class MyRESTRequestService extends Service {
private static final String TAG = "MyRESTRequestService";
private ExecutorService threadPool =
Executors.newSingleThreadExecutor();
private Country country = null;
private Message message = new Message();
public MyRESTRequestService() {}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
String countryName = (String) intent
.getCharSequenceExtra("COUNTRY_NAME");
Handler handler = intent.getParcelableExtra("HANDLER");
threadPool.execute(() -> {
try {
country = new HTTPHandler()
.getCountryByName(countryName);
message.obj = country;
message.what = 1;
handler.sendMessage(message);
Log.d(TAG, country.toString());
} catch (IOException e) {
e.printStackTrace();
}
});
return super.onStartCommand(intent, flags, startId);
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
我的Activity
班:
public class CountrySearchActivity extends AppCompatActivity implements MyHandler.IUIUpdater {
@BindView(R.id.btn_get_country_from_webservice)
Button btnGetCountryFromWebService;
@BindView(R.id.tv_container_country_name)
EditText countryNameEntryField;
@BindView(R.id.tv_obtained_country)
TextView resultingCountry;
private void getCountryFromWebService() {
String countryNameForGetting = countryNameEntryField
.getText()
.toString();
Handler handler = new MyHandler(this);
Intent intent = new Intent(getApplicationContext(),
MyRESTRequestService.class);
intent.putExtra("COUNTRY_NAME", countryNameForGetting);
intent.putExtra("HANDLER", new Messenger(handler));
ContextCompat.startForegroundService(getApplicationContext(),
intent);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_country_search);
ButterKnife.bind(this);
btnGetCountryFromWebService.setOnClickListener(v ->
getCountryFromWebService());
}
@Override
public void updateTheUi(Message message) {
resultingCountry.setText((String) message.obj);
stopService(new Intent(getApplicationContext(),
MyRESTRequestService.class));
}
}
我的Handler
班:
public class MyHandler extends Handler {
IUIUpdater iuiUpdater;
public MyHandler(IUIUpdater iuiUpdater) {
this.iuiUpdater = iuiUpdater;
}
@Override
public void handleMessage(Message msg) {
iuiUpdater.updateTheUi(msg);
}
public interface IUIUpdater {
void updateTheUi(Message message);
}
}
我调试了,在调用ContextCompat.startForegroundService(getApplicationContext(), intent)
之后在服务类中没有遇到任何断点。断点放置在Service
方法的onCreate()
,onStartCommand()
方法的构造函数中(这里没有显示,但它在那里)。
答案 0 :(得分:1)
您必须显示通知并请求<form id="MyForm">
text 1
<input type="text"><br />
text 2
<input type="text"><br />
un-ticked checkbox
<input type="checkbox"><br />
ticked checkbox
<input type="checkbox" checked><br />
<select>
<option>Value 1</option>
<option>Value 2</option>
<option>Value 3</option>
<option>Value 4</option>
</select><br />
<input type="radio" id="val1" name="radio" value="1" checked>
<label for="val1">Value 1</label><br />
<input type="radio" id="val2" name="radio" value="2">
<label for="val2">Value 2</label><br />
<input type="radio" id="val3" name="radio" value="3">
<label for="val3">Value 3</label><br />
<input type="hidden" id="MyHidden" value="42">
<button type="button" onclick="resetForm()">Reset</button>
</form>
权限才能启动前台服务。
请检查Android Developers docs
答案 1 :(得分:1)
我更改了您的服务等级。请尝试一下。
在CountrySearchActivity类中:
String countryNameForGetting = countryNameEntryField
.getText()
.toString();
Handler handler = new MyHandler(this);
Intent intent = new Intent(getApplicationContext(),
MyRESTRequestService.class);
intent.putExtra("COUNTRY_NAME", countryNameForGetting);
intent.putExtra("HANDLER", new Messenger(handler));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
ContextCompat.startForegroundService(this, intent);
else
startService(intent);
服务等级:
public class MyRESTRequestService extends Service {
private static final String TAG = "MyRESTRequestService";
private ExecutorService threadPool =
Executors.newSingleThreadExecutor();
private Country country = null;
private Message message = new Message();
private static final String NOTIFICATION_CHANNEL_ID = "running_service";
public MyRESTRequestService() {}
@Override
public void onCreate() {
super.onCreate();
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
.setOngoing(false)
.setSmallIcon(R.mipmap.ic_launcher)
.setPriority(Notification.PRIORITY_MIN);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID,
NOTIFICATION_CHANNEL_ID, NotificationManager.IMPORTANCE_LOW);
notificationChannel.setDescription(NOTIFICATION_CHANNEL_ID);
notificationChannel.setSound(null, null);
notificationManager.createNotificationChannel(notificationChannel);
startForeground(1, builder.build());
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
String countryName = (String) intent
.getCharSequenceExtra("COUNTRY_NAME");
Handler handler = intent.getParcelableExtra("HANDLER");
threadPool.execute(() -> {
try {
country = new HTTPHandler()
.getCountryByName(countryName);
message.obj = country;
message.what = 1;
handler.sendMessage(message);
Log.d(TAG, country.toString());
} catch (IOException e) {
e.printStackTrace();
}
});
return super.onStartCommand(intent, flags, startId);
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
在AndroidManifest.xml
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<application
....
<service
android:name=".MyRESTRequestService"
android:enabled="true"
android:exported="true" />
</application>