2017-02-15 49 views
1

我用Xamarin Android创建了一个Android手机。该应用内有一个功能,可以将图像发送到Twitter。我在三星S7,alcatel Pixi4和我的平板电脑(Galaxy Tab 2)上从Play商店下载应用程序后测试了此功能。我的代码在外部缓存目录中创建一个位图文件,并请求twitter读取该文件以便将它附加到推文上。为什么不能在外部缓存目录中读取我的文件?

它工作正常。不过,我让其他人测试它(他们也从Play商店下载了我的应用程序),他们告诉我该文件是在缓存目录中创建的,但是位图图片并未附加到他们的推文中。同样重要的是要知道,其他的应用程序,这样做(如长推特)上工作的所有设备:

https://play.google.com/store/apps/details?id=de.cbruegg.longtweet

我不明白。 Twitter,适用于所有设备。这已经过检查。应用程序(例如长鸣)可以发送文件到twitter来发送这个消息。这也适用于所有设备。此外,我的应用程序可以完美地将文件写入缓存目录。适用于所有设备。此外,我的应用程序能够发送位图图片到twitter以推送图片。这适用于我的S7。但不是我测试仪的S7。我不明白。这是我的代码。不管怎样,我做错了什么。顺便说一下,生成推文始终有效。正是在我的测试仪器上进行测试时,图片未附加到推文上的情况。

这是我的代码。请让我知道我应该如何改进它。

public bool TweetImage(Bitmap imageToTweet) 
{ 
    var messageIntent = context.FindMessageIntent(this.twitterConstants.PackageName); 
    if (messageIntent == null) 
    { 
     return false; 
    } 
    string outputFileBMP = SaveBitmap(imageToTweet); 
    context.Tweet(messageIntent, outputFileBMP, this.twitterConstants.DefaultTwitterText, this.twitterConstants.ChooserMessage); 
    return true; 
} 

private string SaveBitmap(Bitmap imageToTweet) 
{ 
    string outputFileBMP = System.IO.Path.Combine(context.ExternalCacheDir.Path, System.Guid.NewGuid().ToString() + ".bmp"); 
    using (var outputFileStream = System.IO.File.Create(outputFileBMP)) 
    { 
     imageToTweet.Compress(Android.Graphics.Bitmap.CompressFormat.Png, 100, outputFileStream); 
    } 
    return outputFileBMP; 
} 

public static Intent FindMessageIntent(this ContextWrapper contextWrapper, params string[] packageNames) 
{ 
    Intent wantedIntent = new Intent(); 
    wantedIntent.SetType("text/plain"); 

    var resolveInfos = contextWrapper.PackageManager.QueryIntentActivities(wantedIntent, PackageInfoFlags.MatchDefaultOnly); 

    var result = (from r in resolveInfos 
        from p in packageNames 
        where p == r.ActivityInfo.PackageName 
        select p).FirstOrDefault(); 

    if (result != null) 
    { 
     wantedIntent.SetPackage(result); 
     return wantedIntent; 
    } 
    return null; 
} 

public static void Tweet(this ContextWrapper contextWrapper, Intent messageIntent, string filePath = null, string message = null, string chooserMessage = null) 
{ 
    if (filePath != null) 
    { 
     using (var file = new Java.IO.File(filePath)) 
     { 
      messageIntent.PutExtra(Intent.ExtraStream, Android.Net.Uri.FromFile(file)); 
     } 
    } 
    if (message != null) 
    { 
     messageIntent.PutExtra(Intent.ExtraText, message); 
    } 

    if (chooserMessage != null) 
    { 
     using (var chooser = Intent.CreateChooser(messageIntent, chooserMessage)) 
     { 
      contextWrapper.StartActivity(chooser); 
     } 
     return; 
    } 
    contextWrapper.StartActivity(messageIntent); 
} 

回答

1

由于您使用外部缓存目录,你应该始终确保它在使用它之前存在。从Android文档:

外部存储器可能不可用 - 例如,当用户将存储器安装到PC或已经移除提供外部存储器的SD卡时,您应该始终验证卷是在访问它之前可用。您可以通过调用getExternalStorageState()来查询外部存储状态。如果返回的状态等于MEDIA_MOUNTED,那么您可以读取和写入文件。

S7支持MicroSD卡,因此您的测试仪可能就是这种情况吗?

此外,Long Tweet会将图像存储和共享与您的显示略有不同。这里是区别:

  1. 它们将生成的位图存储到内部缓存目录(CacheDir而不是ExternalCacheDir)。
  2. 它们将读取和写入权限(File对象的Readable和Executable属性)设置为生成的文件和目录,以便其他应用程序在具有完整路径时可以访问该文件。

为了记录在案,这里是他们如何设置意图的Java代码:

public static void intentImage(Context context, File file, String intentAction) 
{ 
    file.getParentFile().getParentFile().setExecutable(true, false); 
    file.getParentFile().setExecutable(true, false); 
    file.getParentFile().getParentFile().setReadable(true, false); 
    file.getParentFile().setReadable(true, false); 
    file.setReadable(true, false); 
    file.setExecutable(true, false); 

    String fileStr = "file://" + file.toString(); 

    Intent intent = new Intent(); 
    intent.setAction(intentAction); 

    if (intentAction == "android.intent.action.SEND") 
    { 
     intent.putExtra("android.intent.extra.STREAM", Uri.parse(fileStr)); 
     intent.setType("image/" + fileStr.substring(fileStr.lastIndexOf(".") + 1)); 
    } 

    else 
    { 
     intent.setDataAndType(Uri.parse(fileStr), "image/" + fileStr.substring(fileStr.lastIndexOf(".") + 1)); 
    } 

    context.startActivity(intent); 
} 

我会利用内部缓存目录设置正确的权限生成的文件开始(可能还父文件夹)。

相关问题