0

ユーザーがボタンをクリックすると、メインアクティビティがブロードキャストレシーバーを呼び出し、次にサービスを呼び出して、ユーザーの GPS 位置を特定の間隔で電子メールアドレスに送信するこのアプリケーションが既にあります。アプリは問題なく動作します。

ただし、私がやりたいことは、ユーザーがデバイスの電源ボタンをアクティブにすると、ブロードキャスト レシーバーがアクティブになることです。これまでのところ、この質問を見て、それを使用したので、マニフェスト ファイルは次のようになります。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.angelo.serviceexample"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk
    android:minSdkVersion="10"
    android:targetSdkVersion="16" />

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET" /> 

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name="com.angelo.serviceexample.MainActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <action android:name="android.permission.PREVENT_POWER_KEY" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <service android:name="com.angelo.serviceexample.GPSLoggerService" />
    <receiver android:name="com.angelo.serviceexample.AlarmReceiver">
        <intent-filter>
            <action android:name="android.intent.action.SCREEN_OFF"></action>
            <action android:name="android.intent.action.SCREEN_ON"></action>
            <action android:name="android.intent.action.ACTION_POWER_CONNECTED">    </action>
            <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED"></action>
             <action android:name="android.intent.action.ACTION_SHUTDOWN"></action>
        </intent-filter>
    </receiver>

</application>

</manifest>

また、Broadcast Receiver クラスには、アクティブ化されたときに呼び出すためのインテント フィルターがあります。これまでのところ、AlarmReceiver.java ファイルは次のようになっています。

package com.angelo.serviceexample;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

public class AlarmReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        context.startService(new Intent(context,GPSLoggerService.class));
        //Toast.makeText(, "power button clicked",Toast.LENGTH_LONG).show();
        Log.v("Tag", "AlarmReceiver called.");
    }
}

ただし、LogCat をチェックしていたときは、ユーザーがメイン アクティビティのボタンを押すたびに、次のようにログがアクティブになります。

public class MainActivity extends Activity {
  private int currentIntervalChoice = 0;

  @Override
  public boolean dispatchKeyEvent(KeyEvent event) {
    if (event.getKeyCode() == KeyEvent.KEYCODE_POWER) {
        setAppInfo();
        addButtonListeners();
        enableControls();
        return true;
    }

    return super.dispatchKeyEvent(event);
  }

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    setAppInfo();
    addButtonListeners();
    enableControls();
  }

  private void setAppInfo() {
    TextView txtInfo = (TextView)findViewById(R.id.app_info);
    txtInfo.setText(Html.fromHtml(getString(R.string.app_info)));
    Linkify.addLinks(txtInfo, Linkify.ALL);
  }

  private void addButtonListeners() {
    ((Button)findViewById(R.id.start_logging)).setOnClickListener(btnClick);
    ((Button)findViewById(R.id.logging_interval)).setOnClickListener(btnClick);
  }

  private void enableControls(){
    boolean isServiceRunning = AppSettings.getServiceRunning(this);
    String buttonText = getString(R.string.start_logging);

    if(isServiceRunning){
            buttonText = getString(R.string.stop_logging);

            ((Button)findViewById(R.id.logging_interval)).setEnabled(false);
    }
    else{
            ((Button)findViewById(R.id.logging_interval)).setEnabled(true);
    }

    ((Button)findViewById(R.id.start_logging)).setText(buttonText);
  }

  private void changeLoggingIntercal(){
    final AlertDialog.Builder builder = new AlertDialog.Builder(this);
    final String loggingIntervals[] = { "1 minute", "3 minute", "5 minutes", "10 minutes" }; 

    builder.setTitle(getString(R.string.logging_interval));
    builder.setSingleChoiceItems(loggingIntervals, currentIntervalChoice, new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
                currentIntervalChoice = which;

                setLoggingInterval(currentIntervalChoice);

                dialog.dismiss();
        }
    });

  builder.show();
  }

  private void setLoggingInterval(int intervalChoice){
    int interval = 1;

    switch(intervalChoice){
            case 0:         interval = 1;   break;
            case 1:         interval = 3;  break;
            case 2:         interval = 5;  break;
            case 3:         interval = 10;  break;
            default:        interval = 1;   break;
    }

    AppSettings.setLoggingInterval(this, interval);
  }

  public void setLogFileName(){
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    String dateString = sdf.format(new Date());
    String filename = "GPSLog." + dateString + ".kml";

    AppSettings.setLogFileName(this, filename);
  }

  private View.OnClickListener btnClick = new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        switch(v.getId()){
            case R.id.start_logging:{
                    toggleLogging(AppSettings.getServiceRunning(MainActivity.this), 
                                              AppSettings.getLoggingInterval(MainActivity.this));
                    enableControls();       
                    break;
            }
            case R.id.logging_interval:{
                    changeLoggingIntercal();
                    break;
            }
        }
    }
  };

  private void toggleLogging(boolean isStart, int interval){
    AlarmManager manager = (AlarmManager)getSystemService(Service.ALARM_SERVICE);
    PendingIntent loggerIntent = PendingIntent.getBroadcast(this, 0,new Intent(this,AlarmReceiver.class), 0);

    if(isStart){
        manager.cancel(loggerIntent);

        AppSettings.setServiceRunning(this, false);

        AppLog.logString("Service Stopped.");
    }
    else{
        setLogFileName();

        long duration = interval * 60 * 1000;

        manager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
                        SystemClock.elapsedRealtime(), duration, loggerIntent);
        AppSettings.setServiceRunning(this, true);
        Toast.makeText(getApplicationContext(), "Service Started with interval " + interval 
                + ", Logfile name: " + AppSettings.getLogFileName(this), Toast.LENGTH_LONG).show();
        AppLog.logString("Service Started with interval " + interval 
                + ", Logfile name: " + AppSettings.getLogFileName(this));
    }
  }
}

