2015年8月26日 星期三

Android 修改系統時間

需先Root後才可使用

public static boolean changeSystemTime(String datetime) {
String[] times = datetime.split(" ");
if (times.length == 2) {
return changeSystemTime(times[0].replace("-", ""),
times[1].replace(":", ""));
}
return false;
}

private static boolean changeSystemTime(String date, String time) {
try {
Process process = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(
process.getOutputStream());
String command = "date -s " + date + "." + time + "\n";
os.writeBytes(command);
os.flush();
os.writeBytes("exit\n");
os.flush();
process.waitFor();
return true;
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return false;
}

2015年8月24日 星期一

eclipse android 加快開啟速度

1. 在 Windows -> Preferences -> Validation,按一下「Disable All」就可以把所有的驗證器都關掉。之後你可以在編輯器中按右鍵,在選單中選擇「Validate」來手動驗證。

2.在 Windows -> Preferences -> General -> Startup and Shutdown
  • Marketplace Client:eclipse 廣告更新
  • Equinox Provisioning Platform Automatic Update Support:eclipse 自動更新
  • mylyn:用在任務管理
  • WindowBuilder Discovery UI:Java 拉UI用的
  • Codan Analysis UI for C/C++:C/C++ 做UI用
以上幾個沒用到的都可以取消勾選,Android Development Toolkit 做Android 開發要打勾。

3.到Eclipse的目錄下找到eclipse.ini 檔,在修改以下參數前請先複製一份。
白色為不需修改部分,根據不同版本的eclipse會不太一樣
紅色為須自己加入的參數

-startup
plugins/org.eclipse.equinox.launcher_1.3.0.v20120522-1813.jar
--launcher.library
plugins/org.eclipse.equinox.launcher.win32.win32.x86_1.1.200.v20120913-144807
-product
org.eclipse.epp.package.java.product
--launcher.defaultAction
openFile
--launcher.XXMaxPermSize
1024M
-showsplash
org.eclipse.platform
--launcher.XXMaxPermSize
1024m
--launcher.defaultAction
openFile
-vmargs
-server
-Dosgi.requiredJavaVersion=1.7
-Dhelp.lucene.tokenizer=standard
-Xverify:none
-Xmn128m
-Xms1024m
-Xmx1024m
-Xss2m
-XX:PermSize=128m
-XX:MaxPermSize=128m
-XX:+UseParallelGC
儲存後重開eclipse

2015年8月17日 星期一

Google Cloud Messaging(GCM)

Eclipse

例專案package是com.griever.test
將 gcm.jar 加入專案的libs

在AndroidManifest加入以下內容

加入權限
<permission 

android:name="com.griever.test.permission.C2D_MESSAGE" 
android:protectionLevel="signature"/>
<uses-permission android:name="com.griever.test.permission.C2D_MESSAGE"/>
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
<uses-permission android:name="android.permission.INTERNET" />


加在application內

<receiver
          android:name="com.griever.test.gcm.GCMBroadcastReceiver"
          android:permission="com.google.android.c2dm.permission.SEND" >
          <intent-filter>
              <action android:name="com.google.android.c2dm.intent.RECEIVE" />
              <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
              <category android:name="com.griever.test" />
           </intent-filter>
</receiver>
<service android:name="com.griever.test.gcm.GCMIntentService" />



新增GCMBroadcastReceiver.java

public class GCMBroadcastReceiver extends BroadcastReceiver {
final String TAG = "GCM";

public void onReceive(Context context, Intent intent) {
Log.v(TAG, "onReceive: " + intent.getAction());
ComponentName comp = new ComponentName(context.getPackageName(),
GCMIntentService.class.getName());
context.startService(intent.setComponent(comp));
setResultCode(Activity.RESULT_OK);
}


新增GCMIntentService.java

public class GCMIntentService extends GCMBaseIntentService {

@SuppressWarnings("hiding")
private static final String TAG = "GCMIntentService";
private static final String GOOGLE_PROJECT_ID = "12345678910";
public GCMIntentService() {
super(GOOGLE_PROJECT_ID);
}

@Override
protected void onRegistered(Context context, String registrationId) {
ServerUtilities.register(context, registrationId);
}

@Override
protected void onUnregistered(Context context, String registrationId) {
if (GCMRegistrar.isRegisteredOnServer(context)) {
ServerUtilities.unregister(context, registrationId);
} else {
// This callback results from the call to unregister made on
// ServerUtilities when the registration to the server failed.
// Log.i(TAG, "Ignoring unregister callback");
}
}

@Override
protected void onMessage(Context context, Intent intent) {
//接收訊息
}

}

@Override
protected void onDeletedMessages(Context context, int total) {
// Log.i(TAG, "Received deleted messages notification");
}

@Override
public void onError(Context context, String errorId) {
// Log.i(TAG, "Received error: " + errorId);
}

@Override
protected boolean onRecoverableError(Context context, String errorId) {
// Log.i(TAG, "Received recoverable error: " + errorId);
return super.onRecoverableError(context, errorId);
}

}

新增ServerUtilities.java

public final class ServerUtilities {

private static final int MAX_ATTEMPTS = 5;
private static final int BACKOFF_MILLI_SECONDS = 2000;
private static final Random random = new Random();
private static final String TAG = "ServerUtilities";

static boolean register(final Context context, final String regId) {

String serverUrl = "http://192.168.1.100/gcm_register";
Map<String, String> params = new HashMap<String, String>();
params.put("regId", regId);
long backoff = BACKOFF_MILLI_SECONDS;

for (int i = 1; i <= MAX_ATTEMPTS; i++) {
// Log.d(TAG, "Attempt #" + i + " to register");
try {
post(serverUrl, params);
GCMRegistrar.setRegisteredOnServer(context, true);
return true;
} catch (Exception e) {
Log.e(TAG, "Failed to register on attempt " + i, e);
if (i == MAX_ATTEMPTS) {
break;
}
try {
Thread.sleep(backoff);
} catch (InterruptedException e1) {
Thread.currentThread().interrupt();
return false;
}
backoff *= 2;
}
}
return false;
}


static void unregister(final Context context, final String regId) {
String serverUrl = "http://192.168.1.100//gcm_unregister";
Map<String, String> params = new HashMap<String, String>();
params.put("regId", regId);
try {
post(serverUrl, params);
GCMRegistrar.setRegisteredOnServer(context, false);
// Log.i(TAG, "server_unregistered device OK");
} catch (Exception e) {
Log.i(TAG, "server_unregistered device error");
}
}

private static void post(String endpoint, Map<String, String> params)
throws IOException {
URL url;
try {
url = new URL(endpoint);
} catch (MalformedURLException e) {
throw new IllegalArgumentException("invalid url: ");
}
StringBuilder bodyBuilder = new StringBuilder();
Iterator<Entry<String, String>> iterator = params.entrySet().iterator();
// constructs the POST body using the parameters
while (iterator.hasNext()) {
Entry<String, String> param = iterator.next();
bodyBuilder.append(param.getKey()).append('=')
.append(param.getValue());
if (iterator.hasNext()) {
bodyBuilder.append('&');
}
}
String body = bodyBuilder.toString();
// Log.v(TAG, "Posting '" + body + "' to " + url);
byte[] bytes = body.getBytes();
HttpURLConnection conn = null;
try {
conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
conn.setFixedLengthStreamingMode(bytes.length);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded;charset=UTF-8");
// post the request
OutputStream out = conn.getOutputStream();
out.write(bytes);
out.close();
// handle the response
int status = conn.getResponseCode();

if (status != 200) {
throw new IOException("Post failed with error code " + status);
}

InputStream is = conn.getInputStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
String line;
StringBuffer response = new StringBuffer();
while ((line = rd.readLine()) != null) {
response.append(line);
}
rd.close();

// Log.e(TAG, "return :" + response.toString() + " "
// + response.toString().equals("OK"));
if (!response.toString().equals("OK")) {
throw new IOException("Post failed with error msg ");
}

} finally {
if (conn != null) {
conn.disconnect();
}
}
}

}


加入以下程式碼註冊gcm

GCMRegistrar.checkDevice(mContext);

GCMRegistrar.checkManifest(mContext);

final String regId = GCMRegistrar.getRegistrationId(mContext);

if (regId.equals("")) {
GCMRegistrar.register(mContext, CommonUtilities.SENDER_ID);

} else {
System.out.println("gcm is already regist"); // GCMRegistrar.unregister(mContext); // if (GCMRegistrar.isRegisteredOnServer(mContext)) { // } else { // }
}

2015年7月14日 星期二

2015年7月10日 星期五

android surfaceview 相關

CustomView extends SurfaceView implements Callback

private SurfaceHolder sfh;
private Paint mPaint;
private Paint mClearPaint;
private CoreThread coreThread;//

//surfaceview 透明背景
setZOrderOnTop(true);
sfh = getHolder();
sfh.addCallback(this);
sfh.setFormat(PixelFormat.RGBA_8888);

//畫筆設定
mPaint = new Paint();
mPaint.setAntiAlias(true);
mClearPaint = new Paint();
mClearPaint.setXfermode(new PorterDuffXfermode(Mode.CLEAR));

//畫面重整
private void draw() {
Canvas canvas = null;
try {
canvas = sfh.lockCanvas();
if (canvas != null) {
canvas.drawPaint(mClearPaint);
if (MainSprite != null) {
drawMainSprite(canvas);
}
synchronized (drawLock) {
for (SpriteParam sp : FoodList) {
drawFoodSprite(canvas, sp);
}
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (canvas != null)
sfh.unlockCanvasAndPost(canvas);
}
}



2015年6月28日 星期日

android timepicker 設定分間隔

@SuppressLint("NewApi")
private void setTimePickerInterval(TimePicker timePicker) {
try {
Class<?> classForid = Class.forName("com.android.internal.R$id");
// Field timePickerField = classForid.getField("timePicker");
Field field = classForid.getField("minute");
NumberPicker minutePicker = (NumberPicker) timePicker
.findViewById(field.getInt(null));
minutePicker.setMinValue(0);//最小0
minutePicker.setMaxValue(1);//最大1
List<String> displayedValues = new ArrayList<String>();
for (int i = 0; i < 60; i += 30) {//30分為單位
displayedValues.add(String.format("%02d", i));
}
for (int i = 0; i < 60; i += 30) {//30分為單位
displayedValues.add(String.format("%02d", i));
}
minutePicker.setDisplayedValues(displayedValues
.toArray(new String[0]));
} catch (Exception e) {
e.printStackTrace();
}
}

2015年6月17日 星期三

android EditText 取消軟鍵盤自動彈出

Activity

getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);

Xml

<activity android:name="org.MainActivity" android:label="@string/app_name" android:windowSoftInputMode="stateHidden" />
 

或

Dialog

AlertDialog dialog = new AlertDialog.Builder(this).setView(editText).create(); dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); dialog.show();