24311


はじめまして。  
今、twitter4jを使用してTwitterクライアントアプリを作成しています。  
複数画像をメッセージと同時に投稿したいのですが、一度ファイルを取得しているにも関わらず  
ファイルが存在しないことになってしまいます。  
何がいけないのでしょうか？ご教示願います。

[code]

    public class TweetActivity extends Activity {
    
    private EditText mInputText;
    private Twitter mTwitter;
    private Button mGazou;
    private ImageView imageView,imageView2,imageView3,imageView4;
    private Boolean gazou=false;
    UploadedMedia media1=null;
    UploadedMedia media2=null;
    UploadedMedia media3=null;
    UploadedMedia media4=null;
    int k =0;
    Uri[] multi_uri=null;
    Uri uri = null;
    InputStream in;
    long[]mediaIds = null;
    long media_id =0;
    
    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.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
                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,final Intent resultData) {
    
        if (requestCode != RESULT_PICK_IMAGEFILE || resultCode != RESULT_OK) {
            return;
        }
    
        new AsyncTask<Void, Void, Void>() {
            @Override
            protected Void doInBackground(Void... params) {
                try {
                    //mTwitterはOAuth認可済みであるとする
                    String message = "hello";
                    ClipData clipData = resultData.getClipData();
                    long[] mediaIds = new long[clipData.getItemCount()];
                    for (int i = 0, length = clipData.getItemCount(); i < length; i++) {
                        ClipData.Item item = clipData.getItemAt(i);
                        mediaIds[i] = (mTwitter.uploadMedia(String.format("[filename_%d]", i + 1), getContentResolver().openInputStream(item.getUri())).getMediaId());
                    }
    
                    StatusUpdate update = new StatusUpdate(message);
                    update.setMediaIds(mediaIds);
                    mTwitter.updateStatus(update);
    
                } catch (TwitterException e) {
                    e.printStackTrace();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
                return null;
            }
        }.execute();
     }
    
    @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);
    }
    
[/code]

ログキャットは以下のように出力されます。

[code]

    04-26 05:10:17.700: E/AndroidRuntime(3099): FATAL EXCEPTION: AsyncTask #3
    04-26 05:10:17.700: E/AndroidRuntime(3099): Process: android.example.shutwitter, PID: 3099
    04-26 05:10:17.700: E/AndroidRuntime(3099): java.lang.RuntimeException: An error occured while executing doInBackground()
    04-26 05:10:17.700: E/AndroidRuntime(3099):     at android.os.AsyncTask$3.done(AsyncTask.java:300)
    04-26 05:10:17.700: E/AndroidRuntime(3099):     at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
    04-26 05:10:17.700: E/AndroidRuntime(3099):     at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
    04-26 05:10:17.700: E/AndroidRuntime(3099):     at java.util.concurrent.FutureTask.run(FutureTask.java:242)
    04-26 05:10:17.700: E/AndroidRuntime(3099):     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
    04-26 05:10:17.700: E/AndroidRuntime(3099):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
    04-26 05:10:17.700: E/AndroidRuntime(3099):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
    04-26 05:10:17.700: E/AndroidRuntime(3099):     at java.lang.Thread.run(Thread.java:818)
    04-26 05:10:17.700: E/AndroidRuntime(3099): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
    04-26 05:10:17.700: E/AndroidRuntime(3099):     at android.os.Handler.<init>(Handler.java:200)
    04-26 05:10:17.700: E/AndroidRuntime(3099):     at android.os.Handler.<init>(Handler.java:114)
    04-26 05:10:17.700: E/AndroidRuntime(3099):     at android.widget.Toast$TN.<init>(Toast.java:336)
    04-26 05:10:17.700: E/AndroidRuntime(3099):     at android.widget.Toast.<init>(Toast.java:100)
    04-26 05:10:17.700: E/AndroidRuntime(3099):     at android.widget.Toast.makeText(Toast.java:250)
    04-26 05:10:17.700: E/AndroidRuntime(3099):     at android.example.shutwitter.TweetActivity.showToast(TweetActivity.java:238)
    04-26 05:10:17.700: E/AndroidRuntime(3099):     at android.example.shutwitter.TweetActivity.access$1(TweetActivity.java:237)
    04-26 05:10:17.700: E/AndroidRuntime(3099):     at android.example.shutwitter.TweetActivity$3.doInBackground(TweetActivity.java:99)
    04-26 05:10:17.700: E/AndroidRuntime(3099):     at android.example.shutwitter.TweetActivity$3.doInBackground(TweetActivity.java:1)
    04-26 05:10:17.700: E/AndroidRuntime(3099):     at android.os.AsyncTask$2.call(AsyncTask.java:288)
    04-26 05:10:17.700: E/AndroidRuntime(3099):     at java.util.concurrent.FutureTask.run(FutureTask.java:237)
    04-26 05:10:17.700: E/AndroidRuntime(3099):     ... 4 more
    
