參考資料 : Android Tabs Example – With Fragments and ViewPager
參考資料 : TabLayout (Android Design Library) Text Color
2015年11月26日 星期四
2015年11月25日 星期三
2015年11月22日 星期日
Android-AndroidStudio GCM
更新日期 : 20160318_新增註冊ID內容
使用 AndroidStudio 為 App 添加 GCM( Google Cloud Message )
想必大大對 GMC 不陌生吧
如果不知道的沒關係
以下舉例您可能馬上就知道
1 . 安裝應用 App 三不五時就會收到擾人的通知
2 . 安裝應用 遊戲 後,突然收到開戰通知!!!
這些大多都是 推播 ( 以GCM為例 )!!!
為啥要以 GCM 為範例?
其實微軟、亞馬遜也有提供
但是以大眾來講 GCM 是最普及的
進入重點
是如何動作的
1 . 開發者向 Google 申請序號
2 . 在 App 內放置序號並且實作 GCM
3 . 成功之後會回傳 Token
4 . 開發者將 Token 傳送到指定位置存放
5 . 開發者將指定 Token 配合並發送,使用者手機就可收到訊息
步驟
1 . 申請專案序號
連結 : GoogleDevelopersConsole
參考資料 : android-gcm-tool
參考資料 : Push Notification using GCM in Android Studio | Google Cloud Messaging
使用 AndroidStudio 為 App 添加 GCM( Google Cloud Message )
想必大大對 GMC 不陌生吧
如果不知道的沒關係
以下舉例您可能馬上就知道
1 . 安裝應用 App 三不五時就會收到擾人的通知
2 . 安裝應用 遊戲 後,突然收到開戰通知!!!
這些大多都是 推播 ( 以GCM為例 )!!!
為啥要以 GCM 為範例?
其實微軟、亞馬遜也有提供
但是以大眾來講 GCM 是最普及的
進入重點
是如何動作的
1 . 開發者向 Google 申請序號
2 . 在 App 內放置序號並且實作 GCM
3 . 成功之後會回傳 Token
4 . 開發者將 Token 傳送到指定位置存放
5 . 開發者將指定 Token 配合並發送,使用者手機就可收到訊息
步驟
1 . 申請專案序號
連結 : GoogleDevelopersConsole
參考資料 : android-gcm-tool
參考資料 : Push Notification using GCM in Android Studio | Google Cloud Messaging
2015年11月21日 星期六
Java-日期/時間 格式轉換
更新日期 : 20151212 ( 新增流程 )
流程 :
1 . 資料來源
2 . 來源格式
3 . 目的格式
4 . 將來資料來源轉換成 Date (parse)
5 . 將 來源Date 套用在 目的格式 (format)
6 . 轉換成字串
歡迎轉載,請註明出處。
流程 :
1 . 資料來源
2 . 來源格式
3 . 目的格式
4 . 將來資料來源轉換成 Date (parse)
5 . 將 來源Date 套用在 目的格式 (format)
6 . 轉換成字串
try {
// 1 ( 二選一 )
// 自定義
String date = "2015/12/12 07:07:07";
// 系統時間
DateFormat dateFormat_1 = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
String date = dateFormat_1.format(new Date());
System.out.println(date);
// 2
DateFormat dateFormat_1 = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
// 3
DateFormat dateFormat_2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// 4
Date date_org = dateFormat_1.parse(date);
// 5 . 6
String myDate = dateFormat_2.format(date_org);
System.out.println(myDate);
} catch (ParseException e) {
e.printStackTrace();
}
歡迎轉載,請註明出處。
2015年11月18日 星期三
Android-左右滑動圖片 Image ViewPager
參考資料 : 使用ViewPager实现左右滑动效果
參考資料 : Android实现左右滑动指引效果
參考資料 : Android通过ViewPager实现左右滑动切换图片
參考資料 : Android 基于ImageSwitcher实现的左右切换图片
參考資料 : Android Image Slideshow using ViewPager with PagerAdapter
( 有成功,但是沒壓縮造成反應遲緩,無引導點 )
若改無限制
參考資料 : Android UI设计——ViewPager中设置底部显示圆点焦点(二)
( 引導點 )
參考資料 : 用ViewPager实现欢迎引导页面
( 帶有引導點,可動態增加圖片 )
參考資料 : Android Image Slideshow using ViewPager with PagerAdapter
( 有成功,但是沒壓縮造成反應遲緩,無引導點 )
若改無限制
@Override
public int getCount() {
return mResources.length;
}
圖片來源記得要取餘數,不然會 Exception參考資料 : Android UI设计——ViewPager中设置底部显示圆点焦点(二)
( 引導點 )
參考資料 : 用ViewPager实现欢迎引导页面
( 帶有引導點,可動態增加圖片 )
2015年11月13日 星期五
Android-Google Ads 廣告置入 範例 Sample
20170311 新增:整頁廣告
想必大家都聽過寫 App 然後靠廣告賺錢
1 . 在 Gradle 內加入
2 . 在要呈現的版面新增元件
3 . 宣告元件
4 . 將 AdMob 給的序號添加在 String.xml
序號來源 以下有教學
----------------------------------------------------------------
關於廣告帳號註冊
1 . 申請 Ads 帳號
首頁
https://apps.admob.com/#home
註冊Key
https://apps.admob.com/#monetize/pubcontrols:urls
參考資料: Interstitial Ads
參考資料:Interstitial Ads 無法顯示的問題
歡迎轉載,請註明出處。
想必大家都聽過寫 App 然後靠廣告賺錢
那要如何把廣告植入在我們的心血?
其實沒有我們想像的困難
此 Sample 是以 AndroidStudio 版本為主 : 連結
如果大大是以 Eclipse 開發 請參考 : 連結
雖然網路以上有流程
但只需要自己所要的部分
1 . 在 Gradle 內加入
compile 'com.google.android.gms:play-services-ads:7.8.0'
2 . 在要呈現的版面新增元件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ads="http://schemas.android.com/apk/res-auto"
.
.
<com.google.android.gms.ads.AdView
android:id="@+id/adView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
ads:adSize="BANNER"
ads:adUnitId="@string/banner_ad_unit_id">
</com.google.android.gms.ads.AdView>
</LinearLayout>
3 . 宣告元件
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
AdView mAdView = (AdView) findViewById(R.id.adView);
AdRequest adRequest = new AdRequest.Builder().build();
mAdView.loadAd(adRequest);
.
.
}
4 . 將 AdMob 給的序號添加在 String.xml
序號來源 以下有教學
<resources>
<string name="banner_ad_unit_id">ca-app-pub-111222333444555666/555444111</string>
</resources>
----------------------------------------------------------------
關於廣告帳號註冊
1 . 申請 Ads 帳號
https://apps.admob.com/#home
註冊Key
https://apps.admob.com/#monetize/pubcontrols:urls
參考資料: Interstitial Ads
參考資料:Interstitial Ads 無法顯示的問題
歡迎轉載,請註明出處。
Android-Parse Push ParsePushBroadcastReceiver ( 三 )
在前面兩個章節有介紹如何 :
You can add key in onReciver
- String strChannel = intent.getExtras().getString("com.parse.Channel");
- String strData = intent.getExtras().getString("com.parse.Data");
2 . 將原先的註冊的 Receiver 更改
( 更改成剛剛繼承的 Receiver )
3 . 如果覺得原生的 Notification 太單調,也可以改成自己的
歡迎轉載,請註明出處。
- 初始化 Parse
- 接收 Parse Push Message
- 發送 Push Message
這次我們要做第二點的延伸
延伸?
簡單的說,Parse SDK 有預設
但我們想自己做 Design 這樣可以嗎??
Notification Icon、Notification Message ...etc.
Notification Icon、Notification Message ...etc.
當然是可以的
1 . extends ParsePushBroadcastReceiver
( ex : is ParsePushBroadcastReceiver, isn't ParseBroadcastReceiver )
( ex : is ParsePushBroadcastReceiver, isn't ParseBroadcastReceiver )
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import com.parse.ParsePushBroadcastReceiver;
public class MyParseReceiver extends ParsePushBroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.d("MyParseReceiver", "action:" + action);
}
}
You can add key in onReciver
- String strChannel = intent.getExtras().getString("com.parse.Channel");
- String strData = intent.getExtras().getString("com.parse.Data");
2 . 將原先的註冊的 Receiver 更改
<receiver
android:name="com.parse.ParsePushBroadcastReceiver"
android:exported="false" >
<intent-filter>
<action android:name="com.parse.push.intent.RECEIVE" />
<action android:name="com.parse.push.intent.OPEN" />
<action android:name="com.parse.push.intent.DELETE" />
</intent-filter>
</receiver>
( 更改成剛剛繼承的 Receiver )
<receiver
android:name="MyParseReceiver"
android:exported="false" >
<intent-filter>
<action android:name="com.parse.push.intent.RECEIVE" />
<action android:name="com.parse.push.intent.OPEN" />
<action android:name="com.parse.push.intent.DELETE" />
</intent-filter>
</receiver>
3 . 如果覺得原生的 Notification 太單調,也可以改成自己的
// 將提醒功能取消
@Override
protected Notification getNotification(Context context, Intent intent) {
return null;
}
private void myNotification(...){
Notification...
}
歡迎轉載,請註明出處。
2015年11月9日 星期一
Android-Weather API
World Weather Online
Link : http://www.worldweatheronline.com/
OpenWeatherMap
Link : http://openweathermap.org/
台灣氣象資訊
雖然有資料,但送出格式有待確認
Link : http://www.worldweatheronline.com/
OpenWeatherMap
Link : http://openweathermap.org/
台灣氣象資訊
雖然有資料,但送出格式有待確認
Java-Synchronized 同步 用法 執行
想必大家都聽過 Synchronized 同步 之類的
但聽過這麼多
但是到底是啥東西??
簡單的說 : 你要使用此物件、方法,你就是要
排隊!!!
排隊!!!
排隊!!!
但是前者結束,後者要搶!!!
為啥要排隊?不是直接使用就好了嗎??
當然也行,但在銀行的例子就不可行
在同一時間只能一個人做領錢的動作
直到確認把錢交至手上為止
下一個人才能領錢或存錢
那寫哪種程式比較常遇到 ?
檔案接收完整性、資料存取之類
以下圖示針對銀行例子做圖解
( 左 : 同時領錢 , 右 : 排隊領錢 )
以下是用範例呈現 :
1 . 不使用 Synchonized
多次執行,結果皆不同。
2 . 使用 Synchonized
多次執行,結果相同。
以下是範例程式碼 : ( 請自行更改 synchronized 需求 )
Test.java
TestThread.java
注意 :
因為線程的執行本身就是不確定的
加了 Synchronizes 只能確保這段程式碼和參數
並不能保證程序的執行順序!!!
如果真的要有順序,先暫時用 Sleep 頂替。
參考資料 : [Java] Synchronized 心得
參考資料 : JAVA筆記-synchronized 同步物件資料,避免Race Condition
歡迎轉載,請註明出處。
但聽過這麼多
但是到底是啥東西??
簡單的說 : 你要使用此物件、方法,你就是要
排隊!!!
排隊!!!
排隊!!!
但是前者結束,後者要搶!!!
為啥要排隊?不是直接使用就好了嗎??
當然也行,但在銀行的例子就不可行
在同一時間只能一個人做領錢的動作
直到確認把錢交至手上為止
下一個人才能領錢或存錢
那寫哪種程式比較常遇到 ?
檔案接收完整性、資料存取之類
以下圖示針對銀行例子做圖解
( 左 : 同時領錢 , 右 : 排隊領錢 )
以下是用範例呈現 :
1 . 不使用 Synchonized
2 . 使用 Synchonized
多次執行,結果相同。
以下是範例程式碼 : ( 請自行更改 synchronized 需求 )
Test.java
public class Test {
public static void main(String[] args) {
TestThread.Threading("1");
TestThread.Threading("2");
}
}
TestThread.java
public class TestThread {
public static void Threading(String message){
new Threading(message).start();
}
public static class Threading extends Thread {
private String _strMessage;
Threading(String strMessage){
this._strMessage = strMessage;
}
public void run() {
// synchronized (TestThread.class) {
try {
for(int i=0; i < 5; i++){
Thread.sleep(1000);
System.out.println(_strMessage + " : " + i);
}
} catch (InterruptedException e) {
}
// }
}
}
}
注意 :
因為線程的執行本身就是不確定的
加了 Synchronizes 只能確保這段程式碼和參數
並不能保證程序的執行順序!!!
如果真的要有順序,先暫時用 Sleep 頂替。
參考資料 : [Java] Synchronized 心得
參考資料 : JAVA筆記-synchronized 同步物件資料,避免Race Condition
歡迎轉載,請註明出處。
2015年11月5日 星期四
Android-GreenDAO 的基本使用方式 可當小型 資料庫 - 3
如果有需要再新增欄位怎麼辦?
比如要在新增有關日期的欄位( 紅字代表新增 )
資料庫重建?
如果真的有需要新增欄位
可以直接在 Class 下新增
但要注意不要由遺漏的
沿用上一篇創立的表格 : Note
當創立完後
會產生以下兩個檔案
我們會修改此檔案
比如要在新增有關日期的欄位( 紅字代表新增 )
1 . Note.java ( 4項須更新 )
package de.greenrobot.daoexample;
// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT. Enable "keep" sections if you want to edit.
/**
* Entity mapped to table NOTE.
*/
public class Note {
private Long id;
/** Not-null value. */
private String note;
private int count;
/** Not-null value. */
private java.util.Date date;
/** Not-null value. */
private java.util.Date Hee;
public Note() {
}
public Note(Long id) {
this.id = id;
}
public Note(Long id, String note, int count, java.util.Date date, java.util.Date Hee) {
this.id = id;
this.note = note;
this.count = count;
this.date = date;
this.Hee = Hee;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
/** Not-null value. */
public String getNote() {
return note;
}
/** Not-null value; ensure this value is available before it is saved to the database. */
public void setNote(String note) {
this.note = note;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
/** Not-null value. */
public java.util.Date getDate() {
return date;
}
/** Not-null value; ensure this value is available before it is saved to the database. */
public void setDate(java.util.Date date) {
this.date = date;
}
/** Not-null value. */
public java.util.Date getHee() {
return Hee;
}
/** Not-null value; ensure this value is available before it is saved to the database. */
public void setHee(java.util.Date Hee) {
this.Hee = Hee;
}
}
2 . NoteDao.java( 5項需更新 )
package de.greenrobot.daoexample;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteStatement;
import de.greenrobot.dao.AbstractDao;
import de.greenrobot.dao.Property;
import de.greenrobot.dao.internal.DaoConfig;
import de.greenrobot.daoexample.Note;
// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.
/**
* DAO for table NOTE.
*/
public class NoteDao extends AbstractDao<Note, Long> {
public static final String TABLENAME = "NOTE";
/**
* Properties of entity Note.<br/>
* Can be used for QueryBuilder and for referencing column names.
*/
public static class Properties {
public final static Property Id = new Property(0, Long.class, "id", true, "_id");
public final static Property Note = new Property(1, String.class, "note", false, "NOTE");
public final static Property Count = new Property(2, int.class, "count", false, "COUNT");
public final static Property Date = new Property(3, java.util.Date.class, "date", false, "DATE");
public final static Property Hee = new Property(4, java.util.Date.class, "Hee", false, "HEE");
};
public NoteDao(DaoConfig config) {
super(config);
}
public NoteDao(DaoConfig config, DaoSession daoSession) {
super(config, daoSession);
}
/** Creates the underlying database table. */
public static void createTable(SQLiteDatabase db, boolean ifNotExists) {
String constraint = ifNotExists? "IF NOT EXISTS ": "";
db.execSQL("CREATE TABLE " + constraint + "'NOTE' (" + //
"'_id' INTEGER PRIMARY KEY ," + // 0: id
"'NOTE' TEXT NOT NULL ," + // 1: note
"'COUNT' INTEGER NOT NULL ," + // 2: count
"'DATE' INTEGER NOT NULL ," + // 3: date
"'HEE' INTEGER NOT NULL );"); // 4: Hee
}
/** Drops the underlying database table. */
public static void dropTable(SQLiteDatabase db, boolean ifExists) {
String sql = "DROP TABLE " + (ifExists ? "IF EXISTS " : "") + "'NOTE'";
db.execSQL(sql);
}
/** @inheritdoc */
@Override
protected void bindValues(SQLiteStatement stmt, Note entity) {
stmt.clearBindings();
Long id = entity.getId();
if (id != null) {
stmt.bindLong(1, id);
}
stmt.bindString(2, entity.getNote());
stmt.bindLong(3, entity.getCount());
stmt.bindLong(4, entity.getDate().getTime());
stmt.bindLong(5, entity.getHee().getTime());
}
/** @inheritdoc */
@Override
public Long readKey(Cursor cursor, int offset) {
return cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0);
}
/** @inheritdoc */
@Override
public Note readEntity(Cursor cursor, int offset) {
Note entity = new Note( //
cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0), // id
cursor.getString(offset + 1), // note
cursor.getInt(offset + 2), // count
new java.util.Date(cursor.getLong(offset + 3)), // date
new java.util.Date(cursor.getLong(offset + 4)) // Hee
);
return entity;
}
/** @inheritdoc */
@Override
public void readEntity(Cursor cursor, Note entity, int offset) {
entity.setId(cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0));
entity.setNote(cursor.getString(offset + 1));
entity.setCount(cursor.getInt(offset + 2));
entity.setDate(new java.util.Date(cursor.getLong(offset + 3)));
entity.setHee(new java.util.Date(cursor.getLong(offset + 4)));
}
/** @inheritdoc */
@Override
protected Long updateKeyAfterInsert(Note entity, long rowId) {
entity.setId(rowId);
return rowId;
}
/** @inheritdoc */
@Override
public Long getKey(Note entity) {
if(entity != null) {
return entity.getId();
} else {
return null;
}
}
/** @inheritdoc */
@Override
protected boolean isEntityUpdateable() {
return true;
}
}
歡迎轉載,請註明出處。
訂閱:
文章 (Atom)