Androidは初めてです。
放送受信機でGPSロケーションを取得したいのですが、エラーが表示されます。
私のコードは:
public void onReceive(Context context, Intent intent) {
LocationManager locManager = (LocationManager)
getSystemService(Context.LOCATION_SERVICE);
// errors in getSystemService method
LocationListener locListener = new MyLocationListener();
locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0,
locListener);
Location loc = locManager
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
Log.d(" **location**", " location" + loc.getLatitude());
}
質問:
BroadcastReceiverから、Location Managerも起動できませんでした。そのため、BroadcastReceiverでサービスを開始し、そのサービスでLocation Managerを操作しました。この解決策はAndroid開発ドキュメントにあります。サービスの代わりにアクティビティを開始することもできます。
BroadcastReceiverでサービスに切り替えるコードは次のとおりです。
これをonReceive
メソッドに書き込む
Intent serviceIntent = new Intent(context,MyService.class);
serviceIntent.putExtra("locateRequest", "locateRequest"); // if you want pass parameter from here to service
serviceIntent.putExtra("queryDeviceNumber", results[1]);
context.startService(serviceIntent); //start service for get location
はい、どちらも可能です。
一定の時間内に位置レシーバーにリクエストを送信するタイマー付きのサービス:
public class SrvPositioning extends Service {
// An alarm for rising in special times to fire the
// pendingIntentPositioning
private AlarmManager alarmManagerPositioning;
// A PendingIntent for calling a receiver in special times
public PendingIntent pendingIntentPositioning;
@Override
public void onCreate() {
super.onCreate();
alarmManagerPositioning = (AlarmManager)
getSystemService(Context.ALARM_SERVICE);
Intent intentToFire = new Intent(
ReceiverPositioningAlarm.ACTION_REFRESH_SCHEDULE_ALARM);
intentToFire.putExtra(ReceiverPositioningAlarm.COMMAND,
ReceiverPositioningAlarm.SENDER_SRV_POSITIONING);
pendingIntentPositioning = PendingIntent.getBroadcast(this, 0,
intentToFire, 0);
};
@Override
public void onStart(Intent intent, int startId) {
try {
long interval = 60 * 1000;
int alarmType = AlarmManager.ELAPSED_REALTIME_WAKEUP;
long timetoRefresh = SystemClock.elapsedRealtime();
alarmManagerPositioning.setInexactRepeating(alarmType,
timetoRefresh, interval, pendingIntentPositioning);
} catch (NumberFormatException e) {
Toast.makeText(this,
"error running service: " + e.getMessage(),
Toast.LENGTH_SHORT).show();
} catch (Exception e) {
Toast.makeText(this,
"error running service: " + e.getMessage(),
Toast.LENGTH_SHORT).show();
}
}
@Override
public IBinder onBind(Intent arg0) {
return null;
}
@Override
public void onDestroy() {
this.alarmManagerPositioning.cancel(pendingIntentPositioning);
ReceiverPositioningAlarm.stopLocationListener();
}
}
リスナーとあなたの受信機。リスナーをアクティビティで使用して、新しい場所の準備ができたことを通知できます。
public class ReceiverPositioningAlarm extends BroadcastReceiver {
public static final String COMMAND = "SENDER";
public static final int SENDER_ACT_DOCUMENT = 0;
public static final int SENDER_SRV_POSITIONING = 1;
public static final int MIN_TIME_REQUEST = 5 * 1000;
public static final String ACTION_REFRESH_SCHEDULE_ALARM =
"org.mabna.order.ACTION_REFRESH_SCHEDULE_ALARM";
private static Location currentLocation;
private static Location prevLocation;
private static Context _context;
private String provider = LocationManager.GPS_PROVIDER;
private static Intent _intent;
private static LocationManager locationManager;
private static LocationListener locationListener = new LocationListener() {
@Override
public void onStatusChanged(String provider, int status, Bundle extras){
try {
String strStatus = "";
switch (status) {
case GpsStatus.GPS_EVENT_FIRST_FIX:
strStatus = "GPS_EVENT_FIRST_FIX";
break;
case GpsStatus.GPS_EVENT_SATELLITE_STATUS:
strStatus = "GPS_EVENT_SATELLITE_STATUS";
break;
case GpsStatus.GPS_EVENT_STARTED:
strStatus = "GPS_EVENT_STARTED";
break;
case GpsStatus.GPS_EVENT_STOPPED:
strStatus = "GPS_EVENT_STOPPED";
break;
default:
strStatus = String.valueOf(status);
break;
}
Toast.makeText(_context, "Status: " + strStatus,
Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onProviderEnabled(String provider) {}
@Override
public void onProviderDisabled(String provider) {}
@Override
public void onLocationChanged(Location location) {
try {
Toast.makeText(_context, "***new location***",
Toast.LENGTH_SHORT).show();
gotLocation(location);
} catch (Exception e) {
}
}
};
// received request from the calling service
@Override
public void onReceive(final Context context, Intent intent) {
Toast.makeText(context, "new request received by receiver",
Toast.LENGTH_SHORT).show();
_context = context;
_intent = intent;
locationManager = (LocationManager) context
.getSystemService(Context.LOCATION_SERVICE);
if (locationManager.isProviderEnabled(provider)) {
locationManager.requestLocationUpdates(provider,
MIN_TIME_REQUEST, 5, locationListener);
Location gotLoc = locationManager
.getLastKnownLocation(provider);
gotLocation(gotLoc);
} else {
Toast t = Toast.makeText(context, "please turn on GPS",
Toast.LENGTH_LONG);
t.setGravity(Gravity.CENTER, 0, 0);
t.show();
Intent settinsIntent = new Intent(
Android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
settinsIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
_context.startActivity(settinsIntent);
}
}
private static void gotLocation(Location location) {
prevLocation = currentLocation == null ? null : new Location(
currentLocation);
currentLocation = location;
if (isLocationNew()) {
OnNewLocationReceived(location);
Toast.makeText(_context, "new location saved",
Toast.LENGTH_SHORT).show();
stopLocationListener();
}
}
private static boolean isLocationNew() {
if (currentLocation == null) {
return false;
} else if (prevLocation == null) {
return true;
} else if (currentLocation.getTime() == prevLocation.getTime()) {
return false;
} else {
return true;
}
}
public static void stopLocationListener() {
locationManager.removeUpdates(locationListener);
Toast.makeText(_context, "provider stoped", Toast.LENGTH_SHORT)
.show();
}
// listener ----------------------------------------------------
static ArrayList<OnNewLocationListener> arrOnNewLocationListener =
new ArrayList<OnNewLocationListener>();
// Allows the user to set a OnNewLocationListener outside of this class
// and react to the event.
// A sample is provided in ActDocument.Java in method: startStopTryGetPoint
public static void setOnNewLocationListener(
OnNewLocationListener listener) {
arrOnNewLocationListener.add(listener);
}
public static void clearOnNewLocationListener(
OnNewLocationListener listener) {
arrOnNewLocationListener.remove(listener);
}
// This function is called after the new point received
private static void OnNewLocationReceived(Location location) {
// Check if the Listener was set, otherwise we'll get an Exception
// when we try to call it
if (arrOnNewLocationListener != null) {
// Only trigger the event, when we have any listener
for (int i = arrOnNewLocationListener.size() - 1; i >= 0; i--) {
arrOnNewLocationListener.get(i).onNewLocationReceived(
location);
}
}
}
}
リスナーのインターフェース:
import Android.location.Location;
public interface OnNewLocationListener {
public abstract void onNewLocationReceived(Location location);
}
たった1ポイントを獲得するためのアクティビティ:
protected void btnGetPoint_onClick() {
Intent intentToFire = new Intent(
ReceiverPositioningAlarm.ACTION_REFRESH_SCHEDULE_ALARM);
intentToFire.putExtra(ReceiverPositioningAlarm.COMMAND,
ReceiverPositioningAlarm.SENDER_ACT_DOCUMENT);
sendBroadcast(intentToFire);
OnNewLocationListener onNewLocationListener = new OnNewLocationListener() {
@Override
public void onNewLocationReceived(Location location) {
// use your new location here then stop listening
ReceiverPositioningAlarm.clearOnNewLocationListener(this);
}
};
// start listening for new location
ReceiverPositioningAlarm
.setOnNewLocationListener(onNewLocationListener);
}
編集:
アクティビティでサービスを開始する場合:
this.startService(new Intent(this, SrvPositioning.class));
同様に、受信者が見つけた場所を受信するために、サービスにリスナーを定義できます
編集
マニフェストに次の行を追加します
<service
Android:name="org.mabna.order.services.SrvPositioning"
Android:enabled="true" />
<receiver Android:name="org.mabna.order.receivers.ReceiverPositioningAlarm" >
<!-- this Broadcast Receiver only listens to the following intent -->
<intent-filter>
<action Android:name="org.mabna.order.ACTION_REFRESH_SCHEDULE_ALARM" />
</intent-filter>
</receiver>
STEP 1:開くAndroidManifest.xmlとブロードキャストレシーバーを追加します。
<receiver
Android:name=".Util.GpsConnectorReceiver"
Android:enabled="true">
<intent-filter>
<!-- Intent filters for broadcast receiver -->
<action Android:name="Android.location.PROVIDERS_CHANGED" />
<category Android:name="Android.intent.category.DEFAULT" />
</intent-filter>
</receiver>`
ステップ2:ダイアログテーマでアクティビティを作成:
<activity
Android:name=".Activity.ActivityDialogGps"
Android:theme="@style/AppTheme.Dark.Dialog"></activity>
STEP 3: BroadcastReceiverクラスを作成GpsConnectorReceiver
public class GpsConnectorReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().matches("Android.location.PROVIDERS_CHANGED")) {
Intent pushIntent = new Intent(context, ConnectivityCheck .class);
context.startService(pushIntent);
}
}}
ステップ4:ConnectivityCheckという名前の別のサービスクラスを作成します。
public class ConnectivityCheck extends Service {
@Override
public void onCreate() {
super.onCreate();
if (!checkConnection()) {
Toast.makeText(context, "off", Toast.LENGTH_LONG).show();
Intent dialogIntent = new Intent(this, ActivityDialogInternet.class);
dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(dialogIntent);
}
stopSelf();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
private boolean checkConnection() {
final LocationManager manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
return manager.isProviderEnabled(LocationManager.GPS_PROVIDER);
}}
STEP 5:というアクティビティを作成しますActivityDialogGps
public class ActivityDialogGps extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dialog_gps);
}}
ステップ6: Gps接続がオフの場合ActivityDialogGps呼び出されてダイアログを表示します: