2014-02-26 46 views
0

對於我們用Adobe AIR編寫的遊戲,當我們在Android上顯示本地或推送通知時,我們希望遊戲中的聲音之一成爲通知聲音。Android - 從沒有android.permission.WRITE_EXTERNAL_STORAGE的資產播放聲音

目前我們有一個解決方案,我們並不真的很高興,因爲它需要額外的Android權限,我們真的覺得這是不必要的。基本上,你傳遞資源路徑,比如說「audio/core/reward.mp3」,它位於「assets」文件夾的根目錄下,然後在Android端,它將該文件拖入InputStream,將其寫入文件在外部存儲上,Android的MediaPlayer會從那裏播放它。

很顯然,當你在Android上播放文件時,AIR不會做什麼,因爲你不需要「WRITE_EXTERNAL_STORAGE」來播放聲音,所以對於我們的情況,當應用程序目前不在運行時,一個推送通知進來了,我將如何能夠播放這個文件,這個文件被打包並用在AS3的事物上?

這樣做是被推薦的方式,

MediaPlayer m = new MediaPlayer(); 
    AssetFileDescriptor afd = context.getAssets().openFd(soundPath); 
    m.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength()); 
    m.prepare(); 
    m.setVolume(1f, 1f); 
    m.start(); 
    playSound = false; 

但是,這並不與

java.io.FileNotFoundException: This file can not be opened as a file descriptor; it is probably compressed 

所以我需要做非優選方法的錯誤工作,

public static void HandleMessage(Context context, CharSequence title, CharSequence message, String soundPath) 
{ 
    log("HandleMessage (message: '" + message + "', title: '" + title +"', icon: " + Extension.getIcon(context) + ", class: " + Extension.getEntryClass(context)); 
    long when = System.currentTimeMillis(); 

    NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); 
    Intent notificationIntent = new Intent(context, Extension.getEntryClass(context)); 

    PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0); 

    Notification notification = new NotificationCompat.Builder(context) 
     .setContentText(message) 
     .setContentIntent(contentIntent) 
     .setTicker(message) 
     .setSmallIcon(Extension.getIcon(context)) 
     .setWhen(when) 
     .setAutoCancel(true) 
     .setVibrate(new long[] { 1000, 400 }) 
     .build(); 

    Boolean playSound = true; 
    if(null != soundPath && "" != soundPath) 
    { 
     try { 
      MediaPlayer m = new MediaPlayer(); 
      String newPath = checkWriteFile(context, soundPath); 
      log(newPath); 
      if(null != newPath) 
      { 
       m.setDataSource(newPath); 
       m.prepare(); 
       m.setVolume(1f, 1f); 
       m.start(); 
       playSound = false; 
      } 
     } catch (IOException e) { 
      log(e.getLocalizedMessage()); 
      e.printStackTrace(); 
     } 
    } 
    if(playSound) 
    { 
     notification.sound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); 
    } 

    nm.notify(NotifId, notification); 

    NotifId++; 
} 

public static String checkWriteFile(Context context, String relPath) 
{ 
    Boolean exists = false; 
    String newPath = null; 
    String fullPath = Environment.getExternalStorageDirectory().getPath() + "/" + context.getPackageName() + "/temp/" + relPath; 
    int index = fullPath.lastIndexOf("/") + 1; 
    String file = fullPath.substring(index); 
    String path = fullPath.substring(0, index); 
    log(relPath + ", " + fullPath + ", " + (new File(fullPath)).exists()); 

    if (!(new File(fullPath)).exists()) { 
     try { 
      byte[] buffer = null; 
      InputStream fIn = context.getAssets().open(relPath); 
      log("InputStream: " + fIn); 

      int size=0; 

      try { 
       size = fIn.available(); 
       buffer = new byte[size]; 
       fIn.read(buffer); 
       fIn.close(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
      exists = (new File(path)).exists(); 
      if (!exists) { 
       new File(path).mkdirs(); 
      } 

      FileOutputStream save; 
      try { 
       save = new FileOutputStream(path + file); 
       save.write(buffer); 
       save.flush(); 
       save.close(); 
       newPath = fullPath; 
      } catch (FileNotFoundException e) { 
       e.printStackTrace(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
     catch (Exception e) { 
      log(e.getLocalizedMessage()); 
      e.printStackTrace(); 
     } 
    } 
    else { 
     newPath = fullPath; 
    } 

    return newPath; 
} 
+1

被替換,你可以將它解壓到內部存儲而不是外部。 – njzk2

+0

@ njzk2我的話,我覺得多笨!請添加此作爲答案,我會接受。非常感謝。 – seaders

回答

1

如果你想避免android.permission.WRITE_EXTERNAL_STORAGE,你可以提取你的文件到內部存儲而不是外部。

String fullPath = Environment.getExternalStorageDirectory() (...) 

可以通過

String fullPath = context.getFilesDir() (...) 
+0

由於這是一個很小的文件,如果它在任何階段被刪除,我們都會很好,但實際上我會用getCacheDir()來代替。再次感謝幫助和指針,真的很感激。 – seaders