また、これは問題のサービス クラスです。

public class GPSLoggerService extends Service implements LocationListener{

    private static final int gpsMinTime = 500;
    private static final int gpsMinDistance = 0;
    private static final int TIMER_DELAY = 1000;

    private LocationManager manager = null;
    private double latitude = 0.0;
    private double longitude = 0.0;
    private Timer monitoringTimer = null;

    public GPSLoggerService() {
        AppLog.logString("GPSLoggerService.GPSLoggerService().");
    }

    @Override
    public IBinder onBind(Intent arg0) {
        AppLog.logString("GPSLoggerService.onBind().");
        return null;
    }

    @Override
    public void onCreate() {
        AppLog.logString("GPSLoggerService.onCreate().");
        super.onCreate();
    }

    public int onStartCommand(Intent intent, int flags, int startId) {
        AppLog.logString("GPSLoggerService.onStartCommand().");
        startLoggingService();
        startMonitoringTimer();
        return Service.START_STICKY;
    }

    @Override
    public void onLocationChanged(Location location) {
        AppLog.logString("GPSLoggerService.onLocationChanged().");

        latitude = location.getLatitude();
        longitude = location.getLongitude();
    }

    @Override
    public void onProviderDisabled(String provider) {
        AppLog.logString("GPSLoggerService.onProviderDisabled().");
    }

    @Override
    public void onProviderEnabled(String provider) {
        AppLog.logString("GPSLoggerService.onProviderEnabled().");
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
        AppLog.logString("GPSLoggerService.onStatusChanged().");
    }

    private void startLoggingService(){
        if (manager == null){
            manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        }

        final Criteria criteria = new Criteria();

        criteria.setAccuracy(Criteria.ACCURACY_FINE);
        criteria.setAltitudeRequired(false);
        criteria.setBearingRequired(false);
        criteria.setCostAllowed(true);
        criteria.setPowerRequirement(Criteria.POWER_LOW);

        final String bestProvider = manager.getBestProvider(criteria, true);

        if (bestProvider != null && bestProvider.length() > 0){
            manager.requestLocationUpdates(bestProvider, gpsMinTime,gpsMinDistance, this);
        }
        else{
            final List<String> providers = manager.getProviders(true);

            for (final String provider : providers){
                manager.requestLocationUpdates(provider, gpsMinTime, gpsMinDistance, this);
            }
        }
    }

    private void stopLoggingService(){
            stopSelf();
    }

    private void startMonitoringTimer(){
        monitoringTimer = new Timer();

        monitoringTimer.scheduleAtFixedRate(
        new TimerTask(){

            @Override
            public void run(){

                if (longitude != 0.0 && latitude != 0.0){
                    monitoringTimer.cancel();
                    monitoringTimer = null;

                    manager.removeUpdates(GPSLoggerService.this);

                    sendCoordinates(latitude, longitude);
                    stopLoggingService();
                }
            }
        }, 
        GPSLoggerService.TIMER_DELAY,
        GPSLoggerService.TIMER_DELAY);
    }

    private void sendCoordinates(double latitude, double longitude){
        Looper.prepare();
        GMailSender sender = new GMailSender("sender@gmail.com", "password");
        //Subject, Body, Sender, Recipient
        try {
            sender.sendMail("Sample GPS Location",   
                    "This should go to my yahoo account. My Location is at is - Lat: " + latitude + " Long: " + longitude,   
                    "sender@gmail.com",   
                    "receiver@yahoo.com");   

            Toast.makeText(getApplicationContext(), "Mail Sent", Toast.LENGTH_SHORT).show();
        } 
        catch (Exception e) {   
            Log.e("SendMail", e.getMessage(), e);   
        }

    }

}

これまでのところ、サービスを呼び出す電話イベントを介してブロードキャストレシーバーを呼び出す方法についてオンラインで読んでいます。よくわかりませんが、設定したバインドオーバーライドが原因で問題が発生していると思います。

4

1 に答える 1

0

サービスを開始する必要があります

public class AlarmReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
       Intent service=new Intent(context,UploadObservationService.class);
            **context.startService(service);**
        Log.v("Tag", "AlarmReceiver called.");
    }
}
于 2014-11-25T05:41:04.547 に答える