Skip to content

Commit fe9358c

Browse files
Initial commit
1 parent 5d56047 commit fe9358c

File tree

21 files changed

+422
-0
lines changed

21 files changed

+422
-0
lines changed

ShakeToRefresh/.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.gradle
2+
/local.properties
3+
/.idea/workspace.xml
4+
.DS_Store

ShakeToRefresh/app/proguard-rules.txt

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Add project specific ProGuard rules here.
2+
# By default, the flags in this file are appended to flags specified
3+
# in D:/DevMobile/sdk1/eclipse_Android_SDK/android-sdk_r18-windows/android-sdk-windows/tools/proguard/proguard-android.txt
4+
# You can edit the include path and order by changing the ProGuard
5+
# include property in project.properties.
6+
#
7+
# For more details, see
8+
# http://developer.android.com/guide/developing/tools/proguard.html
9+
10+
# Add any project specific keep options here:
11+
12+
# If your project uses WebView with JS, uncomment the following
13+
# and specify the fully qualified class name to the JavaScript interface
14+
# class:
15+
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16+
# public *;
17+
#}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3+
package="com.survivingwithandroid.shaketorefresh.app" >
4+
5+
<application
6+
android:allowBackup="true"
7+
android:icon="@drawable/ic_launcher"
8+
android:label="@string/app_name"
9+
android:theme="@style/AppTheme" >
10+
<activity
11+
android:name="com.survivingwithandroid.shaketorefresh.app.MainActivity"
12+
android:label="@string/app_name" >
13+
<intent-filter>
14+
<action android:name="android.intent.action.MAIN" />
15+
16+
<category android:name="android.intent.category.LAUNCHER" />
17+
</intent-filter>
18+
</activity>
19+
</application>
20+
21+
</manifest>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/*
2+
* Copyright (C) 2014 Francesco Azzola
3+
* Surviving with Android (http://www.survivingwithandroid.com)
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package com.survivingwithandroid.shaketorefresh.app;
19+
20+
import android.app.Activity;
21+
import android.support.v7.app.ActionBarActivity;
22+
import android.os.Bundle;
23+
import android.view.Menu;
24+
import android.view.MenuItem;
25+
import android.widget.ArrayAdapter;
26+
import android.widget.ListView;
27+
import android.widget.Toast;
28+
29+
30+
public class MainActivity extends Activity implements ShakeEventManager.ShakeListener {
31+
32+
private String[] dataList;
33+
private ArrayAdapter<String> adpt;
34+
private ListView listView;
35+
private ShakeEventManager sd;
36+
@Override
37+
protected void onCreate(Bundle savedInstanceState) {
38+
super.onCreate(savedInstanceState);
39+
setContentView(R.layout.activity_main);
40+
createData();
41+
adpt = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, dataList);
42+
listView = (ListView) findViewById(R.id.list);
43+
listView.setAdapter(adpt);
44+
sd = new ShakeEventManager();
45+
sd.setListener(this);
46+
sd.init(this);
47+
}
48+
49+
50+
@Override
51+
public boolean onCreateOptionsMenu(Menu menu) {
52+
53+
// Inflate the menu; this adds items to the action bar if it is present.
54+
55+
return true;
56+
}
57+
58+
@Override
59+
public boolean onOptionsItemSelected(MenuItem item) {
60+
61+
return super.onOptionsItemSelected(item);
62+
}
63+
64+
private void createData() {
65+
int start = (int) (Math.random() * 10);
66+
dataList = new String[15];
67+
68+
for (int i=0; i < dataList.length; i++)
69+
dataList[i] = "Item_" + (start + i);
70+
}
71+
72+
@Override
73+
public void onShake() {
74+
createData();
75+
adpt = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, dataList);
76+
Toast.makeText(this, "Refresh data...", Toast.LENGTH_SHORT).show();
77+
listView.setAdapter(adpt);
78+
}
79+
80+
81+
@Override
82+
protected void onResume() {
83+
super.onResume();
84+
sd.register();
85+
}
86+
87+
88+
@Override
89+
protected void onPause() {
90+
super.onPause();
91+
sd.deregister();
92+
}
93+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
/*
2+
* Copyright (C) 2014 Francesco Azzola
3+
* Surviving with Android (http://www.survivingwithandroid.com)
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package com.survivingwithandroid.shaketorefresh.app;
18+
19+
import android.content.Context;
20+
import android.hardware.Sensor;
21+
import android.hardware.SensorEvent;
22+
import android.hardware.SensorEventListener;
23+
import android.hardware.SensorManager;
24+
import android.util.Log;
25+
26+
public class ShakeEventManager implements SensorEventListener {
27+
28+
private SensorManager sManager;
29+
private Sensor s;
30+
31+
32+
private static final int MOV_COUNTS = 2;
33+
private static final int MOV_THRESHOLD = 4;
34+
private static final float ALPHA = 0.8F;
35+
private static final int SHAKE_WINDOW_TIME_INTERVAL = 500; // milliseconds
36+
37+
// Gravity force on x,y,z axis
38+
private float gravity[] = new float[3];
39+
40+
private int counter;
41+
private long firstMovTime;
42+
private ShakeListener listener;
43+
44+
public ShakeEventManager() {
45+
}
46+
47+
public void setListener(ShakeListener listener) {
48+
this.listener = listener;
49+
}
50+
51+
public void init(Context ctx) {
52+
sManager = (SensorManager) ctx.getSystemService(Context.SENSOR_SERVICE);
53+
s = sManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
54+
register();
55+
}
56+
57+
public void register() {
58+
sManager.registerListener(this, s, SensorManager.SENSOR_DELAY_NORMAL);
59+
}
60+
61+
@Override
62+
public void onSensorChanged(SensorEvent sensorEvent) {
63+
float maxAcc = calcMaxAcceleration(sensorEvent);
64+
Log.d("SwA", "Max Acc ["+maxAcc+"]");
65+
if (maxAcc >= MOV_THRESHOLD) {
66+
if (counter == 0) {
67+
counter++;
68+
firstMovTime = System.currentTimeMillis();
69+
Log.d("SwA", "First mov..");
70+
} else {
71+
long now = System.currentTimeMillis();
72+
if ((now - firstMovTime) < SHAKE_WINDOW_TIME_INTERVAL)
73+
counter++;
74+
else {
75+
resetAllData();
76+
counter++;
77+
return;
78+
}
79+
Log.d("SwA", "Mov counter ["+counter+"]");
80+
81+
if (counter >= MOV_COUNTS)
82+
if (listener != null)
83+
listener.onShake();
84+
}
85+
}
86+
87+
}
88+
89+
@Override
90+
public void onAccuracyChanged(Sensor sensor, int i) {}
91+
92+
public void deregister() {
93+
sManager.unregisterListener(this);
94+
}
95+
96+
97+
private float calcMaxAcceleration(SensorEvent event) {
98+
gravity[0] = calcGravityForce(event.values[0], 0);
99+
gravity[1] = calcGravityForce(event.values[1], 1);
100+
gravity[2] = calcGravityForce(event.values[2], 2);
101+
102+
float accX = event.values[0] - gravity[0];
103+
float accY = event.values[1] - gravity[1];
104+
float accZ = event.values[2] - gravity[2];
105+
106+
float max1 = Math.max(accX, accY);
107+
return Math.max(max1, accZ);
108+
}
109+
110+
// Low pass filter
111+
private float calcGravityForce(float currentVal, int index) {
112+
return ALPHA * gravity[index] + (1 - ALPHA) * currentVal;
113+
}
114+
115+
116+
private void resetAllData() {
117+
Log.d("SwA", "Reset all data");
118+
counter = 0;
119+
firstMovTime = System.currentTimeMillis();
120+
}
121+
122+
123+
public static interface ShakeListener {
124+
public void onShake();
125+
}
126+
}
Loading
Loading
Loading
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<!--
2+
~ *******************************************************************************
3+
~ Copyright (c) 2013-2014 Francesco Azzola (http://www.survivingwithandroid.com).
4+
~
5+
~ Licensed under the Apache License, Version 2.0 (the "License");
6+
~ you may not use this file except in compliance with the License.
7+
~ You may obtain a copy of the License at
8+
~
9+
~ http://www.apache.org/licenses/LICENSE-2.0
10+
~
11+
~ Unless required by applicable law or agreed to in writing, software
12+
~ distributed under the License is distributed on an "AS IS" BASIS,
13+
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
~ See the License for the specific language governing permissions and
15+
~ limitations under the License.
16+
~ *****************************************************************************
17+
-->
18+
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
19+
xmlns:tools="http://schemas.android.com/tools"
20+
android:layout_width="match_parent"
21+
android:layout_height="match_parent"
22+
android:paddingLeft="@dimen/activity_horizontal_margin"
23+
android:paddingRight="@dimen/activity_horizontal_margin"
24+
android:paddingTop="@dimen/activity_vertical_margin"
25+
android:paddingBottom="@dimen/activity_vertical_margin"
26+
tools:context="com.survivingwithandroid.shaketorefresh.app.MainActivity">
27+
28+
<TextView
29+
android:text="@string/app_name"
30+
android:layout_width="wrap_content"
31+
android:layout_height="wrap_content"
32+
android:layout_centerHorizontal="true"
33+
android:id="@+id/txt"/>
34+
35+
<ListView
36+
android:layout_width="wrap_content"
37+
android:layout_height="wrap_content"
38+
android:id="@+id/list"
39+
android:layout_below="@id/txt"
40+
android:layout_marginTop="15dp"/>
41+
42+
</RelativeLayout>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<!--
2+
~ *******************************************************************************
3+
~ Copyright (c) 2013-2014 Francesco Azzola (http://www.survivingwithandroid.com).
4+
~
5+
~ Licensed under the Apache License, Version 2.0 (the "License");
6+
~ you may not use this file except in compliance with the License.
7+
~ You may obtain a copy of the License at
8+
~
9+
~ http://www.apache.org/licenses/LICENSE-2.0
10+
~
11+
~ Unless required by applicable law or agreed to in writing, software
12+
~ distributed under the License is distributed on an "AS IS" BASIS,
13+
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
~ See the License for the specific language governing permissions and
15+
~ limitations under the License.
16+
~ *****************************************************************************
17+
-->
18+
<menu xmlns:android="http://schemas.android.com/apk/res/android"
19+
xmlns:app="http://schemas.android.com/apk/res-auto"
20+
xmlns:tools="http://schemas.android.com/tools"
21+
tools:context="com.survivingwithandroid.shaketorefresh.app.MainActivity" >
22+
23+
</menu>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<resources>
2+
<!-- Example customization of dimensions originally defined in res/values/dimens.xml
3+
(such as screen margins) for screens with more than 820dp of available width. This
4+
would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
5+
<dimen name="activity_horizontal_margin">64dp</dimen>
6+
</resources>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<resources>
2+
<!-- Default screen margins, per the Android Design guidelines. -->
3+
<dimen name="activity_horizontal_margin">16dp</dimen>
4+
<dimen name="activity_vertical_margin">16dp</dimen>
5+
6+
</resources>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!--
3+
~ *******************************************************************************
4+
~ Copyright (c) 2013-2014 Francesco Azzola (http://www.survivingwithandroid.com).
5+
~
6+
~ Licensed under the Apache License, Version 2.0 (the "License");
7+
~ you may not use this file except in compliance with the License.
8+
~ You may obtain a copy of the License at
9+
~
10+
~ http://www.apache.org/licenses/LICENSE-2.0
11+
~
12+
~ Unless required by applicable law or agreed to in writing, software
13+
~ distributed under the License is distributed on an "AS IS" BASIS,
14+
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
~ See the License for the specific language governing permissions and
16+
~ limitations under the License.
17+
~ *****************************************************************************
18+
-->
19+
<resources>
20+
21+
<string name="app_name">ShakeToRefresh</string>
22+
23+
24+
</resources>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<resources>
2+
3+
<!-- Base application theme. -->
4+
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
5+
<!-- Customize your theme here. -->
6+
</style>
7+
8+
</resources>

ShakeToRefresh/build.gradle

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Top-level build file where you can add configuration options common to all sub-projects/modules.
2+
3+
buildscript {
4+
repositories {
5+
mavenCentral()
6+
}
7+
dependencies {
8+
classpath 'com.android.tools.build:gradle:0.9.+'
9+
}
10+
}
11+
12+
allprojects {
13+
repositories {
14+
mavenCentral()
15+
}
16+
}

0 commit comments

Comments
 (0)