【Android】ギャラリーで画像複数選択→そのままツイートしたいのですが・・・
解決済
回答 2
投稿
- 評価
- クリップ 1
- VIEW 3,081
ご無沙汰しております。
Twitterのクライアントアプリを作成しています。
作っている最中表題でつまづき色々調べているのですが
これだという解決策がないのでこちらに質問致します。
Android OSは4.4.2以降を想定して作っています。
twitter4jを用いて作成しています。
ギャラリー画像複数選択→ツイートの部分がどうしてもうまく行きません。
ツイートの前にログキャットでエラー出て強制終了しました。
何故nullを吐き出すか原因がよく分かりません。
そこからのツイートですが、選択した状態の画像をどうtweet();の部分に埋め込めがいいのか分かりません。
ご教示願います。
【ソース】
TwitterActivity.java
ボタンを押したらギャラリーに飛び画像を選択
その後ツイートボタンを押すとタイムラインに飛ぶイメージです。
package android.example.shutwitter;
import java.io.FileDescriptor;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.content.ClipData;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;
import twitter4j.Twitter;
import twitter4j.TwitterException;
public class TweetActivity extends Activity {
private EditText mInputText;
private Twitter mTwitter;
private Button mGazou;
private ImageView imageView,imageView2,imageView3,imageView4;
private static final int RESULT_PICK_IMAGEFILE = 1001;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.new_tweet);
mTwitter = TwitterUtils.getTwitterInstance(this);
//Twitter文字入力
mInputText = (EditText) findViewById(R.id.input_text);
//Twitter画像選択(ギャラリーから)
mGazou = (Button)findViewById(R.id.button1);
mGazou.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
startActivityForResult(intent, RESULT_PICK_IMAGEFILE);
}
});
findViewById(R.id.action_tweet).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
tweet();
}
});
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent resultData) {
imageView=(ImageView) findViewById(R.id.imageView1);
imageView2=(ImageView) findViewById(R.id.imageView2);
imageView3=(ImageView) findViewById(R.id.imageView3);
imageView4=(ImageView) findViewById(R.id.imageView4);
if (requestCode == RESULT_PICK_IMAGEFILE && resultCode == Activity.RESULT_OK) {
Uri uri = null;
if (resultData != null) {
uri = resultData.getData();
if(uri!=null){
//複数選択
ClipData clipData = resultData.getClipData();
List list = new ArrayList();
Bitmap bmp =null;
for( int i = 0; i < clipData.getItemCount(); i ++ ){
ClipData.Item item = clipData.getItemAt(i);
Uri multi_uri = item.getUri();
try {
bmp = getBitmapFromUri(multi_uri);
} catch (IOException e) {
// TODO 自動生成された catch ブロック
e.printStackTrace();
}
list.add(bmp);
}
Bitmap[] multi_bmp = ( Bitmap[] )list.toArray( new Bitmap[0] );
switch(clipData.getItemCount()){
case 1:
imageView.setImageBitmap(multi_bmp[0]);
imageView2.setVisibility(View.GONE);
imageView3.setVisibility(View.GONE);
imageView4.setVisibility(View.GONE);
break;
case 2:
imageView.setImageBitmap(multi_bmp[0]);
imageView2.setImageBitmap(multi_bmp[1]);
imageView3.setVisibility(View.GONE);
imageView4.setVisibility(View.GONE);
break;
case 3:
imageView.setImageBitmap(multi_bmp[0]);
imageView2.setImageBitmap(multi_bmp[1]);
imageView3.setImageBitmap(multi_bmp[2]);
imageView4.setVisibility(View.GONE);
break;
case 4:
imageView.setImageBitmap(multi_bmp[0]);
imageView2.setImageBitmap(multi_bmp[1]);
imageView3.setImageBitmap(multi_bmp[2]);
imageView4.setImageBitmap(multi_bmp[3]);
break;
default:
imageView.setVisibility(View.GONE);
imageView2.setVisibility(View.GONE);
imageView3.setVisibility(View.GONE);
imageView4.setVisibility(View.GONE);
break;
}
}
Log.i("", "Uri: " + uri.toString());
}
}
}
private Bitmap getBitmapFromUri(Uri uri) throws IOException {
ParcelFileDescriptor parcelFileDescriptor =
getContentResolver().openFileDescriptor(uri, "r");
FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor);
parcelFileDescriptor.close();
return image;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.new_tweet_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
switch (item.getItemId()) {
case R.id.menu_not:
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
private void tweet() {
AsyncTask<String, Void, Boolean> task = new AsyncTask<String, Void, Boolean>() {
@Override
protected Boolean doInBackground(String... params) {
try {
mTwitter.updateStatus(params[0]);
return true;
} catch (TwitterException e) {
e.printStackTrace();
return false;
}
}
@Override
protected void onPostExecute(Boolean result) {
if (result) {
showToast("ツイートが完了しました!");
showToast("×ボタンを押して元の画面に戻ってね");
mInputText.setText("");
} else {
showToast("ツイートに失敗しました。。。");
}
}
};
task.execute(mInputText.getText().toString());
}
private void showToast(String text) {
Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
}
}
【LOGCAT】
04-21 05:27:43.157: E/AndroidRuntime(3458): FATAL EXCEPTION: main
04-21 05:27:43.157: E/AndroidRuntime(3458): Process: android.example.shutwitter, PID: 3458
04-21 05:27:43.157: E/AndroidRuntime(3458): java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1001, result=-1, data=Intent { dat=content://com.android.providers.media.documents/document/image:31 flg=0x43 }} to activity {android.example.shutwitter/android.example.shutwitter.TweetActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'int android.content.ClipData.getItemCount()' on a null object reference
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
0
下記のコードを追加してみてください。
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
回答欄を間違えました。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.33%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2016/04/22 10:55
画像の複数選択することができました。
大変恐縮ですが、それ以降プログラムが実行されることはなくエラーで落ちてしまいます。
2016/04/22 11:08
わからないなら下記を行ってください。
ActivityForResultの先頭にブレークポイントを設置し、ブレークポイントで停止した後にステップ実行してください。
2016/04/22 12:14
落ちている箇所ですが、
画像を1枚選択すると
@Override
public void onActivityResult(int requestCode, int resultCode, Intent resultData) {
imageView=(ImageView) findViewById(R.id.imageView1);
imageView2=(ImageView) findViewById(R.id.imageView2);
imageView3=(ImageView) findViewById(R.id.imageView3);
imageView4=(ImageView) findViewById(R.id.imageView4);
if (requestCode == RESULT_PICK_IMAGEFILE && resultCode == Activity.RESULT_OK) {
Uri uri = null;
if (resultData != null) {
uri = resultData.getData();
Log.i("", "Uri: " + uri.toString());
//----------------ここで落ちてます---------------------//
//Error: Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int android.content.ClipData.getItemCount()' on a null object reference
if(uri!=null){
で落ち、
複数枚選択すると、Log.i("", "Uri: " + uri.toString());の部分で落ちてます。
2016/04/22 13:22
単一選択
getData()はURIを返すが、getClipDataはnullを返す。
複数選択(下記は推測です。)
getData()はnullを返すが、getClipData()はClipDataを返す。
2016/04/22 14:21
2016/04/22 17:35
また、1つの質問投稿に複数の関連しない質問を込めるのはよくないと思いますよ。
2016/04/22 19:04
別途質問します。
丁寧に有難うございました。