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 { // }
}