2016-12-27 20 views
1

這實際上是一個拼貼項目。要求是:如何在後臺運行此Android代碼

  1. 使用任何兩個傳感器(我使用Proximity和Accelerometer)製作一個應用程序,可將Android Profile更改爲Ringer,Vibration和Silent。
  2. 確保應用程序關閉後應用程序仍在後臺運行。
  3. 連續運行的傳感器會消耗太多的電池,請做點事情以便儘可能節省電池電量。

我已經完成了NO:1並且按預期運行,只剩下2和3了。 什麼將是在後臺運行這段代碼最簡單的方法:我有一個想法是這樣的:

enter image description here

我要開始使用兩個按鈕停止後臺服務。

這裏是代碼爲NO:1

public class SensorActivity extends Activity implements SensorEventListener{ 

private SensorManager mSensorManager; 
private Sensor proxSensor,accSensor; 

private TextView serviceStatus,profileStatus; 
private Button startService,endService; 

private boolean isObjectInFront,isPhoneFacedDown; 

private AudioManager audioManager; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_sensor); 

    audioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE); 

    mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE); 
    proxSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY); 
    accSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); 

    isObjectInFront = false; 
    isPhoneFacedDown = false; 

    serviceStatus = (TextView) findViewById(R.id.textView_serviceStatus); 
    profileStatus = (TextView) findViewById(R.id.textView_profileStatus); 
} 

protected void onResume() { 
    super.onResume(); 
    mSensorManager.registerListener(this, proxSensor, SensorManager.SENSOR_DELAY_NORMAL); 
    mSensorManager.registerListener(this, accSensor, SensorManager.SENSOR_DELAY_NORMAL); 
} 


protected void onPause() { 
    super.onPause(); 
    mSensorManager.unregisterListener(this); 
} 

@Override 
public void onSensorChanged(SensorEvent event) { 

    if (event.sensor.getType() == Sensor.TYPE_PROXIMITY) { 
     if(event.values[0] > 0){ 
      isObjectInFront = false; 
     } 
     else { 
      isObjectInFront = true; 
     } 

    } 
    if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) { 
     if(event.values[2] < 0){ 
      isPhoneFacedDown = true; 
     } 
     else { 
      isPhoneFacedDown = false; 
     } 
    } 

    if(isObjectInFront && isPhoneFacedDown){ 
     audioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT); 
     profileStatus.setText("Ringer Mode : Off\nVibration Mode: Off\nSilent Mode: On"); 
    } 
    else { 
     if(isObjectInFront){ 
      audioManager.setRingerMode(AudioManager.RINGER_MODE_VIBRATE); 
      profileStatus.setText("Ringer Mode : Off\nVibration Mode: On\nSilent Mode: Off"); 
     } 
     else { 
      audioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL); 
      profileStatus.setText("Ringer Mode : On\nVibration Mode: Off\nSilent Mode: Off"); 
     } 
    } 



} 

@Override 
public void onAccuracyChanged(Sensor sensor, int i) { 

} 

}

+0

您可以使用服務,將在後臺運行,並可以設置BroadcastReceivers這樣你就可以優化電池消費.. –

+0

忘了補充一點,後臺的功能絕使用和種類的服務。 –

+0

有很多關於服務和廣播接收器的教程,你可以谷歌它 –

回答

1

你一定要用戶服務

Android用戶界面被限制爲執行長時間運行的作業以使用戶體驗更平滑。典型的長時間運行任務可以是定期從互聯網下載數據,將多個記錄保存到數據庫中,執行文件I/O,獲取手機聯繫人列表等。對於長時間運行的任務,Service是另一種選擇。

服務是一個應用程序組件,用於在後臺執行長時間運行的任務。 服務沒有任何用戶界面,也不能直接與活動通信。 服務可以無限期地在後臺運行,即使啓動服務的組件被銷燬。 通常,服務總是執行單個操作,並在完成預定任務後自行停止。 服務在應用程序實例的主線程中運行。它不創建它自己的線程。如果您的服務將執行任何長時間運行的阻止操作,則可能會導致應用程序無響應(ANR)。因此,你應該在服務中創建一個新的線程。

Service類

public class HelloService extends Service { 

    private static final String TAG = "HelloService"; 

    private boolean isRunning = false; 

    @Override 
    public void onCreate() { 
     Log.i(TAG, "Service onCreate"); 

     isRunning = true; 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 

     Log.i(TAG, "Service onStartCommand"); 

     //Creating new thread for my service 
     //Always write your long running tasks in a separate thread, to avoid ANR 
     new Thread(new Runnable() { 
      @Override 
      public void run() { 


       //Your logic that service will perform will be placed here 
       //In this example we are just looping and waits for 1000 milliseconds in each loop. 
       for (int i = 0; i < 5; i++) { 
        try { 
         Thread.sleep(1000); 
        } catch (Exception e) { 
        } 

        if(isRunning){ 
         Log.i(TAG, "Service running"); 
        } 
       } 

       //Stop service once it finishes its task 
       stopSelf(); 
      } 
     }).start(); 

     return Service.START_STICKY; 
    } 


    @Override 
    public IBinder onBind(Intent arg0) { 
     Log.i(TAG, "Service onBind"); 
     return null; 
    } 

    @Override 
    public void onDestroy() { 

     isRunning = false; 

     Log.i(TAG, "Service onDestroy"); 
    } 
} 

艙單聲明

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

    <application 
     android:allowBackup="true" 
     android:icon="@drawable/ic_launcher" 
     android:label="@string/app_name" 
     android:theme="@style/AppTheme" > 
    <activity 
     android:name=".HelloActivity" 
     android:label="@string/app_name" > 
     <intent-filter> 
      <action android:name="android.intent.action.MAIN" /> 

      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 
    </activity> 

    <!--Service declared in manifest --> 
    <service android:name=".HelloService" 
     android:exported="false"/> 
</application> 

要啓動服務

Intent intent = new Intent(this, HelloService.class); 
startService(intent); 

Reference

+0

非常感謝你。我會嘗試這個,看看它是否按預期工作,並讓你知道評論。 –

+0

另一個問題:如何停止這項服務? 假設我聲明瞭應用程序,使用按鈕啓動此服務 然後我完全關閉了應用程序,但服務仍在後臺運行。 如何停止服務? –

+0

一旦服務完成執行,服務必須通過調用stopSelf()方法自行停止。但是,您也可以通過調用stopService()方法來自行停止服務。 對stopService方法的調用將在您的服務中調用onDestroy()回調。您必須手動停止您的應用程序執行的操作。 –