I have a problem getting data from my heart_rate_sensor. If I use a light sensor, it works perfectly but when it comes to the other sensor it doesn´t.
Here`s my activity.java file:
package com.example.smartwatchprueba2;
import android.app.Activity;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.widget.TextView;
import com.example.smartwatchprueba2.databinding.ActivityMainBinding;
public class MainActivity extends Activity {
private TextView mTextView,mTextView1;
private ActivityMainBinding binding;
private SensorManager sensorManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
sensorManager = (SensorManager) getSystemService(this.SENSOR_SERVICE);
Sensor sensorLuz = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
Sensor sensorRitmoCardiaco = sensorManager.getDefaultSensor(Sensor.TYPE_HEART_RATE);
sensorManager.registerListener(listener, sensorLuz, SensorManager.SENSOR_DELAY_NORMAL);
sensorManager.registerListener(listener1, sensorRitmoCardiaco, SensorManager.SENSOR_DELAY_NORMAL);
mTextView = binding.textView;
mTextView1=binding.textView1;
}
#Override
protected void onDestroy() {
super.onDestroy();
if (sensorManager != null) {
sensorManager.unregisterListener(listener);
sensorManager.unregisterListener(listener1);
}
}
SensorEventListener listener=new SensorEventListener() {
#Override
public void onSensorChanged(SensorEvent sensorEvent) {
float value = sensorEvent.values[0];
mTextView.setText("Current light level is " + value + " lx");
}
#Override
public void onAccuracyChanged(Sensor sensor, int i) {
}
};
SensorEventListener listener1=new SensorEventListener() {
#Override
public void onSensorChanged(SensorEvent sensorEvent) {
float value1 = sensorEvent.values[0];
mTextView.setText("Current heart rate is: " + value1);
}
#Override
public void onAccuracyChanged(Sensor sensor, int i) {
}
};
}
I thought it could be something with the permission, but I have included Body_sensors permission and it doesnt work. Heres my manifest file so you can see all the permissions.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.smartwatchprueba2">
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.BODY_SENSORS" />
<uses-feature android:name="android.hardware.type.watch" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#android:style/Theme.DeviceDefault">
<uses-library
android:name="com.google.android.wearable"
android:required="true" />
<!--
Set to true if your app is Standalone, that is, it does not require the handheld
app to run.
-->
<meta-data
android:name="com.google.android.wearable.standalone"
android:value="true" />
<activity
android:name=".MainActivity"
android:exported="true"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Related
I am developing a sample watch face wherein a user would be able to select some color configuration on mobile app triggering changes on wear app watch face.
Here is what I have in mobile app to send configuration:
package com.quicklyjava.templatewatchface;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.wearable.DataApi;
import com.google.android.gms.wearable.PutDataMapRequest;
import com.google.android.gms.wearable.PutDataRequest;
import com.google.android.gms.wearable.Wearable;
/**
* Created by P
*/
public class WearConnection {
private final GoogleApiClient mGoogleApiClient;
private String TAG = "wear.bridge";
public WearConnection(Context context) {
mGoogleApiClient = new GoogleApiClient.Builder(context)
.addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
#Override
public void onConnected(Bundle connectionHint) {
Log.d(TAG, "onConnected: " + connectionHint);
}
#Override
public void onConnectionSuspended(int cause) {
Log.d(TAG, "onConnectionSuspended: " + cause);
}
})
.addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
#Override
public void onConnectionFailed(ConnectionResult result) {
Log.d(TAG, "onConnectionFailed: " + result);
}
})
.addApi(Wearable.API)
.build();
}
public void connect(){
mGoogleApiClient.connect();
}
public void disconnect() {
mGoogleApiClient.disconnect();
}
public void sendColor(String path, int color) {
PutDataMapRequest dataMap = PutDataMapRequest.create(path);
dataMap.getDataMap().putInt("value", color);
PutDataRequest request = dataMap.asPutDataRequest();
PendingResult<DataApi.DataItemResult> pendingResult = Wearable.DataApi.putDataItem(mGoogleApiClient, request);
pendingResult.setResultCallback(new ResultCallback<DataApi.DataItemResult>() {
#Override
public void onResult(DataApi.DataItemResult dataItemResult) {
Log.d("wear", "sent: " + dataItemResult);
}
});
}
}
Here is the manifest for mobile:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.quicklyjava.templatewatchface" >
<uses-permission android:name="com.google.android.permission.PROVIDE_BACKGROUND" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<meta-data android:name="com.google.android.gms.version" android:value="#integer/google_play_services_version" />
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
Here is the listener service I implemented in wear:
package com.quicklyjava.templatewatchface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.preference.PreferenceManager;
import android.util.Log;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.data.FreezableUtils;
import com.google.android.gms.wearable.DataEvent;
import com.google.android.gms.wearable.DataEventBuffer;
import com.google.android.gms.wearable.DataMapItem;
import com.google.android.gms.wearable.Node;
import com.google.android.gms.wearable.Wearable;
import com.google.android.gms.wearable.WearableListenerService;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* Created by P
*/
public class TemplateWatchConfigListenerService extends WearableListenerService {
private static final String TAG = "DataLayerSample";
private SharedPreferences preferences;
// keys for the data map
private String KEY_DOT_COLOR="com.quicklyjava.backgroundcolor";
GoogleApiClient mGoogleApiClient;
#Override
public void onCreate() {
super.onCreate();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Wearable.API)
.build();
mGoogleApiClient.connect();
preferences = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
}
#Override
public void onDataChanged(DataEventBuffer dataEvents) {
LOGD(TAG, "onDataChanged: " + dataEvents);
final List<DataEvent> events = FreezableUtils.freezeIterable(dataEvents);
dataEvents.close();
if(!mGoogleApiClient.isConnected()) {
ConnectionResult connectionResult = mGoogleApiClient.blockingConnect(30, TimeUnit.SECONDS);
if (!connectionResult.isSuccess()) {
Log.e(TAG, "WatchFaceConfigListenerService failed to connect to GoogleApiClient.");
return;
}
}
// Loop through the events and send a message back to the node that created the data item.
for (DataEvent event : events) {
Uri uri = event.getDataItem().getUri();
String path = uri.getPath();
DataMapItem item = DataMapItem.fromDataItem(event.getDataItem());
switch (path) {
case "/backgroundColor":
putIntPreference(KEY_DOT_COLOR, item.getDataMap().getInt("value"));
break;
default:
Log.e("TempWatchList","Default");
}
getBaseContext().sendBroadcast(new Intent("com.quicklyjava.action.config_changed"));
}
}
#Override
public void onPeerConnected(Node peer) {
LOGD(TAG, "onPeerConnected: " + peer);
}
#Override
public void onPeerDisconnected(Node peer) {
LOGD(TAG, "onPeerDisconnected: " + peer);
}
public static void LOGD(final String tag, String message) {
if (Log.isLoggable(tag, Log.DEBUG)) {
Log.d(tag, message);
}
}
private void putIntPreference(String key, int value) {
preferences
.edit()
.putInt(key, value)
.apply();
}
}
Finally here is the wear manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.quicklyjava.templatewatchface" >
<uses-sdk android:minSdkVersion="21"
android:targetSdkVersion="21" />
<uses-feature android:name="android.hardware.type.watch" />
<!-- Required to act as a custom watch face. -->
<uses-permission android:name="com.google.android.permission.PROVIDE_BACKGROUND" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<service
android:name=".TemplateWatchService"
android:label="#string/template_name"
android:permission="android.permission.BIND_WALLPAPER" >
<meta-data
android:name="android.service.wallpaper"
android:resource="#xml/watch_face" />
<meta-data
android:name="com.google.android.wearable.watchface.preview"
android:resource="#drawable/preview_digital" />
<meta-data
android:name="com.google.android.wearable.watchface.preview_circular"
android:resource="#drawable/preview_digital_circular" />
<intent-filter>
<action android:name="android.service.wallpaper.WallpaperService" />
<category android:name="com.google.android.wearable.watchface.category.WATCH_FACE" />
</intent-filter>
</service>
<service android:name=".TemplateWatchConfigListenerService" >
<intent-filter>
<action android:name="com.google.android.gms.wearable.BIND_LISTENER" />
</intent-filter>
</service>
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
</application>
The onDataChanged method is not getting triggered when the sendColor method in mobile app is called. Is there anything I am missing?
add a key-value in the data item map
map.put("system", System.currentmillions())
and send again
yeah, you are missing some important meta-data tags
In wear manifest, add these tag to the WatchFaceService's service tag:
<meta-data <!-- Companion config -->
android:name="com.google.android.wearable.watchface.companionConfigurationAction"
android:value="com.example.package.CONFIG_FACE" />
<meta-data <!-- wear config -->
android:name="com.google.android.wearable.watchface.wearableConfigurationAction"
android:value="com.example.package.CONFIG_FACE" />
And in your Companion manifest , just add only these lines to the CompanionConfigActivity's activity tag :
<intent-filter>
<action android:name="com.example.package.CONFIG_FACE" />
<category android:name="com.google.android.wearable.watchface.category.COMPANION_CONFIGURATION" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
The code :
com.example.package.CONFIG_FACE
must be same in both the manifests.
i have a string in my service, and i want to send it to fragment. But it seems onReceive() method on my BroadcastReceiver never called, and i just can't figured out why. Thanks for answers.
My Service Class
public class Servis extends Service {
static final String MAP = "MyService";
static final String USERID = "";
public static final String FILEPATH = "filepath";
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
System.out.println("starting service");
Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
String id = intent.getStringExtra("UserID");
System.out.println(id);
Intent intent1 = new Intent(MAP);
intent1.putExtra(USERID, id);
sendBroadcast(intent1);
return START_REDELIVER_INTENT;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
Toast.makeText(this, "My Service Created", Toast.LENGTH_LONG).show();
Log.d(MAP, "onCreate");
}
#Override
public void onDestroy() {
Toast.makeText(this, "My Service Stopped", Toast.LENGTH_LONG).show();
Log.d(MAP, "onDestroy");
}
#Override
public void onStart(Intent intent, int startid) {
Toast.makeText(this, "My Service Started", Toast.LENGTH_LONG).show();
Log.d(MAP, "onStart");
}
}
My Fragment Class
package com.example.mobilproje;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.widget.Toast;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
public class MapFragment extends FragmentActivity{
private GoogleMap googleHarita;
private BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
handleResult(bundle);
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.map_fragment);
registerReceiver(receiver, new IntentFilter(
Servis.MAP));
if (googleHarita == null) {
googleHarita = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.haritafragment))
.getMap();
if (googleHarita != null)
LatLng EvKoordinat = new LatLng(40.7994211,29.9517352);
googleHarita.addMarker(new MarkerOptions().position(EvKoordinat).title("Ev"));
googleHarita.moveCamera(CameraUpdateFactory.newLatLngZoom(EvKoordinat, 13));
}
}
}
#Override
public void onResume() {
registerReceiver(receiver, new IntentFilter(
Servis.MAP));
}
private void handleResult(Bundle bundle) {
if (bundle != null) {
String string = bundle.getString(Servis.USERID);
System.out.println("string");
}
}
}
AndroidManifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.mobilproje"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="13"
android:targetSdkVersion="23" />
<uses-permission android:name="android.permission.NFC" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-feature
android:glEsVersion="0x00020000"
android:required="true" />
<application
android:allowBackup="true"
android:icon="#drawable/nfc"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:theme="#style/mytheme"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.nfc.action.TECH_DISCOVERED" />
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<action android:name="android.nfc.action.TAG_DISCOVERED" />
</intent-filter>
<meta-data
android:name="android.nfc.action.TECH_DISCOVERED"
android:resource="#xml/nfc_tech_filter" />
</activity>
<activity
android:name=".MapFragment"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="AIzaSyCgPPczPpQA_00_v-nTux_WuGuaO9egUpc" />
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<service android:enabled="true" android:name=".Servis" android:process=":localservice"/>
</application>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
</manifest>
I have developed simple application to display the latitude and longitude in android... but it is showing the null pointer exception... please let me know what is the error..
My Activity class
import android.app.Activity;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.widget.Toast;
public class SignalStrengthActivity extends Activity implements LocationListener{
private LocationManager locationManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
}
#Override
protected void onResume() {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 1, this);
super.onResume();
}
#Override
protected void onPause() {
locationManager.removeUpdates(this);
super.onPause();
}
#Override
public void onLocationChanged(Location location) {
if (location != null) {
Toast.makeText(this, "Latitude and Longitude " + location.getLatitude() + " " +
location.getLongitude(), Toast.LENGTH_SHORT).show();
}
}
#Override
public void onProviderDisabled(String provider) {
Toast.makeText(this, "Latitude and Longitude Offline ", Toast.LENGTH_SHORT).show();
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
}
My Manifest file :-
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.latitudelongitude"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="16" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.latitudelongitude.SignalStrengthActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="#string/app_name"
android:theme="#style/FullscreenTheme" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
when i execute the application it does not display anything.. indicating that the location object is null... please let me know how to fix the problem
Go through the link below:
Link 1
I am having an issue with loading up a new intent after my splash screen. I have looked at questions relating to this exception but they all seem to be dealing with thing like google play or google maps not being referenced correctly this is not the case for me.
These are the related questions I have looked at
Not found activity to handle intent?
activity not found to handle intent
no activity found to handle intent
Below is my manifest code
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.main"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="15" />
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:name=".Splash"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".HomePage"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.HOMEPAGE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name=".OrderPlaced"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.ORDERPLACED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
</manifest>
Here is the code for the class splash
package com.android.main;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
public class Splash extends Activity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
Thread timer = new Thread(){
public void run(){
try{
sleep(1000);
}catch(InterruptedException e) {
e.printStackTrace();
}finally{
Intent openStartingPoint = new Intent("com.android.main.HOMEPAGE");
startActivity(openStartingPoint);
}
}
};
timer.start();
}
#Override
protected void onPause() {
super.onPause();
finish();
}
}
And here is the class HomePage I am trying to load after the splash screen
package com.android.main;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
public class HomePage extends Activity {
/** Called when the activity is first created. */
TextView name;
EditText editName;
TextView drinks;
Spinner drinksSpinner;
TextView message;
CheckBox checkbox;
Button createOrderButton;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
createOrder();
}
public void createOrder(){
createOrderButton = (Button) findViewById(R.id.bCreateOrder);
createOrderButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
postInformationtoAPI();
}
private void postInformationtoAPI() {
goToOrderCompleted();
}
private void goToOrderCompleted() {
Intent intent = new Intent(HomePage.this , OrderPlaced.class);
HomePage.this.startActivity(intent);
Log.i("onClick", "trying to start new activity to change layout");
}
});
}
}
The app force quits after loading the splash screen and gives the following exception
03-14 22:32:33.553: E/AndroidRuntime(3166): android.content.ActivityNotFoundException: No Activity found to handle Intent { act=com.android.main.HOMEPAGE }
Any help with this would be greatly appreciated
You have to differentiate the Intent's Constructor,
Intent openStartingPoint = new Intent("com.android.main.HOMEPAGE");
Which assume com.android.main.HOMEPAGE as Intent's action Filter. Which is not available in your application's android manifest.xml file. You have
<action android:name="android.intent.action.HOMEPAGE" />
which should be,
<action android:name="com.android.main.HOMEPAGE" />
OR just change it with,
Intent openStartingPoint = new Intent(Splash.this, HOMEPAGE.class);
<activity
android:label="#string/app_name"
android:name=".SplashScreen"
android:screenOrientation="landscape"
android:theme="#android:style/Theme.NoTitleBar.Fullscreen" >
<intent-filter >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.android.main.HOMEPAGE"
android:screenOrientation="landscape"
android:theme="#android:style/Theme.NoTitleBar.Fullscreen" >
<intent-filter >
<action android:name="com.android.main.HOMEPAGE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
Also i would have a timer task to display splash screen
public class SplashScreen extends Activity{
Timer splashTimer;
SplashTimerHandler splashTimerHandler;
private boolean applicationPaused=false;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
this.setSplash();
}
private void setSplash()
{
this.splashTimerHandler=new SplashTimerHandler();
this.splashTimer=new Timer();
this.splashTimer.schedule(this.splashTimerHandler, 0, 1000);
}
#Override
public void onPause()
{
super.onPause();
this.applicationPaused=true;
this.closeSplashTimer();
}
#Override
public void onResume()
{
super.onResume();
if(this.applicationPaused)
{
this.applicationPaused=false;
this.closeSplashTimer();
this.setSplash();
}
}
public class SplashTimerHandler extends TimerTask{
int splashTimerCounter=0;
#Override
public void run()
{
splashTimerCounter++;
if(splashTimerCounter>2)
{
runOnUiThread(splashTimeOver);
}
}
private Runnable splashTimeOver=new Runnable() {
#Override
public void run()
{
closeSplashTimer();
startHomeScreen();
}
};
}
protected void closeSplashTimer()
{
if(this.splashTimer!=null)
{
this.splashTimer.cancel();
this.splashTimer=null;
}
}
private void startHomeScreen()
{
this.closeSplashScreen();
startActivity(new Intent("com.android.main.HOMEPAGE"));
}
private void closeSplashScreen()
{
this.closeSplashTimer();
this.finish();
}
#Override
public boolean onKeyDown(int keycode, KeyEvent event)
{
if(keycode==KeyEvent.KEYCODE_BACK)
{
this.closeSplashScreen();
}
return true;
}
}
I created a preference files for my slide show Live Wallpaper.
Most of the source are copied from several samples. I think I copied them correctly, and the eclipse shows no warnings or errors for my source.
My problem is that the "Settings" button doesn't appear when I choose the Live Wallpaper.
I checked the very close question "Can't get settings button to display for live wallpaper", but it didn't solve my problem.
I suspect something is wrong with my Manifest, or preference sources, but I couldn't find the point.
Sorry for my bad English.
My sources are follows:
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest package="sample.slide_wallpaper"
android:versionCode="1"
android:versionName="1.0"
xmlns:android="http://schemas.android.com/apk/res/android">
<uses-sdk android:minSdkVersion="7" android:targetSdkVersion="8" />
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:icon="#drawable/icon"
android:label="#string/app_name">
<!-- =========================================================== -->
<!-- Launcher -->
<activity android:name=".Launcher" android:label="#string/app_name"
android:theme="#style/Theme.HalfTrans">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- ==============================================================-->
<!-- Live Wallpaper -->
<service
android:enabled="true"
android:permission="android.permission.BIND_WALLPAPER"
android:label="#string/app_name"
android:name="SlideWallpaper"
android:icon="#drawable/thumbnail">
<intent-filter>
<action android:name="android.service.wallpaper.WallpaperService"></action>
</intent-filter>
<meta-data
android:name="android.service.wallpaper"
android:resource="#xml/wallpaper">
</meta-data>
</service>
<!-- ================================================================= -->
<!-- Preferences -->
<activity
android:name="sample.slide_wallpaper.Prefs"
android:label="#string/wallpaper_settings"
android:theme="#android:style/Theme.WallpaperSettings"
android:exported="true">
<intent-filter>
<category android:name="android.intent.category.PREFERENCE" />
</intent-filter>
</activity>
</application>
</manifest>
settings.xml
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
android:title="#string/wallpaper_settings"
>
<ListPreference
android:key="timer_key"
android:title="#string/list_title"
android:summary="#string/list_summary"
android:entries="#array/timer_pref"
android:entryValues="#array/timer_pref_values"
android:defaultValue="5000"
/>
</PreferenceScreen>
**wallpaper.xml**
<?xml version="1.0" encoding="utf-8" ?>
<wallpaper xmlns:android="http://shemas.android.com/apk/res/android"
android:thumbnail="#drawable/thumbnail"
android:description="#string/description"
android:settingsActivity="sample.slidewallpaper.Prefs"
/>
**Prefs.java**
package sample.slide_wallpaper;
import sample.slide_wallpaper.R;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.util.Log;
public class Prefs extends PreferenceActivity
implements SharedPreferences.OnSharedPreferenceChangeListener {
#Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
Log.w("Prefs", "prefs onCreate");
addPreferencesFromResource(R.xml.settings);
}
#Override
protected void onDestroy()
{
getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
super.onDestroy();
}
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key)
{
}
}
SlideWallpaper.java
package sample.slide_wallpaper;
import java.util.Random;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Handler;
import android.service.wallpaper.WallpaperService;
import android.util.Log;
import android.view.Display;
import android.view.SurfaceHolder;
import android.view.WindowManager;
import android.content.SharedPreferences;
import android.content.res.Resources;
//WallpaperService
public class SlideWallpaper extends WallpaperService {
// Path for Prefs
public static final String SHARED_PREFS_NAME = "sample.slide_wallpaper.Prefs";
#Override
public void onCreate() {
.....
super.onCreate();
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
public WallpaperService.Engine onCreateEngine() {
return new WallpaperEngine(getResources());
}
//*********************************************************
//Wallpaper Engine
//*********************************************************
public class WallpaperEngine extends Engine
implements SharedPreferences.OnSharedPreferenceChangeListener {
private final Handler handler=new Handler();
SharedPreferences prefs;
public Bitmap img;
private Bitmap images[] = new Bitmap[5];
private Bitmap eximg;
private final Random randGen = new Random();
private static final String TAG = "WallpaperEngine";
//timer
private long timer = 5000;//interval(sec)×1000
private long startTime = 0;
private int currentAlpha;
private final Paint imagePaint;
private final Runnable drawThread=new Runnable() {
public void run() {
Log.d(TAG,"runnable");
drawFrame();
}
};
public WallpaperEngine(Resources r) {
prefs=SlideWallpaper.this.getSharedPreferences(SHARED_PREFS_NAME, 0);
prefs.registerOnSharedPreferenceChangeListener(this);
images[0]=BitmapFactory.decodeResource(r,R.drawable.imgA);
images[1]=BitmapFactory.decodeResource(r,R.drawable.imgB);
images[2]=BitmapFactory.decodeResource(r,R.drawable.imgC);
images[3]=BitmapFactory.decodeResource(r,R.drawable.imgD);
images[4]=BitmapFactory.decodeResource(r,R.drawable.imgE);
eximg = BitmapFactory.decodeResource(r,R.drawable.bg1);
img = eximg;
imagePaint = new Paint();
imagePaint.setAlpha(255);
}
//=============================
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key){
Log.w(TAG, "onPreferenceChanged");//this Log doesn't show up
String listString = prefs.getString("timer_key", "5000");
int listInt = Integer.parseInt(listString);
timer = listInt;
}
//=================================
#Override
public void onCreate(SurfaceHolder surfaceHolder) {
super.onCreate(surfaceHolder);
Log.d(TAG, "onCreate");
drawFrame();
}
//=====================================
#Override
public void onDestroy() {
super.onDestroy();
handler.removeCallbacks(fadeAnimate);
handler.removeCallbacks(drawThread);
}
//==================================
#Override
public void onVisibilityChanged(boolean visible) {
Log.d(TAG, "Visibility changed");
if (visible) {
if(nowTime() - startTime + 100 < timer){
if (img.isRecycled()) {
img = eximg;
}
drawBitmap(img);
handler.postDelayed(drawThread, timer - (nowTime() - startTime));
}else {
drawFrame();
}
} else {
handler.removeCallbacks(fadeAnimate);
handler.removeCallbacks(drawThread);
}
}
//===================================================
//draws bitmap
private void drawBitmap(Bitmap b) {
............
}
//=========================
#Override
public void onSurfaceCreated(SurfaceHolder holder) {
super.onSurfaceCreated(holder);
}
//============================
#Override
public void onSurfaceChanged(SurfaceHolder holder,
int format,int width,int height) {
super.onSurfaceChanged(holder,format,width,height);
drawFrame();
}
//==============================
#Override
public void onSurfaceDestroyed(SurfaceHolder holder) {
super.onSurfaceDestroyed(holder);
handler.removeCallbacks(fadeAnimate);
handler.removeCallbacks(drawThread);
}
//=================================
#Override
public void onOffsetsChanged(float xOffset,float yOffset,
float xStep,float yStep,int xPixels,int yPixels) {
drawBitmap(img);
}
//=================================================
//Changes image==================================
protected void drawFrame() {
.....
}
private final Runnable fadeAnimate = new Runnable() {
public void run() {
fadeTransition(img, currentAlpha);
}
};
private void fadeTransition(Bitmap b, int alpha) {
.....
}//END fadeTransition
private long nowTime() {
return System.nanoTime() / 1000000;
}
}//Engine
}//END
I really need your help!!
Also, the thumbnail image doesn't show up on the Live Wallpaper list. But this is a small problem.
Your wallpaper.xml has a minor error. The package name is incorrect. It should be:
<?xml version="1.0" encoding="utf-8" ?>
<wallpaper xmlns:android="http://schemas.android.com/apk/res/android"
android:thumbnail="#drawable/thumbnail"
android:description="#string/description"
android:settingsActivity="sample.slide_wallpaper.Prefs"
/>
I solved the problem by myself.
Thanks for Rajesh, I rewrote the whole code of "wallpaper.xml", and it worked correctly.
Actually, I couldn't find the difference, but my revised version is this:
<?xml version="1.0" encoding="utf-8" ?>
<wallpaper
xmlns:android="http://schemas.android.com/apk/res/android"
android:thumbnail="#drawable/thumbnail"
android:description="#string/description"
android:settingsActivity="sample.slide_wallpaper.Prefs"
/>
By revising the source, the thumbnail error was shown up, too!