我想在初始運行後啓動一個Android應用程序作爲後臺服務。第一次運行時,應用程序應該像普通的Android應用程序一樣啓動,然後應該是一個後臺服務,即使在啓動後它仍然可以運行。我寫了下面的代碼。該服務類被驗證爲獨立的Android應用程序。但是這個應用沒有按預期運行。沒有錯誤代碼,但是當調試時,服務類不起作用。如何啓動後啓動Android應用程序作爲服務
清單文件:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tulga.nar.mytrack">
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<receiver android:name=".MyBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:label="@string/title_activity_main"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
初步一次運行活動類:
package com.tulga.nar.mytrack;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.content_main);
}
public void starterHandler(View v)
{
new MyBroadcastReceiver();
}
}
初步一次運行活動類的XML:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.tulga.nar.mytrack.MainActivity">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/starter"
android:text="start service"
android:onClick="starterHandler"/>
</android.support.constraint.ConstraintLayout>
廣播重ceiver類。它在啓動服務按鈕被點擊後從MainActivity調用。它應該開始後臺MyService類。
package com.tulga.nar.mytrack;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context aContext, Intent aIntent) {
// This is where you start your service
aContext.startService(new Intent(aContext, MyService.class));
}
}
這是後臺MyService類。該課程已經過驗證,可用作獨立應用程序。但是在這裏,調試時代碼執行沒有到達這裏。
package com.tulga.nar.mytrack;
import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.Settings;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
/**
* Created by Home on 8/27/2017.
*/
public class MyService extends AppCompatActivity implements
LocationListener
{
private class SendDeviceDetails extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... params) {
String data = "";
HttpURLConnection connection = null;
try {
URL url=new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty("Content-Type",
"application/json");
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.connect();
DataOutputStream wr = new
DataOutputStream(connection.getOutputStream());
wr.writeBytes(params[1]);
wr.flush();
wr.close();
InputStream in = connection.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(in);
int inputStreamData = inputStreamReader.read();
while (inputStreamData != -1) {
char current = (char) inputStreamData;
inputStreamData = inputStreamReader.read();
data += current;
}
} //catch (Exception e) {
//e.printStackTrace();
//}
catch (MalformedURLException e) {
e.printStackTrace();}
catch (IOException e) {
e.printStackTrace();
}
finally {
if (connection != null) {
connection.disconnect();
}
}
return data;
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
Log.e("TAG", result); // this is expecting a response code to be
sent from your server upon receiving the POST data
}
}
public static final int RequestPermissionCode = 1 ;
static public double myLong=151;
static public double myLat=-34;
static public String _id=null;
static public String _rev=null;
Button buttonEnable, buttonGet ;
TextView textViewLongitude, textViewLatitude ;
Context context;
Intent intent1 ;
Location location;
LocationManager locationManager ;
boolean GpsStatus = false ;
Criteria criteria ;
String Holder;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main);
EnableRuntimePermission();
locationManager = (LocationManager)
getSystemService(Context.LOCATION_SERVICE);
criteria = new Criteria();
Holder = locationManager.getBestProvider(criteria, false);
context = getApplicationContext();
CheckGpsStatus();
JSONObject postData = new JSONObject();
try {
postData.put("_id",String.valueOf(""));
postData.put("Lat",
String.valueOf(String.valueOf(MyService.myLat)));
postData.put("Long",
String.valueOf(String.valueOf(MyService.myLong)));
postData.put("_rev",String.valueOf("1-
62076042d87cacd2711268d4a396129b"));
new SendDeviceDetails().execute("my-server-name/mydatabase",
postData.toString());
}
catch (JSONException e) {
e.printStackTrace();
}
}
@Override
public void onLocationChanged(Location location) {
textViewLongitude.setText("Longitude:" + location.getLongitude());
textViewLatitude.setText("Latitude:" + location.getLatitude());
myLong=location.getLongitude();
myLat=location.getLatitude();
}
@Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
@Override
public void onProviderEnabled(String s) {
}
@Override
public void onProviderDisabled(String s) {
}
public void CheckGpsStatus(){
locationManager =
(LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
GpsStatus =
locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
}
public void EnableRuntimePermission(){
if (ActivityCompat.shouldShowRequestPermissionRationale(MyService.this,
Manifest.permission.ACCESS_FINE_LOCATION))
{
Toast.makeText(MyService.this,"ACCESS_FINE_LOCATION permission
allows us to Access GPS in app", Toast.LENGTH_LONG).show();
} else {
ActivityCompat.requestPermissions(MyService.this,new String[]{
Manifest.permission.ACCESS_FINE_LOCATION},
RequestPermissionCode);
}
}
@Override
public void onRequestPermissionsResult(int RC, String per[], int[] PResult)
{
switch (RC) {
case RequestPermissionCode:
if (PResult.length > 0 && PResult[0] ==
PackageManager.PERMISSION_GRANTED) {
Toast.makeText(MyService.this,"Permission Granted, Now your
application can access GPS.", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(MyService.this,"Permission Canceled, Now your
application cannot access GPS.", Toast.LENGTH_LONG).show();
}
break;
}
}
的''元素都有在''標籤之間移動,就像''一樣。你還需要''MyService'的''元素,在同一個地方。 –
不確定這是否與您的情況相關,但用戶必須在調用任何廣播接收器之前手動啓動應用程序。必須在強制關閉後再次手動啓動。 –
第一次用戶必須手動啓動我的應用程序,並在此之後,只有服務將保持即使重新啓動後。 –