2015年4月29日 星期三

[Android] Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?

今天看書練習Broadcast receiver時, 在自定義的BroadcastReceiver的類別onReceive()中, 我使用了一個intent想要將廣播收到的值抓出來再丟去瀏覽器查詢, 如下

    @Override
    public void onReceive(Context context, Intent intent) {
        String strQuery= intent.getStringExtra("QUERY_PARM");
        Uri uri = Uri.parse("https://www.google.com.tw/webhp?hl=zh-TW&gws_rd=ssl#hl=zh-TW&q=" + strQuery);

        Intent it = new Intent(Intent.ACTION_VIEW, uri);
        context.startActivity(it);
    }


但收到廣播後要開啟瀏覽器前, 程式就掛掉惹, 且DDMS出現了以下訊息:
 Calling startActivity() from outside of an Activity  context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?


請問Google大神後, 發現如果是用context執行starActivity, 就需要再開一個新的task
解決方法就是在startActivity之前指派一個flag給intent 就OK了

        Intent it = new Intent(Intent.ACTION_VIEW, uri);
        it.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(it);

2015年4月10日 星期五

[Android] How to use facebook SDK 4.0.0 to share image.

看圖說故事囉~

新增專案

引入module


Facebook SDK下載位址: https://developers.facebook.com/docs/android 下載後請解壓縮
找到下載的Facebook sdk位址按下確定

Sync一下發現出現問題 ANDROID_BUILD_SDK_VERSION

打開facebook的 build.gradle檔, 將四個變數, 複製到gradle.properties

填入版本, 與app的build.gradle相同就好

再Sync一下, 又有問題了 = ="

這次請打開專案的build.gradle 將classpath的gradle版本從1.1.0修改為1.1.3

打開Project Structure (Ctrl+Alt+Shft+S)
照下圖修改一下

點選app->Dependencies->+號->選擇:facebook->OK

打開Facebook developer網頁 https://developers.facebook.com/apps/
新增一個App

選擇Android

填入你想要命名的app名稱

按下Create App ID

 填入你程式的package name和預設進入的Activity名字(通常沒改的話都是MainActivity)

下一步會要求你填入Key Hash

這裡我們要借助剛剛的程式把以下code填到onCreate()裡面,來取得Key Hash (當然你也可以照Facebook guide的建議方式取得): 請注意要修改的地方
 
PackageInfo info;
try {
  info = getPackageManager().getPackageInfo("com.foxlinkimage.alex.facebooksharedemo", PackageManager.GET_SIGNATURES);
  for(Signature signature : info.signatures)
  {      
      MessageDigest md;
      md =MessageDigest.getInstance("SHA");
      md.update(signature.toByteArray());
      String KeyResult =new String(Base64.encode(md.digest(), 0));//String something = new String(Base64.encodeBytes(md.digest()));
      Log.e("hash key", KeyResult);
      Toast.makeText(MainActivity.this, "My FB Key is \n" + KeyResult, Toast.LENGTH_LONG).show();
   }
}catch(PackageManager.NameNotFoundException e1){Log.e("name not found", e1.toString());
}catch(NoSuchAlgorithmException e){Log.e("no such an algorithm", e.toString());
}catch(Exception e){Log.e("exception", e.toString());}



DDMS中填入hash key 並Log level改成Error, 接上手機(開啟模擬器), 按下Debug, 會在下面框框跳出你的hash key

回到網頁上填入它吧! 按下一步, 再回到程式開始進行工作

- 打開Manifest.xml檔
  1. 新增權限, 這裡會用到網路和讀取SD卡
  2. 在<application>標籤裡填入meta-data
 
 < meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/app_id">
在strings.xml新增一個變數app_id, 這個ID就是你剛剛申請時facebook發配給你的, 可以到剛剛那個網頁找到.
往下拉, 新增FacebookActivity和provider, 請注意在provider內後面請改成你的app_id
 
<activity android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation" android:label="@string/app_name" android:name="com.facebook.FacebookActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar">

<provider android:authorities="com.facebook.app.FacebookContentProvider456793911146084" android:exported="true" android:name="com.facebook.FacebookContentProvider">
加入一個按鈕
照key啦~在此僅列出onClick()內的程式碼: 
請注意在onCreate()最一開始要先初始化FacebookSdk元件
 
FacebookSdk.sdkInitialize(getApplicationContext());
 
Bitmap image = BitmapFactory.decodeFile(path);
SharePhoto photo = new SharePhoto.Builder().setBitmap(image).build();
SharePhotoContent content = new SharePhotoContent.Builder().addPhoto(photo).build();
shareDialog.show(content);

噫~好了~ 可以用哩

2015年4月8日 星期三

[Android] Android Studio如何引入Facebook SDK

如何導入, 請參考以下連結的文章:
https://trinitytuts.com/integrating-facebook-sdk-application-android-studio/

將Facebook SDK加入後, sync後可能會出現以下訊息:

Could not find property 'ANDROID_BUILD_SDK_VERSION' on project ':facebook'.


請打開 /libraries/facebook/build.gradle

以下四個屬性 請修改成和你的app設置一樣

compileSdkVersion
buildToolsVersion
minSdkVersion
targetSdkVersion

再次sync後, 我又碰到以下錯誤訊息:

Cannot call getBootClasspath() before setTargetInfo() is called

於是Google後發現是Gradle 1.1.0 plugin 版本的bug, 請參考

http://stackoverflow.com/questions/28689020/cannot-call-getbootclasspath-before-settargetinfo-is-called

解決方法:

打開project的build.gradle

classpath修改為 'com.android.tools.build:gradle:1.1.2'

再次sync一次就可以了