[/code]


CC BY-SA 3.0
2016-04-24T03:46:03.123
24293
2016-04-26T09:12:26.503
2016-04-26T09:12:26.503
15276
15276
question
android eclipse 画像 twitter4j
twitter4Jで複数画像を投稿したいのですが、一度ファイルを取得しているにもかかわらずファイルがないと言われますどのようにしたらよろしいでしょうか？


ギャラリーから取得したURIを`File`に渡していますが、`File`のAPIが扱える`Path`とはファイルパス（`file:`スキーマのもの）であって、Androidの`Content
Provider`が返すコンテンツURI（`content:`スキーマのもの）ではないのが原因です。

`Content Provider`が返却したコンテンツURIから実際のファイルを取得するには、`Content
Resolver`を利用する必要があります。公式ドキュメントの[コンテンツ
プロバイダの作成](http://developer.android.com/intl/ja/guide/topics/providers/content-
provider-
creating.html)などを参考にしてみてください。`ImageView`に画像が表示されるのは、Glideのフレームワークが内部で`ContentResolver`を用いているためです。

ここでは、[ストレージ アクセス
フレームワーク](https://developer.android.com/intl/ja/guide/topics/providers/document-
provider.html)を用いて画像を取得していますが、SAFから取得したコンテンツURIを実際のファイルパスに変換するよりも、`InputStream`を引数に取れる`uploadMedia(java.lang.String
fileName, java.io.InputStream media)`を利用した方が簡単かと思います。

`getContentResolver().openInputStream(resultData.getData())`でストリームを取得できます。

* * *

問題を単純化して、Twitter4Jを用いて複数枚の画像を同時にアップロードするという処理を書く場合は以下のような感じになります。

[code]

    @Override
    public void onActivityResult(int requestCode, int resultCode,final Intent resultData) {
    
        if (requestCode != RESULT_PICK_IMAGEFILE || resultCode != RESULT_OK) {
            return;
        }
    
        new AsyncTask<Void, Void, Void>() {
            @Override
            protected Void doInBackground(Void... params) {
                try {
                    //mTwitterはOAuth認可済みであるとする
                    String message = "hello";
                    ClipData clipData = resultData.getClipData();
                    long[] mediaIds = new long[clipData.getItemCount()];
                    for (int i = 0, length = clipData.getItemCount(); i < length; i++) {
                        ClipData.Item item = clipData.getItemAt(i);
                        mediaIds[i] = (mTwitter.uploadMedia(String.format("[filename_%d]", i + 1), getContentResolver().openInputStream(item.getUri())).getMediaId());
                    }
    
                    StatusUpdate update = new StatusUpdate(message);
                    update.setMediaIds(mediaIds);
                    mTwitter.updateStatus(update);
    
                } catch (TwitterException e) {
                    e.printStackTrace();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
                return null;
            }
        }.execute();
     }
    
[/code]


CC BY-SA 3.0
2016-04-24T12:22:27.350
24311
2016-04-25T15:04:21.957
2016-04-25T15:04:21.957
5337
5337
24293
answer